@sun-asterisk/sunlint
Version:
☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards
57 lines • 1.99 kB
JSON
{
"ruleId": "S052",
"name": "OTP must have ≥20-bit entropy (≥6 digits) and use CSPRNG",
"description": "Prevent guessable OTP by enforcing CSPRNG and minimal entropy. Ban non-crypto RNG and too-short codes.",
"category": "security",
"severity": "error",
"options": {
"otpIdentifiers": [
"otp","oneTime","one_time","passcode","verificationCode","verifyCode",
"confirmCode","pin","totp","hotp","resetCode","activationCode"
],
"bannedRngApis": {
"typescript": ["Math\\.random\\s*\\("],
"javascript": ["Math\\.random\\s*\\("],
"node": ["crypto\\.pseudoRandomBytes\\s*\\("],
"java": ["new\\s+Random\\s*\\(","ThreadLocalRandom\\.current\\s*\\("],
"kotlin": ["kotlin\\.random\\.Random(\\.Default)?"],
"dart": ["new\\s+Random\\s*\\(","Random\\s*\\("]
},
"allowedRngApis": {
"node": ["crypto\\.randomInt\\s*\\(","crypto\\.randomBytes\\s*\\("],
"java": ["new\\s+SecureRandom\\s*\\("],
"kotlin": ["java\\.security\\.SecureRandom"],
"dart": ["Random\\.secure\\s*\\("]
},
"lengthChecks": {
"numericMinDigits": 6,
"alphanumericMinLength": 6,
"regexBadNumeric4": "\\\\b\\\\d{4}\\\\b"
},
"totpHotpHints": {
"requireStandardLib": true,
"minSecretBits": 128,
"maxTimeStepSeconds": 30,
"maxWindow": 1
},
"policy": {
"requireCsprng": true,
"forbidNonCryptoRng": true,
"forbidFourDigitOtp": true,
"requireNoLoggingOfOtp": true,
"requireSingleUseAndTtl": true
},
"detectionHeuristics": {
"variableNameMatchBoost": true,
"builderFunctions": ["generateOtp","issueOtp","createCode","sendOtp","totp","hotp"]
},
"allowlist": {
"paths": ["test/","tests/","__tests__/","fixtures/","mocks/"],
"notes": "Trong test vẫn cấm 4-digit OTP nếu test chạy e2e với hệ thật."
},
"thresholds": {
"maxBannedRngUsages": 0,
"maxShortOtpPatterns": 0
}
}
}