Method
How yof checks your app, and how sure it is
Every yof report says what was checked, what was not, and how sure yof is of each finding. This page explains the rules behind those words, including what yof keeps and what it never does.
What yof checks
Depending on what you ask for, yof looks at your app in up to four ways. The scope section of each report says which ones ran and how far.
From the outside
Your live addresses, the way anyone on the internet sees them: files and keys a site serves, database tables that answer without a sign-in, headers, sign-in limits and redirects.
Inside the code
Your repository, read from where you host it: leaked keys, risky code patterns and risky settings. yof reads the code and does not run it.
Attack tests, with your consent
yof acts like a careful attacker against your running app: signing in, one user reaching another user's records, members reaching admin routes, AI assistant probes, and redirects and sign-in limits. Only under the promises listed below.
Packages
The packages your app installs, matched by name and version against public advisories, including packages known to be exploited or malicious.
Never covered by automated checks
No automated check covers these, so a yof report never claims to. A part that was not checked is never assumed to be fine.
- Flaws in business logic, such as a price or a step a person can skip.
- Weaknesses nobody knows about yet (zero-days).
- People and processes: phishing, passwords shared by hand, who has access.
- Anything outside the scope named in this report, and any change after its date.
Three verdicts, and hardening notes apart
Every finding carries exactly one verdict. Only confirmed findings and findings that need validation are counted.
- Confirmed. yof saw the impact happen, or holds the exact evidence (for example the key that was served, or the installed version an advisory names).
- Needs validation. Likely, but not demonstrated: yof saw the pattern and could not prove the impact. A person or a deeper test needs to confirm it.
- Rejected. Disproved by a second, separate check. Kept for the record, not counted.
The verdict comes from fixed rules, not from a model's opinion. Seen on the live app, or exact evidence in the repository such as a committed key or an installed version an advisory names, means confirmed. A code pattern that yof did not run means needs validation.
Hardening notes
Good practice that would add a layer of protection. yof demonstrated no risk, so these are not findings and are in no count. For example a missing security header, a GitHub Action that is not pinned, or a container image on latest. Each one comes with its fix, in its own section of the report.
How bad each finding is
Severity runs from critical to info. It is anchored to what yof demonstrated, not to how bad a problem could be in theory.
| Severity | What must have been shown |
|---|---|
| Critical | Only for a confirmed finding that yof saw happen: data or control that belongs to someone else (another person's records, a whole table, a key with full power served to everyone), or a package known to be exploited or malicious. |
| High | Serious harm is likely if someone uses it: a confirmed exposure with limits, or a likely problem yof could not demonstrate. A finding that is not confirmed can reach high at most. |
| Medium | Makes an attack easier or its damage larger, under conditions such as a sign-in, a user's click or a specific setting. |
| Low | Small harm on its own, or reachable only in development and test tools. |
| Info | Worth knowing, no harm on its own. |
The limits, named in the reason line of each finding
- Not confirmed: high at most.
- Confirmed from the repository only, not seen on the live app: high at most, unless the package is known to be exploited or is malicious.
- Only in development and test tools: low at most.
- Rejected: no severity at all.
A second check that tries to prove yof wrong
A separate, independent check tries to disprove findings that a model produced and fixes that a model wrote. It records why each one stands or falls, in a fixed order.
- Rules first. The file is not in the code that was read, the path is a test, fixture, example or docs folder, the line does not exist, the value is a placeholder, the installed version already has the fix, or the evidence is not on that line. A rule that disproves the claim decides, and a model can never overturn it.
- A model only when the rules cannot decide: one short, structured answer from our own engine.
- Every reason must point to a fact the checker was shown. An answer that names none is thrown away, and the claim stays undecided, never confirmed.
- The checker never sees what the earlier pass concluded. It is not shown the verdict, the severity, the title or what the fixing model said about its own fix, only the facts, which are the rule, the place, the code and the masked evidence.
Today it checks every fix Patch proposes that a model wrote, and findings you import with the yof command line tool are checked against your own files. Every yof check is rules today, so no finding in a delivered report has needed the model step yet.
Promises, and how we keep them
Each promise below is written into yof's code. Where an automated test checks that the code keeps it, we say so.
Attack tests only with proof and consent
yof attacks only a domain you have proven is yours, using two test accounts you give it and your consent written word for word. It is rate limited, at most 20 requests a second within a fixed budget of requests and time, and it has a working stop.
Enforced by an automated test.
yof never runs your code
yof's systems never install, build or run your code. Install, build and tests run in your own CI.
Enforced by an automated test.
File contents are not stored
yof reads your files in memory. After a scan it keeps its findings and one summary, not your files.
Enforced by an automated test.
Your code is not used to train models
No part of yof sends your code or your findings to model training.
Enforced by an automated test.
The package lookup sends names and versions only
To match your packages against public advisories, yof sends OSV.dev the package names and versions, never your code.
Enforced by an automated test.
Where your data is processed
yof's API runs every scan, report and Patch step in Frankfurt, Germany, so that work is processed in the EU, and the region is set in our code. Its database is in Frankfurt too, which is a setting with our provider, not code. Your repository is read from GitHub, where you host it, and the package lookup goes to OSV.dev. Where outside providers process data is a matter of their settings and contracts, not of our code. The data location page lists every place.
The region of our API is enforced by an automated test. The other places depend on settings and contracts.
What yof does keep
Two things are kept, and we say so plainly.
- Each code finding keeps one line of evidence, up to 140 characters, with secrets masked, so you can see what matched.
- Patch keeps the before and after lines of fixes that were merged, so a person can approve them as recipes for later fixes. This is how Patch learns. It is not model training.
Proof
Measured results come from our public benchmark: yof against two practice apps made to be attacked, scored against each app's own official list, with what it found, what it missed and what it flagged wrongly. The numbers are published per release of yof's checks, and each run names the yof version it measured. We do not quote numbers anywhere else.
A yof report is evidence for your security work. It is not a certification or legal advice, and a report with no findings does not mean the app has no weaknesses.
Credit
The verdict names and the findings.json format come from Cloudflare's open-source security-audit-skill (MIT licence). security-audit-skill on GitHub
yof's rules, words and code are its own.