This project parses untrusted binary input and writes files derived from it, so it treats both as security surfaces even though it is not a networked service.
Use GitHub's private vulnerability reporting on this repository (Security, then Report a vulnerability). That channel keeps the report private until a fix exists. If private reporting is not enabled when you look, open an issue that says only that you have a security report and asks for a private channel, and wait for a reply before sharing details.
There is no dedicated security email address for this project, and none should be inferred.
Please do not include in a report:
- credentials, tokens, or keys of any kind,
- real market-data files or excerpts of them, including order references, quantities, executions, or raw message bytes, or
- anything you cannot share publicly once the issue is resolved.
A minimal synthetic reproduction is always preferred, and itch_synth can
generate one. If a real file is genuinely required to reproduce, say so and
describe it rather than attaching it.
The main branch is the only supported version. There are no releases and no
backports.
Input handling:
- Every frame read is bounds checked before it happens, and a truncated or malformed frame stops the walk with its offset recorded rather than reading past the mapping.
- Field reads are
memcpyloads of an exact width, never casted pointers into mapped memory. - A message whose declared length is not the specification's length is never decoded.
- The parser allocates nothing per message and retains nothing.
Output handling, which an adversarial review of the analysis layer tightened
(docs/decisions.md D-075):
- Text that comes from the feed is validated before it becomes a filename, so a ticker cannot place an output file outside the requested directory.
- The same text is validated before it becomes a CSV field, so it cannot break the row it sits in.
- Bytes outside printable ASCII are escaped before they become part of a JSON string, so an unknown message type cannot produce an unparseable manifest.
- Output directories are staged and renamed into place only after every check
passes, so a failed run never leaves a partial result where a complete one
belongs. Be aware of exactly which paths the command uses: for
--out=DIRit also creates and may deleteDIR.staging, and with--forceit moves the existingDIRtoDIR.previous, removing anything already at that path first, and deletes it once the new directory is in place. Those two sibling paths are the only ones outsideDIRthat the command touches, and it never deletesDIRitself without--force. - Nothing follows a symbolic link deliberately. The staging directory is created by the tool after removing whatever was at that path, and every output file is created inside it; removing a path that is a symbolic link removes the link, not its target.
- Symbolic links are not followed deliberately anywhere; outputs are created
with
fopenin a directory the tool created itself.
Data policy, which is a privacy surface rather than a security one:
- No market data is committed, and
.gitignoreblocks the file patterns. - Committed analysis outputs carry aggregates and level summaries only, never order-level values, and tests scan them for violations.
- No output contains an absolute path.