name: sc-auth description: Authentication flaw detection — weak passwords, broken auth, credential stuffing, and bypass vectors license: MIT metadata: author: ersinkoc category: security version: "1.0.0"
SC: Authentication Flaws
Purpose
Detects authentication vulnerabilities including weak password policies, missing brute force protection, insecure password storage, authentication bypass, hardcoded credentials, insecure password reset flows, and missing multi-factor authentication. Covers session-based, JWT, OAuth, and API key authentication models.
Activation
Called by sc-orchestrator during Phase 2. Runs against all web applications and APIs.
Phase 1: Discovery
File Patterns to Search
**/*auth*, **/*login*, **/*signin*, **/*signup*, **/*register*,
**/*password*, **/*credential*, **/*token*, **/*session*,
**/*oauth*, **/*mfa*, **/*2fa*, **/middleware/*, **/guards/*
Keyword Patterns to Search
# Password hashing
"md5(", "sha1(", "sha256(", "hashlib.md5", "hashlib.sha1",
"MessageDigest.getInstance(\"MD5\"", "MessageDigest.getInstance(\"SHA-1\"",
"bcrypt", "argon2", "scrypt", "pbkdf2", "password_hash(",
"crypto.createHash("
# Authentication logic
"password ==", "password ===", "password.equals(",
"authenticate(", "login(", "verify_password(", "check_password(",
"compareSync(", "compare("
# Hardcoded credentials
"password = \"", "password = '", "passwd", "secret",
"api_key = \"", "token = \"", "admin:admin", "root:root"
# Brute force protection
"rate_limit", "throttle", "max_attempts", "lockout",
"login_attempts", "failed_attempts"
Vulnerability Categories
1. Weak Password Hashing:
# VULNERABLE: MD5/SHA for password storage
password_hash = hashlib.md5(password.encode()).hexdigest()
# SAFE: bcrypt with appropriate cost factor
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
2. Missing Brute Force Protection:
// VULNERABLE: No rate limiting on login
app.post('/login', async (req, res) => {
const user = await User.findOne({ email: req.body.email });
if (user && await bcrypt.compare(req.body.password, user.password)) {
return res.json({ token: generateToken(user) });
}
return res.status(401).json({ error: 'Invalid credentials' });
});
// SAFE: With rate limiting
const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 5 });
app.post('/login', loginLimiter, async (req, res) => { /* ... */ });
3. Timing-Safe Comparison:
// VULNERABLE: Non-constant-time comparison
if token == expectedToken { /* ... */ }
// SAFE: Constant-time comparison
if subtle.ConstantTimeCompare([]byte(token), []byte(expectedToken)) == 1 { /* ... */ }
4. Account Enumeration:
# VULNERABLE: Different responses reveal account existence
if not user_exists(email):
return error("User not found")
if not check_password(password):
return error("Wrong password")
# SAFE: Generic error message
if not user_exists(email) or not check_password(email, password):
return error("Invalid email or password")
Phase 2: Verification
Sanitization Check
- Are passwords hashed with bcrypt/argon2/scrypt (adaptive cost)?
- Is brute force protection implemented on login endpoints?
- Are password reset tokens time-limited and single-use?
- Is timing-safe comparison used for secrets/tokens?
Severity Classification
- Critical: Hardcoded admin credentials, authentication bypass, plaintext password storage
- High: MD5/SHA1 password hashing, missing brute force protection on public login
- Medium: Account enumeration, weak password policy, missing MFA on sensitive operations
- Low: Non-constant-time token comparison, verbose authentication error messages
Output Format
Finding: AUTH-{NNN}
- Title: {Authentication vulnerability type}
- Severity: Critical | High | Medium | Low
- Confidence: 0-100
- File: file/path:line
- Vulnerability Type: CWE-287 (Improper Authentication) | CWE-798 (Hardcoded Credentials) | CWE-916 (Weak Password Hash)
- Description: {What was found}
- Impact: {Account takeover, credential theft, unauthorized access}
- Remediation: {Specific fix}
- References: https://cwe.mitre.org/data/definitions/287.html
Common False Positives
- Test/fixture credentials — hardcoded passwords in test files for test accounts
- Password hashing in migration — hashing algorithm in migration code for legacy compatibility
- Hash functions for non-security purposes — MD5/SHA used for checksums, cache keys, not passwords
- Environment variable reads —
os.getenv("SECRET")reads at runtime, not hardcoded - OAuth provider configuration — OAuth client IDs (public) vs client secrets (should be env var)