Successfully implemented a new static analysis rule to detect unsafe PRNG (Pseudo-Random Number Generator) usage in Soroban smart contracts. The rule identifies cases where env.prng() is used in state-critical code without proper seeding, which can lead to predictable randomness vulnerabilities.
- Rule Name:
unsafe_prng - Finding Code:
S017 - Severity: Warning
- Detection Logic:
- Identifies functions using
env.prng()or PRNG-related methods - Checks for storage mutations (
set,update,remove,extend_ttl,bump) - Flags cases where PRNG is used with storage mutations but without
reseed()calls
- Identifies functions using
- Added
UNSAFE_PRNGconstant with codeS017 - Category:
randomness - Description: "Use of PRNG without proper seeding in state-critical code that could lead to predictable randomness"
- Registered
unsafe_prngmodule - Added rule to default rule registry
- Integrated with existing rule infrastructure
Demonstrates both vulnerable and safe patterns:
Vulnerable Patterns (Flagged):
draw_winner_unsafe()- Lottery without reseedingdistribute_rewards_unsafe()- Token distribution with predictable randomness
Safe Patterns (Not Flagged):
get_random_number()- Read-only PRNG usageset_value()- Storage mutation without PRNG
-
Rule Documentation (
docs/rules/unsafe-prng.md):- Detailed explanation of the vulnerability
- Code examples (vulnerable and safe)
- Mitigation strategies
- References to security standards (CWE-338, OWASP)
-
Example Contract README (
contracts/unsafe-prng-example/README.md):- Quick reference for developers
- Testing instructions
All tests passing (136 tests total):
✅ flags_prng_usage_with_storage_mutation_without_reseed
✅ no_violation_when_prng_reseeded
✅ no_violation_when_prng_without_storage_mutation
✅ no_violation_when_only_storage_mutation
✅ flags_v21_prng_host_functions
✅ empty_source_produces_no_findings
✅ invalid_source_produces_no_panic
This rule helps prevent:
- Predictable Lottery Outcomes: Attackers can't predict winners in lottery/gaming contracts
- Manipulated Token Distribution: Random airdrops and rewards can't be gamed
- NFT Trait Manipulation: Random trait generation becomes more secure
- General Randomness Vulnerabilities: Any state-critical randomness is flagged
# Test the rule
cargo test -p sanctifier-core unsafe_prng
# Test example contract
cargo test -p unsafe-prng-example
# Run all tests
cargo test -p sanctifier-core --libThe rule is automatically included in the default rule registry:
let registry = RuleRegistry::with_default_rules();
let violations = registry.run_all(source_code);- Parse Rust source code using
syncrate - Traverse AST to find function implementations
- For each function:
- Track PRNG usage (
env.prng(),gen_range(), etc.) - Track storage mutations (
set(),update(), etc.) - Track reseed calls (
reseed())
- Track PRNG usage (
- Flag if:
has_prng_usage && has_storage_mutation && !has_prng_reseed
env.prng()- Main PRNG accessorgen_range()- Generate random number in rangeshuffle()- Shuffle vector (v21)prng_u64_in_inclusive_range()- v21 host functionprng_bytes_new()- v21 host functionprng_vec_shuffle()- v21 host function
Detects mutations on:
env.storage().persistent()env.storage().temporary()env.storage().instance()
Methods: set, update, remove, extend_ttl, bump
- No Inter-Function Analysis: Doesn't track PRNG usage across function calls
- Reseed Detection: Only detects direct
reseed()calls in the same function - False Positives: May flag non-critical randomness (cosmetic features)
- Control Flow Analysis: Track PRNG state across function boundaries
- Entropy Source Analysis: Evaluate quality of reseeding entropy
- Configuration Options: Allow users to specify acceptable patterns
- Auto-Fix Suggestions: Propose specific reseeding strategies
- S001 (AUTH_GAP): Missing authentication checks
- S013 (REENTRANCY): Reentrancy vulnerabilities
- S016 (TRUNCATION_BOUNDS): Integer truncation issues
- Soroban PRNG Documentation
- CWE-338: Use of Cryptographically Weak PRNG
- OWASP: Insufficient Randomness
The unsafe PRNG detection rule successfully identifies a critical security vulnerability in Soroban smart contracts. It provides clear warnings with actionable suggestions, helping developers build more secure decentralized applications.