{"record":{"id":"cb30f7248329283a","repo":"apache/hadoop","slug":"invalid-signature","errorCode":null,"errorMessage":"Invalid signature","messagePattern":"Invalid signature","errorType":"exception","errorClass":"SignerException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/Signer.java","lineNumber":120,"sourceCode":"\n  protected void checkSignatures(String rawValue, String originalSignature)\n      throws SignerException {\n    byte[] orginalSignatureBytes = StringUtils.getBytesUtf8(originalSignature);\n    boolean isValid = false;\n    byte[][] secrets = secretProvider.getAllSecrets();\n    for (int i = 0; i < secrets.length; i++) {\n      byte[] secret = secrets[i];\n      if (secret != null) {\n        String currentSignature = computeSignature(secret, rawValue);\n        if (MessageDigest.isEqual(orginalSignatureBytes,\n            StringUtils.getBytesUtf8(currentSignature))) {\n          isValid = true;\n          break;\n        }\n      }\n    }\n    if (!isValid) {\n      throw new SignerException(\"Invalid signature\");\n    }\n  }\n}\n","sourceCodeStart":102,"sourceCodeEnd":124,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/util/Signer.java#L102-L124","documentation":"The final signature check in Signer: checkSignatures() recomputes HMAC-SHA256 over the raw value with every known secret (current and previously rolled-over ones, compared constant-time via MessageDigest.isEqual). If none matches the signature carried after '&s=', SignerException('Invalid signature') is thrown — the value was tampered with, or it was signed with a secret this server does not know.","triggerScenarios":"verifyAndExtract() on a cookie whose payload was edited after signing; secret rotation where servers in the cluster disagree (a node still on an old secret or vice versa beyond the rollover window); a cookie minted by a completely different deployment.","commonSituations":"Manual cookie tampering attempts; inconsistent signature.secret across nodes or missing ZooKeeper-based secret sharing (ZKSignerSecretProvider not used in a HA cluster); clock/rollover skew during secret rotation.","solutions":["Treat as unauthenticated: clear the hadoop.auth cookie and redirect to re-authentication","If it happens fleet-wide after rotation, align secrets on all nodes (or adopt ZKSignerSecretProvider for automatic sharing)","Verify the secret material (signature.secret.file content) matches across servers byte-for-byte"],"exampleFix":"// before\nString raw = signer.verifyAndExtract(signed);\n\n// after: fail closed and force re-login on any SignerException\ntry {\n  String raw = signer.verifyAndExtract(signed);\n} catch (SignerException e) {\n  resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);\n  resp.addHeader(\"Set-Cookie\", \"hadoop.auth=; Max-Age=0; Path=/; HttpOnly\");\n  return;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { String raw = signer.verifyAndExtract(signed); } catch (SignerException e) { /* tampering or secret mismatch: 401, expire hadoop.auth cookie, re-authenticate */ }","preventionTips":["Share secrets cluster-wide (ZKSignerSecretProvider) so every node verifies with the same material","Compare secret file checksums across nodes when validation fails fleet-wide","Never catch-and-continue on signature failure — always fail closed"],"tags":["hadoop-auth","signing","hmac","cookie","tampering"],"backgroundTag":"signature-verification-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}