Skip to content

Commit 01d797e

Browse files
Fixed a crash that could occur with un-restrained CBOR data being decoded leading to stack depletion
1 parent 80843bc commit 01d797e

File tree

5 files changed

+12
-16
lines changed

5 files changed

+12
-16
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ let package = Package(
2424
.library(name: "WebAuthn", targets: ["WebAuthn"])
2525
],
2626
dependencies: [
27-
.package(url: "https://github.com/unrelentingtech/SwiftCBOR.git", from: "0.4.5"),
27+
.package(url: "https://github.com/unrelentingtech/SwiftCBOR.git", from: "0.4.7"),
2828
.package(url: "https://github.com/apple/swift-crypto.git", "2.0.0" ..< "4.0.0"),
2929
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
3030
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.1.0")

Sources/WebAuthn/Ceremonies/Registration/AuthenticatorAttestationResponse.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct ParsedAuthenticatorAttestationResponse {
5656

5757
// Step 11. (assembling attestationObject)
5858
let attestationObjectData = Data(rawResponse.attestationObject)
59-
guard let decodedAttestationObject = try? CBOR.decode([UInt8](attestationObjectData)) else {
59+
guard let decodedAttestationObject = try? CBOR.decode([UInt8](attestationObjectData), options: CBOROptions(maximumDepth: 16)) else {
6060
throw WebAuthnError.invalidAttestationObject
6161
}
6262

Sources/WebAuthn/Ceremonies/Shared/AuthenticatorData.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ extension AuthenticatorData {
105105
/// **credentialPublicKey** (variable): The credential public key encoded in `COSE_Key` format, as defined in [Section 7](https://tools.ietf.org/html/rfc9052#section-7) of [RFC9052], using the CTAP2 canonical CBOR encoding form.
106106
/// Assuming valid CBOR, verify the public key's length by decoding the next CBOR item.
107107
let inputStream = ByteInputStream(data[credentialIDEndIndex...])
108-
let decoder = CBORDecoder(stream: inputStream)
108+
let decoder = CBORDecoder(stream: inputStream, options: CBOROptions(maximumDepth: 16))
109109
_ = try decoder.decodeItem()
110110
let publicKeyBytes = data[credentialIDEndIndex..<(data.count - inputStream.remainingBytes)]
111111

Sources/WebAuthn/Ceremonies/Shared/CredentialPublicKey.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ enum CredentialPublicKey {
4040
}
4141

4242
init(publicKeyBytes: [UInt8]) throws {
43-
guard let publicKeyObject = try CBOR.decode(publicKeyBytes) else {
43+
guard let publicKeyObject = try CBOR.decode(publicKeyBytes, options: CBOROptions(maximumDepth: 16)) else {
4444
throw WebAuthnError.badPublicKeyBytes
4545
}
4646

Tests/WebAuthnTests/WebAuthnManagerRegistrationTests.swift

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -356,18 +356,14 @@ final class WebAuthnManagerRegistrationTests: XCTestCase {
356356
XCTAssertEqual(credential.publicKey, credentialPublicKey)
357357
}
358358

359-
// Swift CBOR library currently crashes when running this test. WE NEED TO FIX THIS
360-
// TODO: Fix this test
361-
// func testFinishRegistrationFuzzying() async throws {
362-
// for _ in 1...50 {
363-
// let length = Int.random(in: 1...10_000_000)
364-
// let randomAttestationObject: URLEncodedBase64 = Data(
365-
// [UInt8](repeating: UInt8.random(), count: length)
366-
// ).base64URLEncodedString()
367-
// let shouldBeNil = try? await finishRegistration(attestationObject: randomAttestationObject)
368-
// XCTAssertNil(shouldBeNil)
369-
// }
370-
// }
359+
func testFinishRegistrationFuzzying() async throws {
360+
for _ in 1...50 {
361+
let length = Int.random(in: 1...10_000_000)
362+
let randomAttestationObject = Array(repeating: UInt8.random(), count: length)
363+
let shouldBeNil = try? await finishRegistration(attestationObject: randomAttestationObject)
364+
XCTAssertNil(shouldBeNil)
365+
}
366+
}
371367

372368
private func finishRegistration(
373369
challenge: [UInt8] = TestConstants.mockChallenge,

0 commit comments

Comments
 (0)