Skip to content

Commit

Permalink
Disable hashing headers for endpoints with static signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto committed Dec 20, 2023
1 parent 4085dfd commit 26eb5bf
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 6 deletions.
15 changes: 12 additions & 3 deletions Sources/Networking/HTTPClient/HTTPClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,14 @@ extension HTTPClient {
}
}

static func headerParametersForSignatureHeader(with headers: RequestHeaders) -> RequestHeaders {
if let header = HTTPRequest.headerParametersForSignatureHeader(headers: headers) {
static func headerParametersForSignatureHeader(
with headers: RequestHeaders,
path: HTTPRequestPath
) -> RequestHeaders {
if let header = HTTPRequest.headerParametersForSignatureHeader(
headers: headers,
path: path
) {
return [RequestHeader.headerParametersForSignature.rawValue: header]
} else {
return [:]
Expand Down Expand Up @@ -543,7 +549,10 @@ extension HTTPRequest {
if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *),
verificationMode.isEnabled,
self.path.supportsSignatureVerification {
result += HTTPClient.headerParametersForSignatureHeader(with: defaultHeaders)
result += HTTPClient.headerParametersForSignatureHeader(
with: defaultHeaders,
path: self.path
)

if let body = self.requestBody {
result += HTTPClient.postParametersHeaderForSigning(with: body)
Expand Down
10 changes: 9 additions & 1 deletion Sources/Security/HTTPRequest+Signing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@ import Foundation

extension HTTPRequest {

static func headerParametersForSignatureHeader(headers: Headers) -> String? {
static func headerParametersForSignatureHeader(
headers: Headers,
path: HTTPRequestPath
) -> String? {
guard #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *) else {
// Signature verification is not available.
return nil
}

guard path.needsNonceForSigning else {
// Static signatures cannot sign header parameters
return nil
}

if let hash = Self.postParameterHash(headers) {
return Self.signatureHashHeader(keys: Self.headersToSign.map(\.rawValue),
hash: hash)
Expand Down
8 changes: 6 additions & 2 deletions Sources/Security/Signing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,10 @@ extension Signing.SignatureParameters {
let nonce: Data = self.nonce ?? .init()
let path: Data = self.path.relativePath.asData
let postParameterHash: Data = self.requestBody?.postParameterHeader?.asData ?? .init()
let headerParametersHash: Data = HTTPRequest.headerParametersForSignatureHeader(headers: self.requestHeaders)?
let headerParametersHash: Data = HTTPRequest.headerParametersForSignatureHeader(
headers: self.requestHeaders,
path: self.path
)?
.asData ?? .init()
let requestDate: Data = String(self.requestDate).asData
let etag: Data = (self.etag ?? "").asData
Expand All @@ -300,7 +303,8 @@ extension Signing.SignatureParameters: CustomDebugStringConvertible {
path: '\(self.path.relativePath)'
message: '\(self.messageString.trimmingWhitespacesAndNewLines)'
headerParametersHash: '\(HTTPRequest.headerParametersForSignatureHeader(
headers: self.requestHeaders
headers: self.requestHeaders,
path: self.path
) ?? "")'
headers: '\(self.requestHeaders)'
postParameterHeader: '\(self.requestBody?.postParameterHeader ?? "")'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,42 @@ final class SignatureVerificationHTTPClientTests: BaseSignatureVerificationHTTPC
expect(header) == "key1,key2:sha256:59b271ae1bbcb1d31d41929817f4b16fb439eb4f31520b5ad1d5ce98920a7138"
}

func testRequestWithHeaderParametersHash() throws {
self.changeClient(.informational)

let request = HTTPRequest(method: .get, path: .mockPath)

let headers: [String: String]? = waitUntilValue { completion in
stub(condition: isPath(request.path)) { request in
completion(request.allHTTPHeaderFields)
return .emptySuccessResponse()
}

self.client.perform(request) { (_: EmptyResponse) in }
}

let header = try XCTUnwrap(headers?[HTTPClient.RequestHeader.headerParametersForSignature.rawValue] as? String)
expect(header) == "X-Is-Sandbox:sha256:b5bea41b6c623f7c09f1bf24dcae58ebab3c0cdd90ad966bc43a45b44867e12b"
}

func testEndpointsWithStaticSignatureDoNotIncludeHeaderParameterHash() throws {
self.changeClient(.informational)

let request = HTTPRequest(method: .get, path: .getOfferings(appUserID: "test"))

let result: [String: String]? = waitUntilValue { completion in
stub(condition: isPath(request.path)) { request in
completion(request.allHTTPHeaderFields)
return .emptySuccessResponse()
}

self.client.perform(request) { (_: EmptyResponse) in }
}

let headers = try XCTUnwrap(result)
expect(headers.keys).toNot(contain(HTTPClient.RequestHeader.headerParametersForSignature.rawValue))
}

}

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *)
Expand Down

0 comments on commit 26eb5bf

Please sign in to comment.