Security Audit & Policies
Security Controls & Audit
CredChain's security posture rests on the contract itself, on signature-derived attribution, and on refusing to store anything that could be stolen. Below is the technical breakdown.
1. Smart Contract & Web3 Security Practices
- Checks-Effects-Interactions Pattern: Smart contract state mutations occur prior to external calls to eliminate reentrancy vulnerabilities.
- Checked Math Operations: All integer additions and counters utilize checked Rust arithmetic preventing overflow exploits.
- 300s Transaction Bounds: Expanded time-bounds window prevents wallet signature expirations and
tx_too_latesequence errors. - Raw XDR Exception Translation: Intercepts raw ledger errors and decodes contract revert codes (
1–6) into actionable remedies.
2. Admin Authority & Credential Storage
- Admin bound at deploy:
__constructor(admin)sets the admin as part of the deploy operation. There is no "set admin if unset" fallback, which would otherwise leave the admin seat claimable by any caller on a fresh contract. - Signature-derived attribution: Forum authorship comes from an Ed25519 signature verified server-side, never from the request body. An unsigned post claiming an address is published anonymously.
- No key material in storage: Wallet session persistence stores only a public address and which wallet was used. Every signature still goes through the extension, so a stolen session grants nothing that is not already public on the ledger.
- No credentials in source: Connection strings come from environment variables only. An earlier implementation hardcoded one; those files are gone, but the credential remains in git history and is treated as compromised.
3. Input Sanitization & SQL Injection Defense
The feedback API is the only server-side surface. It talks to Neon over the HTTP driver, and:
- All database queries use parameterized placeholders (
$1, $2, $3). String concatenation into SQL queries is strictly prohibited. - Input payload strings are truncated and sanitized on API receipt (comments max 500 characters, addresses max 100 characters).
- Ratings are integer-clamped between 1 and 5 (
Math.max(1, Math.min(5, rating))).