github altcha-org/altcha v3.3.0

3 hours ago

This release fixes the widget's proof-of-work code to match the fixed altcha-lib (v2.6.0). It fixes a key-derivation mismatch that caused valid solutions to be rejected, and a verification bypass in altcha/lib. Upgrading is recommended.

Security

  • verifySolution bypass (altcha/lib). If the challenge had no keySignature, or the verifier passed no hmacKeySignatureSecret, verifySolution re-derived the key from the submitted counter but never checked it against the signed keyPrefix. Any counter, for example 0, together with its derived key verified without doing any work. The derived key must now also match keyPrefix. altcha-lib fixed this in e2a6daf (v2.3.2), but the fix never reached the widget's copy of this code until now.
  • Obfuscation plugin key exposure. obfuscate() used the published keyPrefix as its AES key. If keyPrefixLength was overridden, part or all of that key could be published. It now encrypts with the full derived key and publishes only half of it. With default options the output format is the same, so existing obfuscated strings still decode.

Fixes

  • SHA key derivation. Each round now hashes the full digest from the previous round, and the result is cut to keyLength once at the end. This is what altcha-lib and all server ports do. Before, the widget's solutions were rejected (invalidSolution) for SHA-384 or SHA-512 with cost > 1, and for any SHA-* challenge with keyLength below the digest size and cost > 1. The default (SHA-256, keyLength 32) was not affected.
  • PBKDF2 key length. PBKDF2/* now supports any keyLength. Before, only 16, 24 and 32 worked.
  • Algorithm names. The built-in deriveKey functions reject names they don't support. Before, unknown PBKDF2/* names fell back to SHA-256, and SCRYPT and ARGON2ID ignored the name. Each function now accepts only its own exact names:
    • SHA-256, SHA-384, SHA-512
    • PBKDF2/SHA-256, PBKDF2/SHA-384, PBKDF2/SHA-512
    • SCRYPT
    • ARGON2ID
  • Input validation (altcha/lib):
    • createChallenge checks cost, keyLength, memoryCost, parallelism, counter, counterMode, expiresAt, hmacAlgorithm and the secrets.
    • createChallenge also checks the key prefix. keyPrefix must be a non-empty hex string, and it is lowercased before signing. keyPrefixLength must be a positive integer smaller than the derived key.
    • verifySolution returns invalidSolution for a malformed derivedKey (it must be lowercase hex) or counter (it must be an integer the counter mode can encode), instead of throwing or coercing the value.
    • solveChallenge throws immediately on an invalid keyPrefix instead of running until the timeout.
    • hexToBuffer rejects non-hex characters.
    • Canonical JSON keeps a __proto__ key, so an injected key now breaks the signature.
    • verifyServerSignature:
      • checks payload.algorithm against SHA-1, SHA-256, SHA-384 and SHA-512;
      • requires hmacSecret;
      • returns invalidSignature when the signature is missing;
      • checks expiry against the current time without rounding it down to whole seconds, so the up to 1 second of grace is gone.

Upgrade notes

Challenges that are already in flight with these settings will not verify across the upgrade.

  • Calls that used to work and now throw:
    • verifySolution without hmacSignatureSecret, or with an empty one.
    • createChallenge with hmacSignatureSecret: '' or null.
    • createChallenge with hmacKeySignatureSecret but no hmacSignatureSecret.
    • createChallenge with an empty or non-hex keyPrefix.
    • createChallenge with a keyPrefixLength that is not smaller than the derived key.
    • Any built-in deriveKey with an unsupported algorithm name.

Don't miss a new altcha release

NewReleases is sending notifications on new releases.