Skip to content

This can be an attack surface: der::decode() silently accepts trailing bytes — signature bypass vector #552

@tynus2

Description

@tynus2

Hi rasn maintainers,

I'm reporting a (potential) security issue in rasn's der::decode() that affects all versions through 0.28.11.
(seems I cannot get a email addr, and now there is not private issues, so I can only report it here)

Summary

rasn::der::decode() does not verify that all input bytes are consumed after decoding. X.690 DER §8.1.1.1 mandates that a DER encoding is exactly one complete TLV with no trailing data. Currently, der::decode() delegates to T::decode() and returns the result without checking decoder.remaining():

// src/der.rs:6-11
pub fn decode<T: crate::Decode>(input: &[u8]) -> Result<T, crate::error::DecodeError> {
    T::decode(&mut crate::ber::de::Decoder::new(
        input,
        crate::ber::de::DecoderOptions::der(),
    ))
    // ← No check that all input was consumed
}

This means rasn::der::decode::<Null>(&[0x05, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]) succeeds silently, accepting 4 trailing garbage bytes.

Security Impact

This bug is structurally identical to several assigned CVEs for the same class of issue:

CVE Lib CVSS Bug
CVE-2018-16150 axTLS High Trailing bytes in PKCS#1 → Bleichenbacher forgery
CVE-2018-16151/16152 strongswan High Trailing bytes in ASN.1 → signature bypass
CVE-2014-1569 NSS Critical DER permissiveness enables data smuggling

Concrete attack scenarios:

  1. Bleichenbacher-style signature forgery: If rasn is used to parse decrypted PKCS#1 v1.5 DigestInfo, trailing bytes after the ASN.1 structure are silently accepted. With RSA e=3, an attacker can forge signatures.
  2. Two-parser chain bypass: If a strict DER parser signs/verifies bytes and rasn parses the same input, appended data is invisible to rasn but changes the byte representation — enabling signature verification bypass.
  3. Round-trip divergence: decode(input) then encode(value) produces different bytes than the original, breaking certificate transparency logs, replay detection, and any system comparing raw DER encodings.

Reproduction

use rasn::der;
use rasn::types::Null;

let input = &[0x05, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; // NULL + trailing garbage
let result = der::decode::<Null>(input);
assert!(result.is_ok()); // BUG: should reject trailing bytes

Discovery

Found via source code audit during differential fuzzing

I saw you provide a interface for rasn-pkix, so I think this should be reported as a security issue.
Looking forward to your reply.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions