{"record":{"id":"e4195113faf2592e","repo":"crowdsecurity/crowdsec","slug":"pow-unusable-salt","errorCode":null,"errorMessage":"pow: unusable salt","messagePattern":"pow: unusable salt","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pkg/appsec/challenge/pow-worker.js","lineNumber":169,"sourceCode":"self.onmessage = function (e) {\n  var m = e.data || {};\n  var difficulty = m.d | 0;\n\n  // d <= 0 is \"disabled\". d > 64 is the server's Impossible hard-block, which\n  // is rejected before the nonce is ever looked at — searching for it would\n  // just pin every core forever.\n  if (difficulty <= 0 || difficulty > 64) {\n    self.postMessage(\"0\");\n    return;\n  }\n\n  var salt = saltBytes(String(m.p == null ? \"\" : m.p));\n  if (salt === null) {\n    // Deliberately redundant with challenge.js's pre-flight check — this one\n    // covers callers that drive the worker directly, such as the differential\n    // test. There is no slow path to fall back to: a salt this shape means the\n    // server broke its own contract, and any nonce found would be rejected.\n    throw new Error(\"pow: unusable salt\");\n  }\n\n  self.postMessage(solve(salt, difficulty, m.start | 0, (m.stride | 0) || 1));\n};\n","sourceCodeStart":151,"sourceCodeEnd":174,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/pow-worker.js#L151-L174","documentation":"Generic guard in the proof-of-work Web Worker: saltBytes() could not derive a usable salt from the challenge payload (m.p). This is a sentinel-style check, deliberately redundant with challenge.js's pre-flight validation, covering callers that drive the worker directly. It fires when the server-supplied challenge string is empty or in a form the salt hasher cannot consume, so no PoW solution can be computed.","triggerScenarios":"Thrown at pkg/appsec/challenge/pow-worker.js:169 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Verify the appsec remediation component sends a well-formed challenge payload with a non-empty salt ('p' field) to the worker","Check that the challenge string is not truncated or re-encoded between the server response and the worker postMessage","If driving the worker directly in tests, pass the same payload shape the appsec component produces"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}