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:
| Category | Example | Why it matters |
|---|---|---|
| Denial of service through parsing | An input that makes er7::parse panic, hang, or allocate without bound | The parser is the untrusted-input surface; a counterexample to rule R6 is a security bug, not just a spec bug |
| Redaction failure | er7-redact leaves a value its policy names for removal, or --report prints a value | This is the crate where being wrong leaks patient data; any instance is treated as a vulnerability |
| Silent corruption | A message round-trips to something other than what went in, without an error | A clinical record altered silently in transit is a patient-safety problem |
Properties you can check, not just trust
- No
unsafeanywhere — every crate root carries#![forbid(unsafe_code)], which the compiler enforces and anallowcannot override. - Runtime dependencies: zero, one, and two —
er7has none (enforced by a test),er7-redacthas one,serde-er7has 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.