Branch/Environment/Version
- Branch/Version: Observed on 5.8.2, but I think this is the case for all versions
- Environment: Observed in Hybrid
Describe the bug
When using upstream request signing with HMAC, the docs suggest that a Date header will be added to the request as it is necessary for compliance with the RFC. In my observation, this is only the case when the headerList configured for the API is empty. if a non-empty header list is defined, the date header will not be added. This is true even if "date" is included in the configured headerList.
Reproduction steps
- Enable request signing with a configuration like:
{
"is_enabled": true,
"secret": "shhhhh",
"key_id": "tyk-key-id",
"algorithm": "hmac-sha256",
"header_list": [ "(request-target)", "x-example" , "date"],
"certificate_id": "",
"signature_header": "authorization"
},
- Call the API without including a Date header
Actual behavior
No date header is added (the backend receives a call with a signature, but the signature is not based on a date header and no date header is received by the backend)
Expected behavior
A date header is added to the request and used in generating the signature
Screenshots/Video
N/A
Logs (debug mode or log file):
N/A
Configuration (tyk config file):
Additional context
I believe this comes from generateHeaderList. I have done very little with Go before, but at a naive read I think it should be something like:
func generateHeaderList(r *http.Request, headerList []string) []string {
var result []string
// date header is must as per Signing HTTP Messages Draft
if r.Header.Get("date") == "" {
refDate := "Mon, 02 Jan 2006 15:04:05 MST"
tim := time.Now().Format(refDate)
r.Header.Set("date", tim)
}
if len(headerList) == 0 {
result = make([]string, len(r.Header)+1)
result[0] = "(request-target)"
i := 1
for k := range r.Header {
loweredCaseHeader := strings.ToLower(k)
result[i] = strings.TrimSpace(loweredCaseHeader)
i++
}
} else {
result = make([]string, 0, len(headerList))
for _, v := range headerList {
if r.Header.Get(v) != "" {
result = append(result, v)
}
}
if len(result) == 0 {
headers := []string{"(request-target)", "date"}
result = append(result, headers...)
}
}
return result
}
Branch/Environment/Version
Describe the bug
When using upstream request signing with HMAC, the docs suggest that a Date header will be added to the request as it is necessary for compliance with the RFC. In my observation, this is only the case when the headerList configured for the API is empty. if a non-empty header list is defined, the date header will not be added. This is true even if "date" is included in the configured headerList.
Reproduction steps
Actual behavior
No date header is added (the backend receives a call with a signature, but the signature is not based on a date header and no date header is received by the backend)
Expected behavior
A date header is added to the request and used in generating the signature
Screenshots/Video
N/A
Logs (debug mode or log file):
N/A
Configuration (tyk config file):
Additional context
I believe this comes from generateHeaderList. I have done very little with Go before, but at a naive read I think it should be something like: