Skip to content

fix(ic-agent): return errors instead of panicking on malformed certified data; release 0.49.3 - #744

Merged
lwshang merged 3 commits into
mainfrom
fix/no-panic-on-malformed-certified-data
Oct 23, 2026
Merged

lwshang merged 3 commits into
mainfrom
fix/no-panic-on-malformed-certified-data

Conversation

@lwshang

@lwshang lwshang commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

A subnet can sign a certificate that verifies correctly but has an unexpected shape inside. Several lookups in ic-agent assumed the shape and would panic. They now return an AgentError:

Location Before After
lookup_incomplete_subnet Principal::from_slice panics on a /subnet/<id>/node/<label> longer than 29 bytes try_from_slice → AgentError::PrincipalError
lookup_canister_ranges shard[0] panics when /canister_ranges/<id> is a bare leaf shard paths must be exactly one label, otherwise CertificateVerificationFailed
lookup_api_boundary_nodes path[0] panics when /api_boundary_nodes is a bare leaf CertificateVerificationFailed
fetch_subnet_by_canister Principal::from_slice(&delegation.subnet_id) panics on a blob longer than 29 bytes try_from_slice → AgentError::PrincipalError

Affected public APIs: Agent::fetch_subnet_by_id, Agent::fetch_subnet_by_canister (and therefore get_subnet_by_canister), Agent::fetch_api_boundary_nodes_by_{canister,subnet}_id.

Only a subnet that signs malformed state can trigger these. That matters for cloud engines, which are not trusted the way regular subnets are. The delegation subnet_id case is NNS-signed, so it isn't reachable in practice; this change just makes it fail gracefully. A core protocol teammate reported these issues.

check_delegation already handled the shard-path case safely; this change makes the other lookups consistent with it.

Release

The second commit prepares 0.49.3. It bumps all workspace crates and Cargo.lock, and cuts the Unreleased changelog section, which also contains #743.

CI fix

The third commit bumps async-trait from 0.1.89 to 0.1.92 in Cargo.lock. Rust 1.99's clippy flags double_must_use on code generated by #[async_trait], which broke lint for any branch based on main; the problem was already there before this PR. The new version pulls in syn 3, and both crates need Rust 1.71 or newer, so the MSRV (1.88) is unaffected. I checked this with cargo +1.88.0 check --workspace.

Testing

  • New unit tests in response_authentication.rs build malformed trees for the first three cases. Each test panics on main and passes on this branch.
  • cargo test -p ic-agent --lib: 61 passed.
  • The delegation.subnet_id case has no test, because building it would require a delegation that passes verification.

🤖 Generated with Claude Code

lwshang and others added 3 commits October 22, 2026 12:02
…ied data

A subnet can sign a certificate whose tree is well-formed but whose
contents are not. Several lookups trusted that shape and panicked:

- `lookup_incomplete_subnet`: `Principal::from_slice` on a node label
  longer than 29 bytes.
- `lookup_canister_ranges`: `shard[0]` when `/canister_ranges/<id>` is a
  bare leaf.
- `lookup_api_boundary_nodes`: `path[0]` when `/api_boundary_nodes` is a
  bare leaf.
- `fetch_subnet_by_canister`: `Principal::from_slice` on the delegation's
  `subnet_id` (NNS-signed, so not reachable in practice).

Use `Principal::try_from_slice` and reject unexpected path shapes with
`CertificateVerificationFailed`, and add regression tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bump all workspace crates 0.49.2 -> 0.49.3.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Rust 1.99 clippy flags `clippy::double_must_use` on the code generated by
async-trait 0.1.89, which fails the lint job under `-D warnings` on every
`#[async_trait]` trait. async-trait 0.1.92 no longer triggers it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The targeted guards preserve valid-data behavior, regression tests cover the reported malformed-tree cases, and no blocking issues remain.

No open issues 🎉

What changed in this PR

This PR hardens ic-agent against malformed certified data by returning errors instead of panicking, and prepares release 0.49.3.

Changes:

  • Adds fallible principal parsing and tree-path validation, with three malformed-tree regression tests.
  • Updates workspace versions and release notes, including the earlier root-attested subnet-routing fix.
  • Updates the locked async-trait dependency and adds syn 3 to address the reported Clippy failure.
File Description
ic-agent/​src/​agent/​response_authentication.rs Validates malformed node IDs and tree paths; adds regression tests.
ic-agent/​src/​agent/​mod.rs Returns an error for oversized delegation subnet IDs.
CHANGELOG.md Documents the fixes in release 0.49.3.
Cargo.toml Bumps workspace and internal dependency versions to 0.49.3.
Cargo.lock Records release versions and the procedural-macro dependency update.

Review effort: Balanced

@lwshang
lwshang marked this pull request as ready for review October 22, 2026 12:28
@lwshang
lwshang requested a review from a team as a code owner October 22, 2026 12:28
@zeropath-ai

zeropath-ai Bot commented Oct 22, 2026

Copy link
Copy Markdown

✅ No security or compliance issues detected. Reviewed everything up to 22a26f3.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► ic-agent/src/agent/mod.rs
      Change subnet_id extraction to use Principal::try_from_slice
► ic-agent/src/agent/response_authentication.rs
      Update node_id extraction to use Principal::try_from_slice
► ic-agent/src/agent/response_authentication.rs
      Adjust canister ranges lookup path to shard handling
► ic-agent/src/agent/response_authentication.rs
      Update canister_ranges_tree lookups to use shard.as_bytes
► ic-agent/src/agent/response_authentication.rs
      Update api_boundary_nodes extraction to use first path label bytes
► ic-agent/src/agent/response_authentication.rs
      Add tests for certificate/lookup validations in response authentication

@lwshang
lwshang merged commit 0857d7d into main Oct 23, 2026
23 checks passed
@lwshang
lwshang deleted the fix/no-panic-on-malformed-certified-data branch October 23, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants