APS-95Recommended
Write abuse cases next to user stories
For each user story that touches money, accounts, personal data or a new outside connection, write at least one abuse case. It says how someone could misuse the feature and what the app must do instead.
How to do it
An abuse case is a user story told by an attacker or a careless user. "As a shopper, I apply a coupon" gets "As a shopper, I apply the same single-use coupon from two tabs at once". Write it in the same ticket, with the expected safe result. Turn it into an automated test before the feature ships, as Turn every fix into a check does for findings. Use the STRIDE line from the threat file to find cases you would miss.
Examples
JavaScript example
test('abuse case: one single-use coupon redeemed from two tabs at once works once', async () => {
const results = await Promise.all([redeem(cart, 'WELCOME10'), redeem(cart, 'WELCOME10')]);
assert.equal(results.filter(r => r.ok).length, 1);
});
Python example
def test_abuse_case_single_use_coupon_from_two_tabs_works_once(client, cart):
with ThreadPoolExecutor() as pool:
results = list(pool.map(lambda _: redeem(client, cart, "WELCOME10"), range(2)))
assert sum(r.ok for r in results) == 1
How to check
A script reads the tickets merged in the last release that carry a sensitive label. Each links at least one abuse case, and each abuse case names a test that exists and passes.
Sources
Related rules
- APS-1 Plan attacks before building in Application security
- SEC-7 Turn every fix into a check in Adversarial testing
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/threat-modelling/abuse-cases">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.