Skip to content

MF3-L12: validate session-key scope ID formats at request boundary#826

Merged
philanton merged 2 commits into
fix/audit-findings-finalx3from
fix/mf3-l12
Jun 10, 2026
Merged

MF3-L12: validate session-key scope ID formats at request boundary#826
philanton merged 2 commits into
fix/audit-findings-finalx3from
fix/mf3-l12

Conversation

@philanton

Copy link
Copy Markdown
Contributor

What

app_sessions.v1.submit_session_key_state only validated array length and lowercasing for application_ids and app_session_ids. It did not validate each ID's format. As a result malformed-but-lowercase IDs passed request validation, reached signature verification, and could persist as inert, unusable scopes (never matching a real application/app-session).

This aligns the handler with the validation already applied in create_app_session and the RPC application_id query-param path.

Changes

  • application_ids: replaced the lowercase-only loop with app.IsValidApplicationID() (regex ^[a-z0-9_-]{1,66}$, which already enforces lowercase).
  • app_session_ids: added core.IsValidHash() (^0x[0-9a-fA-F]{64}$) before the lowercase canonical check. IsValidHash is case-insensitive, so the lowercase check is kept.
  • Both checks run before signature verification — fail fast at the request boundary. Array-length caps unchanged.
  • Tests: refactored the two stale lowercase-only tests into a shared submitStateExpectingError helper; added format-rejection cases (uppercase / illegal char / over-length application IDs; non-hash / short / no-0x / uppercase-hex app-session IDs).

Severity

Low — hardening/consistency, not an exploitable vuln. The request is self-authenticated (both user_sig and session_key_sig gate persistence, so no injection into another user's state), and DB column constraints (VARCHAR(66) / CHAR(66)) already reject oversized values. Worst real case is a user signing their own malformed scope that silently never authorizes anything; this rejects it up front instead.

Test

go build ./nitronode/api/app_session_v1/
go vet  ./nitronode/api/app_session_v1/
go test ./nitronode/api/app_session_v1/ -run TestSubmitSessionKeyState

All green.

🤖 Generated with Claude Code

…dary

submit_session_key_state only checked array length and lowercasing for
ApplicationIDs and AppSessionIDs, letting malformed-but-lowercase IDs
reach signature verification and persist as inert, unusable scopes.

Validate each application_id with app.IsValidApplicationID (subsumes the
lowercase check) and each app_session_id with core.IsValidHash plus the
lowercase canonical check, rejecting both at the request boundary —
matching the validation already applied in create_app_session.

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

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 15752e16-c7cf-4354-ab71-261951c48046

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mf3-l12

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@philanton philanton changed the base branch from main to fix/audit-findings-finalx3 June 8, 2026 09:13

@nksazonov nksazonov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good job — the fix correctly addresses the audit finding by moving both IsValidApplicationID and IsValidHash checks ahead of signature verification, closing the malformed-but-lowercase bypass. Two minor polish items below.

Comment thread nitronode/api/app_session_v1/submit_session_key_state.go Outdated
Comment thread nitronode/api/app_session_v1/submit_session_key_state.go Outdated

@ihsraham ihsraham left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No blockers from me. Approving for L-12 closure.

The fix moves both scope-ID format checks to the request boundary before signature verification and storage. application_ids now use app.IsValidApplicationID, and app_session_ids require a 32-byte hash shape plus lowercase canonical form. The new tests also cover malformed app IDs and app-session IDs and assert those requests do not reach LockSessionKeyState, which is the right proof for this finding.

What is still worth cleaning up is not a closure blocker: the public docs/API wording still describes these arrays as loose lowercase strings rather than the stricter formats now enforced. I would update that in the release/docs pass so clients do not copy the old shape.

Collapse the two app_session_ids guards (hash shape + lowercase) into a
single IsValidHash(id, true) check with one error message, so callers see
one error surface for the single "0x-prefixed 32-byte lowercase hex hash"
rule. Replace the leaked ApplicationIDRegex string in the application_ids
error with stable human-readable wording.

IsValidHash gains a requireLowercase arg backed by LowercaseHashRegex;
existing checksummed-tolerant callers (get_app_sessions, get_escrow_channel)
pass false. Docs (api.yaml, app_session_v1 README) now describe the exact
enforced formats instead of "loose lowercase strings".

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

Copy link
Copy Markdown
Contributor Author

@ihsraham good catch on the docs — went ahead and updated them in 59d9f15: api.yaml and the app_session_v1 README now spell out the exact formats (^[a-z0-9_-]{1,66}$ and ^0x[0-9a-f]{64}$) instead of "loose lowercase strings".

@philanton philanton merged commit 568c364 into fix/audit-findings-finalx3 Jun 10, 2026
5 of 7 checks passed
@philanton philanton deleted the fix/mf3-l12 branch June 10, 2026 15:10
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