Don't use System.Random for security purposes
System.Random is weak: its numbers can be predicted, which can lead to vulnerabilities in a security critical context (tokens, session ids, salts, password reset codes, CAPTCHA...).
This is CWE-338 Use of Cryptographically Weak Pseudo-Random Number Generator.
Flagged Code
This is CWE-338 Use of Cryptographically Weak Pseudo-Random Number Generator.
Flagged Code
string CreatePasswordResetCode() {
var random = new Random(); // flagged: predictable generator
return random.Next(100000, 999999).ToString();
}
string CreateSessionId() => Random.Shared.NextInt64().ToString("x"); // flagged: Random.Shared
Fixed Codestring CreatePasswordResetCode() => RandomNumberGenerator.GetInt32(100000, 1000000).ToString(); string CreateSessionId() => RandomNumberGenerator.GetHexString(32);
How to fix
In a security critical context use System.Security.Cryptography.RandomNumberGenerator (GetInt32(), GetBytes(), GetHexString(), GetString()): slower, but unpredictable. See: https://stackoverflow.com/questions/32932679/using-rngcryptoserviceprovider-to-generate-random-string Otherwise keep the faster System.Random and suppress the issues. More on System.Random weakness: https://stackoverflow.com/a/6842191/27194
CQLinq source
This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.
// <Name>Don't use System.Random for security purposes</Name>
// <Id>ND3101:DontUseSystemRandomForSecurityPurposes</Id>
warnif count > 0
from m in Application.Methods
where m.CreateA("System.Random".AllowNoMatch()) ||
m.IsUsing("System.Random.get_Shared()".AllowNoMatch())
select new {
m,
Debt = 15.ToMinutes().ToDebt(),
AnnualInterest = 1.ToHours().ToAnnualInterest()
}
//<Expl>
// The *{0}* should not use *System.Random* (nor *Random.Shared*) because it is a
// *weak* pseudo-random number generator.
// This can potentially allow an attacker to predict security-sensitive
// values that are generated.
//</Expl>
//<Desc>
// **System.Random** is weak: its numbers can be predicted, which can lead
// to vulnerabilities in a security critical context (tokens, session ids,
// salts, password reset codes, CAPTCHA...).
//
// This is CWE-338 *Use of Cryptographically Weak Pseudo-Random Number Generator*.
//
// **Flagged Code**
// ```csharp
// string CreatePasswordResetCode() {
// var random = new Random(); // flagged: predictable generator
// return random.Next(100000, 999999).ToString();
// }
//
// string CreateSessionId() => Random.Shared.NextInt64().ToString("x"); // flagged: Random.Shared
// ```
//
// **Fixed Code**
// ```csharp
// string CreatePasswordResetCode() =>
// RandomNumberGenerator.GetInt32(100000, 1000000).ToString();
//
// string CreateSessionId() => RandomNumberGenerator.GetHexString(32);
// ```
//</Desc>
//<HowToFix>
// In a security critical context use
// **System.Security.Cryptography.RandomNumberGenerator** (*GetInt32()*,
// *GetBytes()*, *GetHexString()*, *GetString()*): slower, but unpredictable.
// See: https://stackoverflow.com/questions/32932679/using-rngcryptoserviceprovider-to-generate-random-string
// Otherwise keep the faster **System.Random** and suppress the issues.
// More on *System.Random* weakness: https://stackoverflow.com/a/6842191/27194
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
Security: all 39 items
- Software Composition Analysis (SCA) ND3120
- Transitive Software Composition Analysis (SCA) ND3121
- Don't hard-code secrets in constants ND3114
- Review credentials built from hard-coded values ND3115
- Don't use insecure deserializers ND3110
- Don't use weak hash algorithms (MD5, SHA1) ND3109
- Don't use DES/3DES/RC2 weak cipher algorithms ND3102
- Don't use weak password-based key derivation ND3123
- Don't use the ECB encryption mode ND3132
- Don't disable certificate validation ND3103
- Don't hard-code TLS/SSL protocol versions ND3122
- Review commands vulnerable to SQL injection ND3107
- Review data adapters vulnerable to SQL injection ND3108
- Review raw SQL built from composed strings ND3128
- Review LDAP filters composed from strings ND3137
- Don't enable external XML entity resolution (XXE) ND3111
- Review processes started with a composed arguments string ND3124
- Review web endpoints building file paths from their parameters ND3129
- Review custom archive extraction (Zip Slip) ND3135
- Review assemblies and types loaded from runtime-provided names ND3125
- Review web endpoints without [Authorize] nor [AllowAnonymous] ND3118
- Review state-changing endpoints opened to anonymous callers ND3130
- Review state-changing MVC actions without anti-forgery validation ND3119
- Review HTML-encoding bypasses ND3133
- Review explicitly disabled request validation ND3134
- Review redirects to a URL that is not validated as local ND3126
- Review request-influenced outbound HTTP calls (SSRF) ND3136
- Review insecure ASP.NET Core CORS policies and unguarded developer exception page ND3116
- Review cookies created without HttpOnly and Secure flags ND3117
- Review regular expressions without a match timeout (ReDoS) ND3112
- Review secrets compared with non-constant-time equality ND3113
- Review secrets passed to logging methods ND3127
- Review security operations that log nothing ND3131
- Don't use System.Random for security purposes ND3101
- Don't use CoSetProxyBlanket and CoInitializeSecurity ND3100
- Review publicly visible event handlers ND3104
- Pointers should not be publicly visible ND3105
- Seal methods that satisfy non-public interfaces ND3106
- Restrict sensitive APIs to reviewed components ND3138