skills/insufficient-randomness-anti-pattern/SKILL.md
Security anti-pattern for insufficient randomness vulnerabilities (CWE-330). Use when generating or reviewing code that creates security tokens, session IDs, encryption keys, nonces, or any security-critical random values. Detects use of Math.random() or predictable seeds.
npx skillsauth add igbuend/grimbard insufficient-randomness-anti-patternInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Severity: High
Insufficient randomness occurs when security-sensitive values (session tokens, password reset codes, encryption keys) are generated using predictable non-cryptographic PRNGs. AI models frequently suggest Math.random() or Python's random module for simplicity. These generators enable attackers to predict outputs after observing a few values, allowing token forgery, session hijacking, and cryptographic compromise.
Never use predictable, non-cryptographic random number generators for security-sensitive values.
// VULNERABLE: Using Math.random() to generate a session token.
function generateSessionToken() {
let token = '';
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
// Math.random() is a standard PRNG, not a cryptographically secure one.
// Its output is predictable if an attacker can observe enough previous values
// or has some knowledge of the initial seed (which can be time-based).
for (let i = 0; i < 32; i++) {
token += chars.charAt(Math.floor(Math.random() * chars.length));
}
return token;
}
// An attacker who obtains a few of these tokens can potentially
// reverse-engineer the PRNG's internal state and predict future tokens.
// SECURE: Using a cryptographically secure pseudo-random number generator (CSPRNG).
const crypto = require('crypto');
function generateSessionToken() {
// `crypto.randomBytes()` generates random data using the operating system's
// underlying entropy sources, making it unpredictable.
// It is designed specifically for cryptographic use cases.
const buffer = crypto.randomBytes(32); // Generate 32 bytes of random data.
return buffer.toString('hex'); // Convert to a hex string for easy use.
}
// The resulting token is 64 characters long and has 256 bits of entropy,
// making it infeasible for an attacker to guess or predict.
Python:
# VULNERABLE: Using random module for security
import random
import string
def generate_reset_token():
chars = string.ascii_letters + string.digits
# random module is predictable - can be reversed with ~624 observations
return ''.join(random.choice(chars) for _ in range(32))
# SECURE: Using secrets module (Python 3.6+)
import secrets
def generate_reset_token():
# secrets module uses os.urandom() - cryptographically secure
return secrets.token_urlsafe(32) # 32 bytes = 256 bits
# Alternative: Using os.urandom directly
import os
import base64
def generate_session_id():
return base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8')
Java:
// VULNERABLE: Using java.util.Random for security
import java.util.Random;
public String generateSessionToken() {
Random random = new Random(); // Predictable PRNG!
byte[] bytes = new byte[32];
random.nextBytes(bytes);
return Base64.getEncoder().encodeToString(bytes);
}
// SECURE: Using SecureRandom
import java.security.SecureRandom;
import java.util.Base64;
public String generateSessionToken() {
SecureRandom secureRandom = new SecureRandom();
byte[] bytes = new byte[32];
secureRandom.nextBytes(bytes);
return Base64.getEncoder().encodeToString(bytes);
}
C#:
// VULNERABLE: Using System.Random for security
using System;
public string GenerateApiKey()
{
var random = new Random(); // Predictable!
var bytes = new byte[32];
random.NextBytes(bytes);
return Convert.ToBase64String(bytes);
}
// SECURE: Using RandomNumberGenerator
using System;
using System.Security.Cryptography;
public string GenerateApiKey()
{
using (var rng = RandomNumberGenerator.Create())
{
var bytes = new byte[32];
rng.GetBytes(bytes);
return Convert.ToBase64String(bytes);
}
}
rg 'Math\.random\(\)' --type js (JavaScript)rg 'import random[^_]|from random import' --type py (Python random module)rg 'new Random\(\)|Random\.next' --type java (Java util.Random)rg '\brand\(|mt_rand\(' --type php (PHP rand/mt_rand)rg 'random\.seed|Random\(time|srand\(time'rg 'session.*token|reset.*token|api.*key' -A 10secrets module or os.urandom().crypto.randomBytes() or crypto.getRandomValues().java.security.SecureRandom.crypto/rand package.System.Security.Cryptography.RandomNumberGenerator.development
Security anti-pattern for Cross-Site Scripting vulnerabilities (CWE-79). Use when generating or reviewing code that renders HTML, handles user input in web pages, uses innerHTML/document.write, or builds dynamic web content. Covers Reflected, Stored, and DOM-based XSS. AI code has 86% XSS failure rate.
development
Security anti-pattern for XPath injection vulnerabilities (CWE-643). Use when generating or reviewing code that queries XML documents, constructs XPath expressions, or handles user input in XML operations. Detects unescaped quotes and special characters in XPath queries.
development
Security anti-pattern for weak password hashing (CWE-327, CWE-759). Use when generating or reviewing code that stores or verifies user passwords. Detects use of MD5, SHA1, SHA256 without salt, or missing password hashing entirely. Recommends bcrypt, Argon2, or scrypt.
development
Security anti-pattern for weak encryption (CWE-326, CWE-327). Use when generating or reviewing code that encrypts data, handles encryption keys, or uses cryptographic modes. Detects DES, ECB mode, static IVs, and custom crypto implementations.