Goto Fail, Goto Fail — JavaScript Bug Hunt

Modelled on Apple's goto fail bug (CVE-2014-1266, February 2014): a duplicated goto fail; line in the TLS handshake meant the final signature check was…

  • Language: JavaScript
  • Layer: Backend
  • Difficulty: Easy
  • Concepts: Security, Control Flow
  • Modelled on: Apple · CVE-2014-1266
  • Visible tests: a fully valid certificate is accepted; a forged signature is rejected
  • Reward: 50 XP for a complete fix

Briefing

Modelled on Apple's goto fail bug (CVE-2014-1266, February 2014): a duplicated goto fail; line in the TLS handshake meant the final signature check was never executed. Every certificate that got that far was accepted, so anyone on the network could impersonate a secure site.

verify.js runs three checks in sequence and returns whether the certificate is trustworthy — except one of them can never fail the request.

Fix verifyCertificate so all three checks actually gate the result.

Bug report

BUG-GOTOFAIL · Priority: Critical (auth bypass) · Reported by: security audit

verifyCertificate(cert) must return true only when ALL of these hold:

  • cert.chainValid is true
  • cert.notExpired is true
  • cert.signatureValid is true

Observed: a certificate with signatureValid=false is still accepted, as long as the first two checks pass.

Logs

[tls] accepted cert issuer="Totally Legit CA" signatureValid=false
[tls] MITM proxy interception went undetected in staging

The code as shipped

src/tls/verify.js (editable)

// Returns true only if every check passes.
exports.verifyCertificate = function (cert) {
  var ok = true;

  if (!cert.chainValid) {
    ok = false;
    return ok;
  }

  if (!cert.notExpired) {
    ok = false;
    return ok;
  }
    return ok;

  if (!cert.signatureValid) {
    ok = false;
    return ok;
  }

  return ok;
};

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.