skills/testing-application-security/SKILL.md
Applies OWASP-informed security testing within a tester scope: an authorization gate before any probing, authorization matrices, broken access control and IDOR checks, input validation and injection observation, session and auth behaviour, and safe reporting of findings. Use when testing auth-protected features, when a security review needs QA coverage, when an exploratory session surfaced something security-shaped, or when access control needs a systematic check rather than a spot check.
npx skillsauth add jaktestowac/awesome-copilot-for-testers testing-application-securityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when a feature's protection matters and the functional suite only proves the happy path works for someone who is allowed to use it.
This is security testing at a tester's depth: systematic verification that the application enforces what it claims, not penetration testing. The highest-value work here is unglamorous and rarely done: a complete authorization matrix, checked server-side, for every role against every endpoint. Broken access control is consistently the most common serious defect class in web applications, and it is found by being thorough rather than by being clever.
Everything in this skill runs after the authorization gate in Phase 0. Testing a system you are not authorized to test is not a testing activity.
Nothing else in this skill runs until this is complete. Work through ./resources/scope-and-authorization-gate.md and record:
If any line is missing, stop and get it. A missing authorization line is a blocking condition, not a formality to catch up on afterwards.
For third-party systems, a bug bounty scope statement counts as authorization for exactly what it lists and nothing else.
The API endpoints absent from the UI are the productive part. They are frequently protected by nothing except being undocumented.
The core deliverable. ./resources/authz-matrix-template.md has the format.
Every role against every protected resource, with the expected outcome and the observed one:
| Endpoint | Anonymous | User A | User B (other tenant) | Admin |
| --- | --- | --- | --- | --- |
| GET /api/orders/{A's id} | 401 | 200 | 403 | 200 |
| PATCH /api/orders/{A's id} | 401 | 200 | 403 | 200 |
| GET /api/admin/users | 401 | 403 | 403 | 200 |
Bold marks the expected allow. Every other cell is a deny that must be verified rather than assumed.
Check each cell at the API, with the session or token for that role, bypassing the UI entirely. A cell verified by "the button is not visible" is not verified.
The cases that produce findings:
GET denied, POST or PATCH unchecked on the same pathrole: "admin" in a profile update and seeing whether it sticksVerifiable at a tester's depth, from ./resources/owasp-test-angles.md:
HttpOnly, Secure, SameSiteSend inputs a validator should reject and observe the response. The goal is evidence of a class of defect, not exploitation.
Content-Type matches what it returnsWhen a response indicates a real injection path, stop and report. Confirming a vulnerability class is a tester's job; developing it into an exploit is not, and going further can cause damage the authorization did not cover.
testing-api-contracts finds these systematically)Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options.git directories, and backup files reachable in the deployed environmentSecurity findings do not go in the public bug tracker. Use ./resources/finding-report-template.md and the team's security disclosure path.
Each finding carries:
State the stopping point explicitly. "Confirmed that user A can read user B's order; did not enumerate further" tells the reader both what is proven and what remains unknown.
GET and not the other methods on the same path./resources/scope-and-authorization-gate.md - the Phase 0 record, what authorization must state, production rules, and stop conditions./resources/authz-matrix-template.md - matrix format, the cases that find defects, and API-level verification recipes./resources/owasp-test-angles.md - OWASP Top 10 mapped to concrete checks a tester can run, with the boundary of each./resources/finding-report-template.md - severity guidance, reporting path, redaction rules, and a worked exampleplanning-exploratory-testing - when a charter targets authorization or input handlingtesting-api-contracts - which finds undocumented response fields, one of the commonest data exposure pathshandling-sensitive-test-data - for the accounts and data used during security testingreporting-bugs - for non-security defects found along the way; security findings use the disclosure path insteadanalyzing-regression-scope - when a permission model change needs its blast radius mappedassessing-release-readiness - when a security finding bears on a go/no-go decisionauditing-accessibility - a different systematic audit over the same surfaceThis skill is complete when:
testing
Tests the customization assets themselves - skills, prompts, custom agents, instructions - the way a product is tested: activation cases that check an asset fires when it should and stays quiet when it should not, output-contract cases, safety cases, collision cases between assets competing for the same trigger, a weighted rubric scored blind, and a baseline-versus-candidate gate before an edit ships. Use when a skill is edited and nobody knows whether behaviour changed, when two skills fight over the same request, when a description is being tuned for discoverability, when a collection has grown past manual spot-checking, or when the request mentions skill evals, prompt regression, or "does this skill actually work".
development
Shapes QA output for the person who has to act on it: result and blocker in the first two lines, one decision per report, findings ordered by what they cost, the long artifact in a file and the decisions in the message, and magnitude stated in units the reader can count. Use when a report is accurate but nobody acts on it, when a finding set is too long to read under time pressure, when the same findings must be retold for a developer, a release manager, and an on-call engineer, or when the request mentions "too long", "make this readable", "just tell me what to do", "so what", or "summarize this for stakeholders". Pairs with unslop-answers, which makes the same report honest.
testing
Verifies that the lines and branches a change actually touched are executed by tests, using LCOV or Cobertura diff coverage instead of whole-repo percentages, and escalates uncovered high-risk changes into a blocking finding. Use when a pull request needs a coverage gate that unrelated tests cannot satisfy, when total coverage looks healthy but the diff is untested, when wiring diff coverage into CI, or when someone claims a change is covered because the suite is green.
development
Cuts AI tells from test code: tests that pass without proving anything, tautological assertions, mock-only tests, hardcoded waits, coverage theater, vague names, swallowed errors, retries used as fixes. Use whenever test code is written, changed, or reviewed, including tests produced as a side effect of a feature task, and when the request mentions "review these tests", "are these tests any good", "this test always passes", "this suite is flaky", or "clean up these tests". Must always apply to test code.