Skip to content

Security: ORDNET/ODNCA-verify

Security

SECURITY.md

Security Policy

Reporting a vulnerability

Please report security issues privately first. Do not open a public issue for anything that could let a forged certificate be accepted as valid.

Preferred channel: GitHub private vulnerability reporting — the "Report a vulnerability" button on the Security tab of this repository. This creates a private advisory only the maintainers can see.

Please include what the issue is, which file and line, how to reproduce it, and what an attacker gains.

What to expect

  • Acknowledgement: within 3 working days.
  • Assessment: within 10 working days, with a severity.
  • Fix: anything that would cause the verifier to accept an invalid certificate, or the certificate page to execute attacker-controlled script, is prioritised over everything else.
  • Credit: we will name you in the release notes unless you prefer otherwise.

We do not currently operate a bug bounty.

Threat model

This repository is the trust-removal layer: an offline verifier and a proof/certificate server whose entire purpose is to let anyone check ORDnet's claims without trusting ORDnet. The assumptions that matter:

  1. The certificate is attacker-controlled. A certificate is just a JSON file. Whoever writes it chooses every field in it, including its root. The verifier therefore never treats any value inside the certificate as authoritative about itself: the root to fold against is supplied separately (--root), pinned from the on-chain commit inscription or the /commits endpoint. See verify-cert.js and the K4 fix below.

  2. Registered names are attacker-controlled strings. SNS-NAME-1 permits almost any character in a name (1–2048 bytes, no whitespace or control characters, unicode allowed). A name is therefore never emitted into HTML, an attribute, or a <script> block without escaping appropriate to that context. See the H2 fix below.

  3. The exit code is a security signal. Any wrapper that does verify-cert.js … && accept relies on a non-zero exit for every failure. The exit code covers every check that ran, not just the merkle path.

Verifying a certificate correctly

ROOT=$(curl -s https://odnca.org/commits | jq -r '.commits[-1].root')
node verify-cert.js cert.json --root "$ROOT" --key <(curl -s https://odnca.org/commit-key)

The --root must come from the chain (or the chain-backed /commits endpoint), never from the certificate you are checking.

There aren't any published security advisories