← All issues

[14] WebCrypto EC SPKI/PKCS8 importer bounds check

Severity: High | Component: WebCore Web Crypto | d3de21e

renderer에서 도달 가능한 parser 버그를 수정하는 패치이므로 High로 평가됩니다. 0xFF length byte가 parse cursor를 buffer 끝 기준 128바이트 이상 이동시킵니다. SPKI 경로에서는 keyData.size() - index에서 unsigned underflow가 발생하고, PKCS8 경로에서는 subvector(index) OOB로 인해 RELEASE_ASSERT를 통한 crash가 발생합니다.

CryptoKeyEC::platformImportSpkiplatformImportPkcs8 모두 bounds check 없이 indexbytesUsedToEncodedLength(keyData[index]) + 1만큼 이동시켰습니다. long-form length byte는 최대 128을 반환하므로, indexkeyData.size()를 크게 초과하게 됩니다.

Source/WebCore/crypto/cocoa/CryptoKeyECCocoa.cpp

index += 1; // BIT STRING 읽기
+ if (index + bytesUsedToEncodedLength(keyData[index]) + 1 > keyData.size())
+ return nullptr;
index += bytesUsedToEncodedLength(keyData[index]) + 1;
auto keySize = keyData.size() - index;

두 importer 모두에서 cursor 이동 직전에 bounds check가 추가되었습니다. 또한 기존 RSA 테스트에 일대일로 대응하는 EC LayoutTest 6개가 추가되었습니다.

공격자 제어 ASN.1 length byte에 대한 advance 후 bounds check 누락 — parse cursor가 buffer 끝을 초과하는 패턴.

SubtleCrypto.importKey는 SPKI (SubjectPublicKeyInfo) 또는 PKCS8 (PrivateKeyInfo) 형식의 바이트 데이터를 입력으로 받습니다. ASN.1 DER length 인코딩은 두 가지로 나뉩니다. 0x80 미만의 byte는 길이를 직접 나타내고, 0x80 이상인 경우에는 이후에 오는 byte 수가 실제 길이 값을 구성합니다. 예를 들어 0xFF는 이후 127바이트가 길이를 인코딩하므로, length field 자체가 최대 128바이트를 차지하게 됩니다. bytesUsedToEncodedLength(b)는 이 length field의 바이트 수를 반환합니다. 한편 Vector<uint8_t>::subvector(offset)offset <= size()RELEASE_ASSERT로 검증합니다.

commit 메시지에 명확히 기재되어 있습니다. 308706@main에서 RSA에 대해 동일한 버그가 수정되었지만, EC 경로에 대한 적용은 빠졌습니다.

🔒

How a single malformed length byte in a `crypto.subtle.importKey` call drives the parse cursor off the end of the buffer — and what the two diverging consequences mean for the renderer.

더 확인하려면 구독해 주세요

🔒

Multiple reusable audit patterns identified across WebKit's ASN.1 / DER parsers, with concrete starting points for variant discovery in sibling-algorithm key importers.

더 확인하려면 구독해 주세요