Security audit fixes (2026-04): TRON rawData verify, feedback @-mentions, RPC URL redaction, vitest 4 - #30
Merged
Conversation
Addresses findings from the 2026-04 internal audit plus Socket.dev supply-chain triage. M1 — TRON rawDataHex verification before signing Every TronGrid builder now decodes the returned Transaction.raw protobuf and asserts the inner contract matches the caller's intent (owner_address / to_address / amount / contract_address / calldata / vote_count / resource / fee_limit) byte-for-byte before the handle is issued. Closes the MITM window where a compromised TronGrid response could swap destination or amount between the JSON preview we show the user and the hex the Ledger actually signs. New: src/modules/tron/verify-raw-data.ts (minimal protobuf decoder + per-contract-type expectation matcher; no new deps). Wired into all seven builders in src/modules/tron/actions.ts. Covered by test/tron-raw-data-verify.test.ts (15 cases: 5 happy-path + 10 tamper-detection including swapped to_address/amount/owner/ contract-type/TRC20-contract/TRC20-calldata/vote-count/resource, invalid hex, truncated protobuf). M2 — Neutralize @-mentions in feedback issue titles GitHub parses @-mentions in issue titles, not just bodies. A prompt- injected summary string containing '@someuser' would ping arbitrary users when opening the issue. Title is now run through the same neutralizeMentions() helper as the body. L1 — Redact RPC URLs from config-error messages Configured RPC URLs commonly embed a provider API key in the path (e.g. .../v3/<key>). RpcConfigError no longer interpolates the URL into its message, so malformed URLs don't leak the key into logs/ stderr. I1 — npm audit clean Bumped vitest ^2.1.0 → ^4.1.4, pulling in a vite/esbuild chain that resolves GHSA-67mh-4wv8-2f99 (dev-only). All 341 tests pass unchanged on the new major. npm audit now reports 0 vulnerabilities. Socket.dev supply-chain triage (no code change): - picomatch@2.3.2 ReDoS (transitive via @walletconnect/keyvaluestorage → unstorage → anymatch@3): not reachable in our deployment — glob patterns are WC-internal storage keys, never user-controlled input. Upgrading requires an npm override to picomatch@4 which is ESM-only and breaks anymatch@3's CJS usage. Leaving as-is. - @0no-co/graphqlsp / @gql.tada/cli-utils (network + shell access): dev-only GraphQL LSP + CLI pulled transitively via @lifi/sdk → @mysten/sui → gql.tada. Not invoked at runtime. - node-mock-http / parseurl "typosquat" flags: false positives; both are legitimate UnJS / jshttp packages pinned in lockfile. - content-disposition unstable-ownership: legit maintainer transition on a transitive express dep; not actionable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
szhygulin
added a commit
that referenced
this pull request
Apr 14, 2026
Security patch release — no API changes, no breaking behaviour. Contains: - TRON rawDataHex verification before Ledger signing (MITM defence) - Feedback issue titles now neutralize @-mentions - RPC config errors no longer echo URLs (prevents API-key leak in logs) - vitest 2.x → 4.x (resolves GHSA-67mh-4wv8-2f99, dev-only) See PR #30 for full details and Socket.dev triage. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Transaction.rawprotobuf and asserts the inner contract matches caller intent byte-for-byte before the signing handle is issued. Closes the MITM window where a compromised TronGrid response could swap destination/amount/contract between the JSON preview shown to the user and the hex the Ledger actually signs.RpcConfigError. Provider API keys commonly live in the URL path; no longer interpolated into error messages that end up in logs.^2.1.0→^4.1.4. Pulls a vite/esbuild chain that resolves GHSA-67mh-4wv8-2f99 (dev-only). All 341 tests pass unchanged.npm audit→ 0 vulns.TRON verifier details
New
src/modules/tron/verify-raw-data.ts(~250 LOC) decodesTransaction.raw→Contract→google.protobuf.Any→ the inner contract using a minimal wire-format parser (no new deps), then matches against a discriminated-unionTronRawDataExpectationfor all seven contract kinds:TransferContract(native TRX send)TriggerSmartContract(TRC-20)VoteWitnessContractFreezeBalanceV2Contract/UnfreezeBalanceV2ContractWithdrawExpireUnfreezeContractWithdrawBalanceContractCovered by
test/tron-raw-data-verify.test.ts: 5 happy-path + 10 tamper-detection cases (swappedto_address/amount/owner_address/ contract-type / TRC-20 contract / TRC-20 calldata / vote_count / resource, invalid hex, truncated protobuf).Socket.dev triage (no code change)
picomatch@2.3.2@walletconnect/keyvaluestorage → unstorage → anymatch@3. Patterns are WC-internal storage keys, never user-controlled.picomatch@4is ESM-only and breaksanymatch@3's CJS usage.@0no-co/graphqlsp@1.15.3@lifi/sdk → @mysten/sui → gql.tada. Not invoked at runtime.@gql.tada/cli-utils@1.7.3node-mock-http/parseurlcontent-disposition@1.1.0Test plan
npx vitest run— 341/341 passnpx tsc --noEmit— cleannpm audit— 0 vulnerabilitiesraw_data_hexlocally) → verifier should throw before handle is issued🤖 Generated with Claude Code