Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,45 @@ change in flight, so it is derived here rather than counted:
gh api repos/Flowfin/core/branches --jq length

WHAT IS ABSENT IS BEHAVIOUR RATHER THAN CODE, and that distinction is the one a
reporter needs. The crate compiles, a suite runs against it, and what the types
in it hold today is a name, a statement about which thread a caller may use it
from, and the measurement facility. There is no request, no cache, no decode and
no sign-in. `README.md` says the same thing in its own words, and the section
below on what is not a vulnerability here says what follows from it.
reporter needs. The crate compiles and a suite runs against it. There is no
request, no decode and no sign-in: no module here opens a socket or sends a byte,
nothing turns admitted bytes into pixels, and no credential is presented to a
server.

What does execute is parsing, over bytes nobody here wrote. The targets are not
listed in this file, because the suite derives its own list from the corpus and a
second list here would be a second thing to keep in step:

git ls-tree --name-only origin/main tests/fixtures/corpus/

One directory per target, and `tests/replay_the_seed_corpus.rs` replays every
seed in every one of them inside `cargo test --locked`. That file refuses in both
directions - a directory with no entry point behind it, and an entry point with
no directory - so the reading above is the set rather than a subset somebody
maintained. A header read for the dimensions it declares is among them, which is
the surface 0003 names as the most attacked one this repository will carry.

The cache executes too. `EnvelopeCache` reads and writes through the store a
client supplies, checking a format version, a payload kind, a length and a digest
before any part of a payload is looked at, and removing an entry that fails any
of them.

THIS PARAGRAPH ENUMERATED WHAT THE TYPES HOLD AND SAID THERE WAS NO CACHE. It
said they held a name, a statement about which thread a caller may use them from,
and the measurement facility, which was a fair reading of the ten module roots
`src/` held on 2026-08-26, the day it landed; the first parser landed four hours
after it. What stands under `src/` now is one of the two counts the section above
already hands the reader, and no number for it is written here. It also called
`README.md` a file saying the same thing, and that file corrected its own version
of this claim on 2026-08-29, as `src/lib.rs` corrected a third on 2026-09-18,
each in a change with no reason to open this one. All three ran in the direction
that makes the tree look emptier than it is, in the document that decides where a
reporter looks - which is what #200 closed this section for, and what it was
doing again one enumeration later. No list replaces it: a list here is wrong on
the next landing and nothing in this tree reads one. It was found by reading the
sentence against the corpus the suite replays.

The section below on what is not a vulnerability here says what follows from it.

## Why a defect here is wider than one repository

Expand Down
8 changes: 4 additions & 4 deletions security/statements.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"version": 1,
"updated": "2026-09-02",
"updated": "2026-09-18",
"about": [
"Every scanner pointed at this repository will eventually report something that is not exploitable here, or not reachable from any path this core takes. The choices are to fix it, to suppress it silently, or to say publicly why it does not apply. This document is the third, and it is the only one a downstream consumer can act on.",
"It carries two kinds of entry, because there are two ways a finding stops reaching the gate and they do not have the same shape. A `findings` entry is a finding a scanner raised against this repository and somebody dismissed; it has an identifier, so it carries a per-finding disposition. An `exclusions` entry is a class taken out of what a scanner is pointed at; it has no identifier and no list of what would have been found, so it carries a scope, and it carries what is consequently NOT being looked for. That last field is the one a consumer needs and the one an author will otherwise leave out.",
Expand Down Expand Up @@ -41,9 +41,9 @@
"scanner": "Scorecard",
"subject": "whether a fuzzing harness for this repository is registered with OSS-Fuzz or an equivalent",
"status": "not_applicable",
"justification": "There is no untrusted input surface in this tree today that a fuzzer would reach, and onboarding to OSS-Fuzz needs somebody who can be paged.",
"impact": "THIS DISPOSITION IS TRUE OF THE TREE AS IT STANDS AND NOT OF THE TREE THIS BOARD HAS PLANNED. 0101 puts a server's answers and an artwork byte stream on the untrusted list, 0055 calls the decoder the most attacked surface this repository will carry, and issue #86 is open to fuzz every parser reachable from that list and replay the seed corpus inside the gating build. A consumer reading a permanent dismissal here would take the absence of a fuzzer for a decision rather than for a state, and it is a state.",
"retires_when": "A parser reachable from 0101's untrusted list lands in this tree, which is what #86 is open for. The dismissal does not expire on its own and nothing raises the finding again when that happens, which is why the condition is written here rather than left in the dismissal."
"justification": "Onboarding to OSS-Fuzz needs somebody who can be paged, and there is one account here. That is the whole of what this dismissal rests on now. THIS FIELD ALSO SAID THERE WAS NO UNTRUSTED INPUT SURFACE IN THIS TREE THAT A FUZZER WOULD REACH, AND THE TREE HELD FIVE PARSE TARGETS WITH A REPLAYED SEED CORPUS BEFORE THE SENTENCE WAS PUBLISHED. The corpus directories are one per target and `tests/replay_the_seed_corpus.rs` derives its target list from them, so which surfaces they are is read with `git ls-tree --name-only origin/main tests/fixtures/corpus/` rather than listed here. Three landed on 2026-08-31 and the fourth and fifth on 2026-09-02, the last of them eleven hours before this document did. A consumer who read the deleted half took the absence of a fuzzer for the absence of anything to fuzz, which is the opposite of what the tree said on the day. It was found by reading this entry against the corpus the suite replays, and issue #445 is where it is recorded.",
"impact": "0101 puts a server's answers and an artwork byte stream on the untrusted list and 0055 calls the image decoder the most attacked surface this repository will carry, so the surfaces a fuzzer would be pointed at are here and are exercised on every pull request - but by replay rather than by search. What is NOT looked for is a NEW hostile input: no coverage-guided run happens anywhere on this board, so a defect no seed already reaches is found by nobody. THIS FIELD DESCRIBED THE REPLAY AS WORK #86 WAS OPEN FOR, AND THE REPLAY RUNS INSIDE `cargo test --locked`, which the `test` check carries. #86 is open for the coverage-guided half, which is the half this paragraph is a disclosure about.",
"retires_when": "THE CONDITION THIS FIELD NAMED IS MET AND THE DISMISSAL IS STILL HERE, WHICH IS TWO STATES RATHER THAN ONE. It said a parser reachable from 0101's untrusted list landing in this tree retires the dismissal; five of them had landed before this document was written. What is left is the half of the ground that holds, which is that nobody here can be paged, and lifting the dismissal is an act on the code-scanning surface rather than a change to this tree, so no branch here performs it. It does not expire on its own and nothing raises the finding again."
}
],
"exclusions": [
Expand Down
Loading