[{"data":1,"prerenderedAt":164},["ShallowReactive",2],{"blog-vulnerabilities/timing-attacks":3},{"id":4,"title":5,"body":6,"category":144,"date":145,"dateModified":145,"description":146,"draft":147,"extension":148,"faq":149,"featured":147,"headerVariant":150,"image":149,"keywords":149,"meta":151,"navigation":152,"ogDescription":153,"ogTitle":149,"path":154,"readTime":155,"schemaOrg":156,"schemaType":157,"seo":158,"sitemap":159,"stem":160,"tags":161,"twitterCard":162,"__hash__":163},"blog/blog/vulnerabilities/timing-attacks.md","Timing Attacks Explained",{"type":7,"value":8,"toc":133},"minimark",[9,16,21,36,41,60,64,73,77,86,102,121],[10,11,12],"tldr",{},[13,14,15],"p",{},"Timing attacks extract secret information by measuring how long operations take. String comparison using === returns as soon as it finds a difference, leaking how many characters were correct. Use constant-time comparison functions like crypto.timingSafeEqual for comparing secrets, tokens, and passwords.",[17,18,20],"h2",{"id":19},"how-timing-attacks-work","How Timing Attacks Work",[22,23,25],"code-block",{"label":24},"Vulnerable: early-exit comparison",[26,27,32],"pre",{"className":28,"code":30,"language":31},[29],"language-text","// JavaScript === returns immediately on first difference\nfunction checkApiKey(provided, actual) {\n  return provided === actual;  // VULNERABLE!\n}\n\n// If actual = \"secret123\"\n// \"axxxxxxxx\" - fails immediately (fast)\n// \"sxxxxxxxx\" - first char matches, then fails (slightly slower)\n// \"sexxxxxxx\" - two chars match (even slower)\n\n// By measuring response times, attacker can guess one char at a time\n","text",[33,34,30],"code",{"__ignoreMap":35},"",[37,38,40],"h3",{"id":39},"what-can-be-leaked","What Can Be Leaked",[42,43,44,48,51,54,57],"ul",{},[45,46,47],"li",{},"API keys and tokens",[45,49,50],{},"Password hashes (comparing to stored hash)",[45,52,53],{},"HMAC signatures",[45,55,56],{},"Session tokens",[45,58,59],{},"Any secret comparison",[17,61,63],{"id":62},"the-fix-constant-time-comparison","The Fix: Constant-Time Comparison",[22,65,67],{"label":66},"Safe: using crypto.timingSafeEqual",[26,68,71],{"className":69,"code":70,"language":31},[29],"import crypto from 'crypto';\n\nfunction safeCompare(a, b) {\n  // Must be same length for timingSafeEqual\n  if (a.length !== b.length) {\n    return false;\n  }\n\n  return crypto.timingSafeEqual(\n    Buffer.from(a),\n    Buffer.from(b)\n  );\n}\n\n// This always takes the same time regardless of where they differ\n",[33,72,70],{"__ignoreMap":35},[37,74,76],{"id":75},"length-safe-version","Length-Safe Version",[22,78,80],{"label":79},"Hiding length differences",[26,81,84],{"className":82,"code":83,"language":31},[29],"function constantTimeCompare(provided, actual) {\n  // Use HMAC to normalize length\n  const hash = (s) => crypto\n    .createHmac('sha256', 'constant-key')\n    .update(s)\n    .digest();\n\n  return crypto.timingSafeEqual(\n    hash(provided),\n    hash(actual)\n  );\n}\n",[33,85,83],{"__ignoreMap":35},[87,88,89,96],"faq-section",{},[90,91,93],"faq-item",{"question":92},"Is this attack practical over the network?",[13,94,95],{},"Over a local network or with many samples, yes. Statistical analysis can extract timing differences of microseconds. Cloud environments and CDNs add noise but do not eliminate the risk.",[90,97,99],{"question":98},"Does bcrypt prevent this for passwords?",[13,100,101],{},"Bcrypt should be used for password storage, but you still need constant-time comparison of the resulting hash. Use bcrypt.compare() which handles this internally.",[103,104,105,111,116],"related-articles",{},[106,107],"related-card",{"description":108,"href":109,"title":110},"Another timing issue","/blog/vulnerabilities/race-conditions","Race Conditions",[106,112],{"description":113,"href":114,"title":115},"Auth security","/blog/vulnerabilities/broken-auth","Broken Authentication",[106,117],{"description":118,"href":119,"title":120},"Key management","/blog/how-to/secure-api-keys","Secure API Keys",[122,123,126,130],"cta-box",{"href":124,"label":125},"/","Start Free Scan",[17,127,129],{"id":128},"find-timing-vulnerabilities","Find Timing Vulnerabilities",[13,131,132],{},"Our scanner identifies timing-unsafe comparisons in your code.",{"title":35,"searchDepth":134,"depth":134,"links":135},2,[136,140,143],{"id":19,"depth":134,"text":20,"children":137},[138],{"id":39,"depth":139,"text":40},3,{"id":62,"depth":134,"text":63,"children":141},[142],{"id":75,"depth":139,"text":76},{"id":128,"depth":134,"text":129},"vulnerabilities","2026-01-23","Timing attacks measure how long operations take to extract secrets. Learn about timing-safe comparisons and how to protect sensitive operations.",false,"md",null,"red",{"noindex":152},true,"Learn how timing attacks work and how to prevent them.","/blog/vulnerabilities/timing-attacks","5 min read","[object Object]","TechArticle",{"title":5,"description":146},{"loc":154},"blog/vulnerabilities/timing-attacks",[],"summary_large_image","KGf-f9fpljzeQYDWyfrJSDxzted73EwfMgKDf5yVY90",1775843926398]