Skip to content

dpp-digital-link: malformed/duplicate AI segments silently mis-parsed; no length cap on decoded values #23

Description

@LKSNDRTMLKV

Static read-through audit of crates/dpp-digital-link. Five verified findings. No unsafe, no crypto, no reachable panics outside test code.

1. Trailing unpaired AI code is silently dropped

Location: src/digital_link/link.rs:78
Issue: while i + 1 < ai_segments.len() silently drops a dangling AI code with no paired value instead of erroring.
Failure scenario: https://id.odal-node.io/01/09506000134352/21 (odd segment count) parses successfully with serial: None instead of returning an error for the truncated/malformed URI.

2. Duplicate primary-key AI creates parser-differential ambiguity

Location: src/digital_link/link.rs:87-90
Issue: A second 01 segment later in the path unconditionally overwrites gtin with no duplicate/position check.
Failure scenario: .../01/09506000134352/21/SN1/01/00000000000001 parses; resolver_base's path prefix is computed from the first 01 occurrence while the final gtin field reflects the last one. Two consumers of this struct can disagree about which GTIN the URI refers to.

3. GS1-mandated length limits are declared but never enforced

Location: src/digital_link/ai.rs:15, src/digital_link/link.rs::parse
Issue: max_len is defined per-AI but never read in parse. Values decoded from an untrusted URI (percent_decode, line 84) have no length cap.
Failure scenario: A crafted Digital Link URI with an arbitrarily long serial/batch/variant value is accepted and propagated downstream into AAS submodels/JSON-LD payloads unbounded.

4. Non-object JSON silently discards the entire passport payload

Location: src/jsonld/context.rs:33-41
Issue: frame_passport returns a bare @context envelope with no error if passport isn't a JSON object.
Failure scenario: Any caller passing a non-object Value (e.g. from unvalidated deserialized input) gets a "successful" result containing no data, silently.

5. Dead code branch

Location: src/digital_link/link.rs:111-113
Issue: The AiRole::DataAttribute match arm is unreachable — no descriptor in AI_TABLE currently has that role.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsecuritySecurity-relevant issue

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions