mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
fix timing oracle attack against signature V2/V4 verification (#5335)
This change replaces the non-constant time comparison of request signatures with a constant time implementation. This prevents a timing attack which can be used to learn a valid signature for a request without knowing the secret key. Fixes #5334
This commit is contained in:
committed by
Nitish Tiwari
parent
e39d7ddb0f
commit
a6318dbdaf
@@ -26,6 +26,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/subtle"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -34,7 +35,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/sha256-simd"
|
||||
sha256 "github.com/minio/sha256-simd"
|
||||
)
|
||||
|
||||
// AWS Signature Version '4' constants.
|
||||
@@ -146,6 +147,15 @@ func doesPolicySignatureMatch(formValues http.Header) APIErrorCode {
|
||||
return doesPolicySignatureV4Match(formValues)
|
||||
}
|
||||
|
||||
// compareSignatureV4 returns true if and only if both signatures
|
||||
// are equal. The signatures are expected to be HEX encoded strings
|
||||
// according to the AWS S3 signature V4 spec.
|
||||
func compareSignatureV4(sig1, sig2 string) bool {
|
||||
// The CTC using []byte(str) works because the hex encoding
|
||||
// is unique for a sequence of bytes. See also compareSignatureV2.
|
||||
return subtle.ConstantTimeCompare([]byte(sig1), []byte(sig2)) == 1
|
||||
}
|
||||
|
||||
// doesPolicySignatureMatch - Verify query headers with post policy
|
||||
// - http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html
|
||||
// returns ErrNone if the signature matches.
|
||||
@@ -180,7 +190,7 @@ func doesPolicySignatureV4Match(formValues http.Header) APIErrorCode {
|
||||
newSignature := getSignature(signingKey, formValues.Get("Policy"))
|
||||
|
||||
// Verify signature.
|
||||
if newSignature != formValues.Get("X-Amz-Signature") {
|
||||
if !compareSignatureV4(newSignature, formValues.Get("X-Amz-Signature")) {
|
||||
return ErrSignatureDoesNotMatch
|
||||
}
|
||||
|
||||
@@ -301,7 +311,7 @@ func doesPresignedSignatureMatch(hashedPayload string, r *http.Request, region s
|
||||
newSignature := getSignature(presignedSigningKey, presignedStringToSign)
|
||||
|
||||
// Verify signature.
|
||||
if req.URL.Query().Get("X-Amz-Signature") != newSignature {
|
||||
if !compareSignatureV4(req.URL.Query().Get("X-Amz-Signature"), newSignature) {
|
||||
return ErrSignatureDoesNotMatch
|
||||
}
|
||||
return ErrNone
|
||||
@@ -380,7 +390,7 @@ func doesSignatureMatch(hashedPayload string, r *http.Request, region string) AP
|
||||
newSignature := getSignature(signingKey, stringToSign)
|
||||
|
||||
// Verify if signature match.
|
||||
if newSignature != signV4Values.Signature {
|
||||
if !compareSignatureV4(newSignature, signV4Values.Signature) {
|
||||
return ErrSignatureDoesNotMatch
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user