security(auth): add response body size limits to OAuth HTTP calls
Wrap all io.ReadAll(resp.Body) calls in the OAuth flow with io.LimitReader capped at 1 MB to prevent memory exhaustion from malicious or unexpectedly large server responses. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1fbd5d87a9
commit
42e037aec1
1 changed files with 7 additions and 20 deletions
|
|
@ -20,6 +20,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const oauthMaxResponseSize int64 = 1 << 20 // 1 MB — more than sufficient for any OAuth response
|
||||||
|
|
||||||
type OAuthProviderConfig struct {
|
type OAuthProviderConfig struct {
|
||||||
Issuer string
|
Issuer string
|
||||||
ClientID string
|
ClientID string
|
||||||
|
|
@ -212,10 +214,7 @@ func RequestDeviceCode(cfg OAuthProviderConfig) (*DeviceCodeInfo, error) {
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, _ := io.ReadAll(io.LimitReader(resp.Body, oauthMaxResponseSize))
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("reading device code response: %w", err)
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("device code request failed: %s", string(body))
|
return nil, fmt.Errorf("device code request failed: %s", string(body))
|
||||||
}
|
}
|
||||||
|
|
@ -303,10 +302,7 @@ func LoginDeviceCode(cfg OAuthProviderConfig) (*AuthCredential, error) {
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, _ := io.ReadAll(io.LimitReader(resp.Body, oauthMaxResponseSize))
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("reading device code response: %w", err)
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("device code request failed: %s", string(body))
|
return nil, fmt.Errorf("device code request failed: %s", string(body))
|
||||||
}
|
}
|
||||||
|
|
@ -366,10 +362,7 @@ func pollDeviceCode(cfg OAuthProviderConfig, deviceAuthID, userCode string) (*Au
|
||||||
return nil, fmt.Errorf("pending")
|
return nil, fmt.Errorf("pending")
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, _ := io.ReadAll(io.LimitReader(resp.Body, oauthMaxResponseSize))
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("reading device token response: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var tokenResp struct {
|
var tokenResp struct {
|
||||||
AuthorizationCode string `json:"authorization_code"`
|
AuthorizationCode string `json:"authorization_code"`
|
||||||
|
|
@ -410,10 +403,7 @@ func RefreshAccessToken(cred *AuthCredential, cfg OAuthProviderConfig) (*AuthCre
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, _ := io.ReadAll(io.LimitReader(resp.Body, oauthMaxResponseSize))
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("reading token refresh response: %w", err)
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("token refresh failed: %s", string(body))
|
return nil, fmt.Errorf("token refresh failed: %s", string(body))
|
||||||
}
|
}
|
||||||
|
|
@ -506,10 +496,7 @@ func ExchangeCodeForTokens(cfg OAuthProviderConfig, code, codeVerifier, redirect
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, _ := io.ReadAll(io.LimitReader(resp.Body, oauthMaxResponseSize))
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("reading token exchange response: %w", err)
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("token exchange failed: %s", string(body))
|
return nil, fmt.Errorf("token exchange failed: %s", string(body))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue