Security

Security policy

How to report a vulnerability, what counts as one, and what a one-maintainer project can honestly promise about handling it.

Reporting a vulnerability

Email joel@joelparkerhenderson.com with “security” in the subject, or use GitHub’s private vulnerability reporting on the repository if you prefer a tracked channel. Do not open a public issue for anything exploitable: there is one maintainer and no embargo machinery, so a public report is a public disclosure whether or not it was meant as one.

Never send a real message. An HL7® v2 message is a clinical record, and a real one in a report is a data breach regardless of intent. Redact first — er7-redact message.er7 gives you a redacted message with the same shape, and er7-redact --report message.er7 prints paths and actions with no values at all. A real message sent to this project will be deleted rather than used.

What is in scope

These are libraries and two command-line tools that parse untrusted input and, in one case, remove patient detail from it. That gives three real categories:

CategoryExampleWhy it matters
Denial of service through parsingAn input that makes er7::parse panic, hang, or allocate without boundThe parser is the untrusted-input surface; a counterexample to rule R6 is a security bug, not just a spec bug
Redaction failureer7-redact leaves a value its policy names for removal, or --report prints a valueThis is the crate where being wrong leaks patient data; any instance is treated as a vulnerability
Silent corruptionA message round-trips to something other than what went in, without an errorA clinical record altered silently in transit is a patient-safety problem

Properties you can check, not just trust

  • No unsafe anywhere — every crate root carries #![forbid(unsafe_code)], which the compiler enforces and an allow cannot override.
  • Runtime dependencies: zero, one, and two — er7 has none (enforced by a test), er7-redact has one, serde-er7 has two.
  • No build scripts, and library code performs no I/O at all — no filesystem, no network, no process spawning, no environment reads, no telemetry.
  • Fuzzed on the untrusted-input surface — four targets under er7/fuzz/, smoke-run in CI.

The canonical policy names the commands that verify each property, plus the one disclosed leak path worth knowing before you log an error (er7::Error::MissingHeader carries text taken from the input).

Disclosure, and what is honestly promised

Disclosure is coordinated, with a deadline that favours users: 90 days after your report, you should disclose publicly whether or not a fix exists. That is stated in advance because a one-maintainer project is exactly the kind that might go quiet.

What the project does not have is named rather than omitted: no bug bounty, no second responder, no third-party audit, no certification of any kind. The full list, and the reasoning, is in the canonical policy.

The canonical document is SECURITY.md at the repository root; this page is a summary of it.