skills/timing-attacks-anti-pattern/SKILL.md
Security anti-pattern for timing side-channel vulnerabilities (CWE-208). Use when generating or reviewing code that compares secrets, tokens, passwords, or cryptographic values. Detects early-exit comparisons that leak information through timing differences.
npx skillsauth add igbuend/grimbard timing-attacks-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: Medium
Attackers measure operation timing to extract secrets. Early-exit comparisons leak information: comparing ABCDEF to ABCDEG takes longer than ABCDEF to XBCDEF (more matching characters before mismatch). These timing differences enable character-by-character secret recovery.
The anti-pattern is comparison functions returning early upon finding differences in sensitive values (passwords, tokens, hashes).
# VULNERABLE: String comparison leaking timing information.
def insecure_compare(s1, s2):
# Exits on first mismatch (early exit).
# First character mismatch returns quickly.
# Last character mismatch takes longer.
if len(s1) != len(s2):
return False
for i in range(len(s1)):
if s1[i] != s2[i]:
return False # Early exit leaks timing.
return True
SECRET_TOKEN = "abcdef123456"
@app.route("/check_token")
def check_token():
provided_token = request.args.get("token")
if insecure_compare(provided_token, SECRET_TOKEN):
return "Token valid!"
return "Token invalid!"
# Attack: Measure response times to discover secret character-by-character.
# token=X -> fast (first char wrong)
# token=a -> slower (first char matches)
# token=ab -> even slower (two chars match)
# SECURE: Constant-time comparison prevents timing leaks.
import hmac
import secrets
def secure_compare(s1_bytes, s2_bytes):
# `hmac.compare_digest` performs constant-time comparison.
# Execution time depends only on length, not values.
# Always compares all bytes.
return hmac.compare_digest(s1_bytes, s2_bytes)
SECRET_TOKEN = secrets.token_bytes(16) # Secure 128-bit token.
@app.route("/check_token_secure")
def check_token_secure():
provided_token_hex = request.args.get("token")
try:
provided_token_bytes = bytes.fromhex(provided_token_hex)
except ValueError:
return "Token invalid!", 400
# Length check handled safely by compare_digest.
if len(provided_token_bytes) != len(SECRET_TOKEN):
return "Token invalid!", 400
if secure_compare(provided_token_bytes, SECRET_TOKEN):
return "Token valid!"
return "Token invalid!"
== or === being used for comparing secrets. These operators are typically not constant-time.False on the first mismatch, it's vulnerable.hmac.compare_digest() or secrets.compare_digest()crypto.timingSafeEqual()subtle.ConstantTimeCompare()MessageDigest.isEqual() (byte arrays)hash_equals()bcrypt.checkpw(), argon2.verify()).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.