T09 · Insecure Skill Coding Practices
Error
- Location
- src/index.ts:241
- Finding
- Reusable Identity Secrets Are Disclosed to the Remote API and Public Blockchain## Vulnerability Details **File Location**: `src/index.ts:241-246`, `src/index.ts:425-433`, `src/index.ts:576-592`, `src/index.ts:770-781`, `src/index.ts:905-913`, `src/index.ts:1148-1185`, and `src/index.ts:1234-1288` **Vulnerability Type**: Sensitive authentication material disclosure **Risk Level**: High ### Vulnerable Code Room creation sends Party A's identity secret to the configured API: ```typescript const body = { roomId, numericRoomId: numericId, partyAIdentitySecret: identitySecret, partyAIdentityHash: identityHash, expiresIn: options.expiresIn || 3600, }; ``` Joining a room sends Party B's identity secret to the API: ```typescript const body = { wallet: this.wallet.publicKey.toBase58(), partyB: this.wallet.publicKey.toBase58(), partyBIdentitySecret: identitySecret, txSignature, signature: sig, ts, }; ``` Cancellation sends both the participant identity secret and Party A's identity secret: ```typescript const res = await fetch( `${this.config.apiUrl}/api/trade-rooms/cancel-onchain`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ roomId, numericRoomId: room.numericRoomId, partyAIdentityHash: room.partyAIdentityHash, partyAIdentitySecret: room.partyAIdentitySecret, isPartyA, identitySecret, partyASlots, partyBSlots, }), } ); ``` Claiming locked tokens also sends the identity secret to the service: ```typescript const res = await fetch( `${this.config.apiUrl}/api/trade-rooms/claim-locked`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ roomId, numericRoomId: room.numericRoomId, partyAIdentityHash: room.partyAIdentityHash, isPartyA, identitySecret, tokenSlots, }), } ); ``` The same secre ...[truncated 3489 chars]
- Remediation
- ## Remediation Suggestions 1. Stop including `partyAIdentitySecret` and `partyBIdentitySecret` in API request bodies and API responses. 2. Never place reusable confidential values in Solana transaction instruction data. 3. Replace preimage-based authorization with wallet signatures over canonical, operation-specific payloads. 4. Bind each signature to: - The protocol and network. - The exact action. - The room ID. - The participant role. - All token, recipient, lockup, and transaction parameters. - A server-issued nonce. - A short expiration time. 5. Enforce one-time nonce consumption and participant-role validation on the server. 6. If identity commitments are a protocol requirement, use a construction that proves knowledge without revealing a reusable preimage. 7. Store any unavoidable client-side secret in protected local storage and erase it after the room lifecycle ends. 8. Remove identity-secret fields from `TradeRoom` responses and redact them from all application and infrastructure logs. 9. Rotate or invalidate existing room secrets because previously submitted transaction data may remain publicly accessible. 10. Document the trust boundary introduced by the API and relayer instead of describing the complete workflow as requiring no trust.
