Skip to content

Security: ValisSowilo/Gleipnir

SECURITY.md

Security policy

Reporting a vulnerability

Please report privately through GitHub's Security → Report a vulnerability form on this repository, which opens a private advisory visible only to the maintainer. Do not open a public issue for a memory-safety or archive-parsing bug.

Include the gleipnir --version output, the platform and compiler, and — most usefully — the archive or input that triggers it. A file under a megabyte that reproduces the fault is worth more than a description of it.

Expect an acknowledgement within a week. There is no bounty; this is a single-maintainer project.

What is in scope

The decompressor treats every archive as untrusted input, so anything that breaks that assumption is in scope:

  • Memory unsafety while parsing a header, index, trailer, segment or recovery block — out-of-bounds read or write, overflow in a length or offset, wild pointer, use-after-free.
  • A crafted archive causing a crash, a hang, or unbounded allocation.
  • Path traversal on extract. Member names that are absolute, carry a drive letter, contain a .. component, or hold control characters are refused, and extraction must not write outside the destination directory.
  • Silent wrong output — any input for which gleipnir exits 0 and produces bytes that are not what was compressed. Every field the reader parses is bounds-checked, and a damaged archive is required to produce a diagnostic and exit 2, never a crash, a hang, or plausible-looking wrong bytes.

scripts/gfuzz.py exercises the storage-decay half of this threat model — bit flips, decayed sectors, truncation, splices, zero holes, trailing junk and pure noise — and asserts that every outcome is either byte-exact output or a non-zero exit.

scripts/sfuzz.py exercises the deliberate half, which random damage does not reach: archives whose magic, version, header hash and index hash are all correct, so they pass every structural check, but whose segment fields contradict each other. That is where a crafted archive attacks, and it is where the bugs fixed in the September 2026 audit lived — undetected by the three suites that existed at the time, all of which passed clean both before and after.

scripts/wfuzz.py covers the word transform, whose segments none of the other suites' inputs are large enough to produce: text carrying the flag and escape bytes the transform must escape, bytes above 0x7F, every case form, and words either side of its 32-letter limit, all round-tripped byte for byte. The transform's decoder indexes a dictionary read out of the archive, so its malformed-segment cases live in sfuzz.py with the rest.

A case that defeats any of them is a good report.

What is out of scope

These are documented properties, not defects:

  • There is no encryption, and none is planned. gleipnir provides integrity, not confidentiality. Encrypt the archive afterwards if the data needs it, and note that doing so removes the ability to scrub or repair it, since neither the checksums nor the parity blocks are readable through ciphertext.
  • Compression is not constant-time and its timing and output size depend on the input. Do not compress attacker-controlled data together with secrets and expect the size not to leak — the CRIME/BREACH class of attack applies here as it does to every general-purpose compressor.
  • Memory use is large and preset-dependent, and scales with -t because each worker owns a complete model. In 1.2 a -9 worker budgets about 1.5 GB (1.1: 1.1 GB), so -9 -t8 needs about 12 GB; gleipnir caps -t to installed RAM. An out-of-memory condition from settings chosen by the operator is a capacity question, covered in USAGE.md.
  • The whole input is buffered in RAM. A large input needs roughly its own size plus tables plus an output buffer, which is a documented limit rather than a resource-exhaustion bug.
  • Anything requiring the attacker to already have write access to the machine running gleipnir, or to the archive being read, without a crafted-input step.

Supported versions

The latest release is supported. Fixes land on main and go out in the next release; there is no backport branch.

There aren't any published security advisories