Skip to content

Commit 2828a22

Browse files
committed
Validate header fields.
1 parent 001494a commit 2828a22

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

Sources/AWSLambdaRuntimeCore/ControlPlaneResponseDecoder.swift

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,39 @@ struct ControlPlaneResponseDecoder: NIOSingleStepByteToMessageDecoder {
331331
}
332332

333333
default:
334-
return .ignore
334+
// Ensure we received a valid http header:
335+
break // fallthrough
336+
}
337+
338+
// We received a header we didn't expect, let's ensure it is valid.
339+
let satisfy = buffer.readableBytesView[0..<colonIndex].allSatisfy { char -> Bool in
340+
switch char {
341+
case UInt8(ascii: "a")...UInt8(ascii: "z"),
342+
UInt8(ascii: "A")...UInt8(ascii: "Z"),
343+
UInt8(ascii: "0")...UInt8(ascii: "9"),
344+
UInt8(ascii: "!"),
345+
UInt8(ascii: "#"),
346+
UInt8(ascii: "$"),
347+
UInt8(ascii: "%"),
348+
UInt8(ascii: "&"),
349+
UInt8(ascii: "'"),
350+
UInt8(ascii: "*"),
351+
UInt8(ascii: "+"),
352+
UInt8(ascii: "-"),
353+
UInt8(ascii: "."),
354+
UInt8(ascii: "^"),
355+
UInt8(ascii: "_"),
356+
UInt8(ascii: "`"),
357+
UInt8(ascii: "|"),
358+
UInt8(ascii: "~"):
359+
return true
360+
default:
361+
return false
362+
}
363+
}
364+
365+
guard satisfy else {
366+
throw LambdaRuntimeError.responseHeadHeaderInvalidCharacter
335367
}
336368

337369
return .ignore

Sources/AWSLambdaRuntimeCore/LambdaRuntimeError.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct LambdaRuntimeError: Error, Hashable {
2020
case responseHeadInvalidStatusLine
2121
case responseHeadMissingContentLengthOrTransferEncodingChunked
2222
case responseHeadMoreThan256BytesBeforeCRLF
23+
case responseHeadHeaderInvalidCharacter
2324
case responseHeadHeaderMissingColon
2425
case responseHeadHeaderMissingFieldValue
2526
case responseHeadInvalidHeader
@@ -48,6 +49,7 @@ struct LambdaRuntimeError: Error, Hashable {
4849
static var responseHeadMissingContentLengthOrTransferEncodingChunked =
4950
LambdaRuntimeError(.responseHeadMissingContentLengthOrTransferEncodingChunked)
5051
static var responseHeadMoreThan256BytesBeforeCRLF = LambdaRuntimeError(.responseHeadMoreThan256BytesBeforeCRLF)
52+
static var responseHeadHeaderInvalidCharacter = LambdaRuntimeError(.responseHeadHeaderInvalidCharacter)
5153
static var responseHeadHeaderMissingColon = LambdaRuntimeError(.responseHeadHeaderMissingColon)
5254
static var responseHeadHeaderMissingFieldValue = LambdaRuntimeError(.responseHeadHeaderMissingFieldValue)
5355
static var responseHeadInvalidHeader = LambdaRuntimeError(.responseHeadInvalidHeader)

Tests/AWSLambdaRuntimeCoreTests/ControlPlaneResponseDecoderTests.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,33 @@ final class ControlPlaneResponseDecoderTests: XCTestCase {
6363
decoderFactory: { ControlPlaneResponseDecoder() }
6464
))
6565
}
66+
67+
func testWhitespaceInHeaderIsRejected() {
68+
let nextResponse = ByteBuffer(string: """
69+
HTTP/1.1 200 OK\r\n\
70+
Content-Type: application/json\r\n\
71+
Lambda-Runtime Aws-Request-Id: 9028dc49-a01b-4b44-8ffe-4912e9dabbbd\r\n\
72+
Lambda-Runtime-Deadline-Ms: 1638392696671\r\n\
73+
Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:eu-central-1:079477498937:function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x\r\n\
74+
Lambda-Runtime-Trace-Id: Root=1-61a7e375-40b3edf95b388fe75d1fa416;Parent=348bb48e251c1254;Sampled=0\r\n\
75+
Date: Wed, 01 Dec 2021 21:04:53 GMT\r\n\
76+
Content-Length: 49\r\n\
77+
\r\n\
78+
{"name":"Fabian","key2":"value2","key3":"value3"}
79+
"""
80+
)
81+
82+
let pairs: [(ByteBuffer, [ControlPlaneResponse])] = [
83+
(nextResponse, [])
84+
]
85+
86+
XCTAssertThrowsError(try ByteToMessageDecoderVerifier.verifyDecoder(
87+
inputOutputPairs: pairs,
88+
decoderFactory: { ControlPlaneResponseDecoder() }
89+
)) {
90+
XCTAssertEqual($0 as? LambdaRuntimeError, .responseHeadHeaderInvalidCharacter)
91+
}
92+
}
6693
}
6794

6895
extension ByteBuffer {

0 commit comments

Comments
 (0)