You write the scopeA config file in your repository, with a consent sentence and your own test accounts.It runs on your machine or in your CIAgainst a preview build. Your live site stays off unless your config turns it on.It tests like an attackerNo sign-in, a broken token, another account's record, admin pages as a normal member.Only what happened twice countsEach finding is confirmed twice and becomes a regression test.It cleans up and reportsIt deletes its own test records and sends only masked results to yof.
.yof/attack.jsonjson
{"app": "shop.example.com","consent": "I own shop.example.com and allow yof attack to test it…","accounts": { "a": { … }, "b": { … } },"production": { "enabled": false }}
$ npx @yof/cli attack http://localhost:3000
auth · signed-in pages with no sign-in and a broken token✓
tenant · account B reads account A's record1 finding
rbac · admin pages as a normal member✓
surface · redirects, headers, the sign-in cookie✓
tenant: seen twice · a regression test was written ✓
deleted its own test records ✓ · masked results sent to yof ✓
.yof/attack.jsonjson
{"app": "shop.example.com","consent": "I own shop.example.com and allow yof attack to test it…","accounts": { "a": { … }, "b": { … } },"production": { "enabled": false }}
$ npx @yof/cli attack http://localhost:3000
auth · signed-in pages with no sign-in and a broken token✓
tenant · account B reads account A's record1 finding
rbac · admin pages as a normal member✓
surface · redirects, headers, the sign-in cookie✓
tenant: seen twice · a regression test was written ✓
deleted its own test records ✓ · masked results sent to yof ✓
.yof/attack.jsonjson
{"app": "shop.example.com","consent": "I own shop.example.com and allow yof attack to test it…","accounts": { "a": { … }, "b": { … } },"production": { "enabled": false }}
$ npx @yof/cli attack http://localhost:3000
auth · signed-in pages with no sign-in and a broken token✓
tenant · account B reads account A's record1 finding
rbac · admin pages as a normal member✓
surface · redirects, headers, the sign-in cookie✓
tenant: seen twice · a regression test was written ✓
deleted its own test records ✓ · masked results sent to yof ✓
.yof/attack.jsonjson
{"app": "shop.example.com","consent": "I own shop.example.com and allow yof attack to test it…","accounts": { "a": { … }, "b": { … } },"production": { "enabled": false }}
$ npx @yof/cli attack http://localhost:3000
auth · signed-in pages with no sign-in and a broken token✓
tenant · account B reads account A's record1 finding
rbac · admin pages as a normal member✓
surface · redirects, headers, the sign-in cookie✓
tenant: seen twice · a regression test was written ✓
deleted its own test records ✓ · masked results sent to yof ✓
.yof/attack.jsonjson
{"app": "shop.example.com","consent": "I own shop.example.com and allow yof attack to test it…","accounts": { "a": { … }, "b": { … } },"production": { "enabled": false }}
$ npx @yof/cli attack http://localhost:3000
auth · signed-in pages with no sign-in and a broken token✓
tenant · account B reads account A's record1 finding
rbac · admin pages as a normal member✓
surface · redirects, headers, the sign-in cookie✓
tenant: seen twice · a regression test was written ✓
deleted its own test records ✓ · masked results sent to yof ✓
What it tests
authOpens each signed-in page with no sign-in and with a broken token.
tenantAccount A makes a test record, then account B tries to read it, find it in a list and change it.
rbacOpens each admin page as a normal member.
aiYour assistant: tries to read its hidden instructions, slip it commands, and reach another account's data.
surfaceOpen redirects, security headers and the sign-in cookie.
What it never does
It never tests your live site unless your config turns that on for this app.
It only reads, signs in and creates its own test records. It changes or deletes only what it made.
It stops at its budget: 300 requests and 110 seconds unless you set less or more.
It deletes its test records at the end, even when you stop it.
Your test accounts stay in your CI secrets. yof never stores a password or token.
shell
$ npx @yof/cli attack http://localhost:3000
.yof/attack.jsonjson
1{2"app": "shop.example.com",3"consent": "I own shop.example.com and allow yof attack to test it and its preview builds with my own test accounts.",4"accounts": {5"a": { "header": "Authorization", "env": "YOF_ATTACK_A" },6"b": { "header": "Authorization", "env": "YOF_ATTACK_B" },7"admin": { "header": "Authorization", "env": "YOF_ATTACK_ADMIN" }8 },
Attack tests
Run them yourself for free, or let yof run them for you as part of a report.
Run it yourself
Free
With the open-source command line tool, on your machine or in your CI, using test accounts you make.
yof runs it for you
Included
In “Security report: Full” ($499) and “Evidence pack” ($1,490). You give consent once in the app. Test accounts are optional.
Automated engagement In development
$1,990per appOpens soon
yof runs every attack test on one app, under rules you confirm first.