Skip to content

Handle malformed XDR in the smart-contract address conversion example #2768

Closed

Description

@kalepail

Note

Automated notice: Stellar Raven filed this issue from its automated evaluation pipeline. The issue includes evidence and a public source record. Please verify the live surface before you act.

Finding

The smart-contract address conversion example accepts Bytes and calls
Address::from_xdr(&env, &bytes).unwrap().

from_xdr is fallible. The unwrap() call therefore panics when the bytes do
not contain a valid address value.

The page names custom authentication as a use case. That use case can process
untrusted bytes, so malformed input is a normal trust-boundary condition.

The page gives no fallible return, validation step, contract error, or malformed-input test.

Evidence

This live read reproduced the example on 2026-08-11:

await stellarDocs.get_doc_page_sections({
  path: "/docs/build/guides/conversions/address-conversions",
  includeContent: true,
});
// address_from_xdr_bytes(...) -> Address {
//   Address::from_xdr(&env, &bytes).unwrap()
// }

Six focused searches covered Address::from_xdr, malformed XDR, input length,
untrusted bytes, decode panics, and malformed input.

The searches found the conversion page. They found no warning or safe decoding example.

The live smart-contract skill covered typed errors, panic_with_error!, and generated try_* clients.
It did not cover malformed XDR or from_xdr at a trust boundary.

Additional recorded evidence:

  • 2026-08-11 live stellarDocs.get_doc_page_sections for /docs/build/guides/conversions/address-conversions returned Address::from_xdr(&env, &bytes).unwrap() in the smart-contract example
  • 2026-08-11 six live Soroban documentation searches found the conversion page but no malformed-XDR handling guidance
  • 2026-08-11 live smart-contract skill read found generic panic and try_* guidance but no from_xdr or malformed-input rule

Recommendation

Replace the infallible example with a fallible function. Return a result or map decode failure to a contract error.

Add one malformed-byte test. State that contracts must not call unwrap() on untrusted XDR input.

If the expected XDR shape has a fixed length, show that guard before decoding.

Source Record

Raven recorded this finding as sd-040 (stellar-docs, discovered 2026-08-11).

Public source record: improvements/stellar-docs/sd-040-address-from-xdr-unwrap-malformed-input.md

Immutable source snapshot: aa71fa0a5b8f

Resolution Handoff

When you deploy a fix, link the resolving issue or pull request to the source record.
Then notify Raven through:

https://github.com/stellar-experimental/stellar-raven/issues/new?template=upstream-improvement-ready.yml&title=%5Bupstream-ready%5D%20sd-040%3A%20

Include the finding ID and the resolving issue or pull request.
Include the deployed version or timestamp. Include the smallest live recheck.
Raven verifies the live surface before it sets the finding to fixed-upstream.
An issue closure or merged pull request does not prove the fix.
A separate reviewer repeats the live check before Raven retires the active finding.
Raven keeps a commit-pinned snapshot when one is available.

Activity

  1. added
    ravenissues discovered by Stellar Raven QA passes
    on Aug 19, 2026
  2. devtechedge commented on Sep 11, 2026

    @devtechedge
    Contributor

    Hi, I'd like to work on this.

    The example on the address conversions page calls Address::from_xdr(&env, &bytes).unwrap(), which shows a panic path rather than a handled one.

    Address::from_xdr returns Result<Address, ConversionError>, so I'll change the example to propagate that result instead of unwrapping it.

    I'll also add a short note on the two failure modes: bytes that are valid XDR for a different ScVal come back as a handleable ConversionError, while bytes that are not valid XDR at all panic inside from_xdr with no way to recover in the contract.

    Once the PR is up I'll link it here.

  3. kaankacar commented on Sep 11, 2026

    @kaankacar
    Contributor

    Working this because Raven filed it (label raven).

    I verified the finding. main still has Address::from_xdr(&env, &bytes).unwrap() on that page.

    PR #2849 from @devtechedge fixes it. I will not open a second PR.

    I checked that PR against the soroban-sdk source. Both of its claims hold:

    • Address::from_xdr returns Result<Address, ConversionError>.
    • Bytes that are not valid XDR for any ScVal panic inside from_xdr, with no in-contract recovery.

    After #2849 merges, this issue still needs the Raven sd-040 handoff.

  4. added a commit that references this issue on Sep 14, 2026
    4191983
  5. ElliotFriend commented on Sep 15, 2026

    @ElliotFriend
    Contributor

    Deployed and handed back to Raven for independent recheck: stellar-experimental/stellar-raven#158

    Fixed by #2849 (merge commit 41919839, 2026-09-14T20:33:10Z), deploy succeeded 20:38:31Z, corrected content observed live at 2026-09-15T19:43:09Z. The example now returns Result<Address, ConversionError> and the prose names both failure modes, including the panic the SDK cannot recover from.

  6. kalepail commented on Sep 16, 2026

    @kalepail
    ContributorAuthor

    Raven independently verified this fix on September 16, 2026.

    The rendered page and the affected indexed section contain the fallible conversion example without unwrap. The complete index read returned 7 sections. The text distinguishes conversion errors from malformed-XDR panics.

    A separate reviewer repeated the source and index checks.
    Raven will retire sd-040 after recording the resolution receipt.

    Original finding

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ravenissues discovered by Stellar Raven QA passes

    Type

    No type

    Projects

    • Status
      No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions