Get listed

Penetration testing vs vulnerability scanning: person vs tripwire

A teal doorbell beside a hat and coral coat on a stand.

A vulnerability scan is an automated inventory of known issues. A pentest is a human trying to chain them.

ZAP or a commercial scanner will find missing headers and textbook XSS. It will not sit with two accounts and walk the invoice id unless you pay for that work and scope it.

The usual mistake is using the words interchangeably in a board slide, then skipping the authenticated test.

This page is when each one is the right buy, and what you still write in CI either way.

ZAP 2.17.0 published on 15 December 2025. zap-baseline.py is a one-minute spider and a passive pass. A green badge that never swapped aliceSid for bobSid is the failure.

How to wire the baseline sits on OWASP ZAP in CI. How to scope the human hours sits on scope then close. The control you still write sits on the secure coding checklist. A missing owner check sits on IDOR.

Two products, two tickets

A scheduled scan matches banners, headers, cookie flags, and known CVE signatures. It is cheap. It should run often. It does not know Alice from Bob. It does not read a refund flow. It does not decide whether a 200 on GET /orders/8412 leaked a tenant.

A hired review is a person with two accounts, a written window, and time to follow a business rule. It is expensive. It should run when you ship a money path, a new tenant model, or a new authn scheme. It is not a weekly badge.

NIST SP 800-115, dated September 2008 on the CSRC page still lists both as different techniques. There is no 2026 replacement that merges the two names. Use both. Do not merge the names.

A green baseline never swapped the session. The person is hired for that swap.
TRIPWIRE zap-baseline.py on STAGING_ORIGIN
 rules.tsv FAILs cookie + 500 body
 green means headers still hold
 never invented aliceSid / bobSid

PERSON two fixtures, refund and export
 finding names the request
 you patch, they retest that id
 CI replay stays 404

What a scheduled scan actually reports

As of 22 August 2026, ZAP Baseline Scan page. The script spiders for one minute by default, waits for passive alerts, then prints PASS, WARN, IGNORE, and FAIL. The page says it does not perform actual attacks. That is the tripwire. Point it at staging you operate. Do not dump customer cookies into a shared runner log.

An infrastructure scanner, Nessus or an ASV job, reports missing patches, default services, and weak TLS ciphers. That is useful. It is still a signature list. Bob reading Alice’s export does not appear there. A PATCH that accepts role is outside its signatures. The eleventh login from one key still returning 200 is a fixture test, not a CVE.

Treat three scan flavors as one product family. ZAP baseline is a web tripwire on headers, cookies, and error bodies. An ASV job is a PCI scan of external hosts. An infra scanner is a CVE and service list inside the VPC. None of those three invents a second session. File them under “scan” in the tracker. Give them a weekly or monthly cadence. Do not give them a pentest label in Jira just because the vendor PDF said “ethical hacking.”

False positives are the other cost. A scanner that flags every missing X-Frame-Options on a JSON API will bury the one 500 that leaked a stack. That is why rules.tsv exists. FAIL the three ids this page named. IGNORE the alert you already ticketed as SEC-188. Review leftover WARN once a sprint, then promote or ignore. A pile of untriaged WARN is not a risk register.

SignalScannerPerson
Missing Secure cookieYes, every weekWill mention, not why you hired them
Known CVE on nginxYes, if the banner matchesOnly if it changes the app risk
Bob reads AliceNo, one sessionYes, that is the hour
Refund without payNoYes, they watch the flow
Extra PATCH fieldRarelyYes, they send role
False positive pileCommonThey drop it or prove it

gowenfawr said the same split on Security Stack Exchange in November 2013, answer 45585: a scan will notice FTP opened to the world. It will not give insight into the application you wrote. the8472 already carries this page. The action is the same: keep the weekly job, stop calling it a review.

What you hire a person to read

You hire a person after the tripwire is boring. Headers are set. Cookies are flagged. The obvious CVEs are patched. Then you pay someone to watch checkout, password reset, export, and admin impersonation with two subjects you minted.

They should file a finding that names the route, the subject, the request against STAGING_ORIGIN, and the fix. How you turn that into a ticket and a retest sits on the scope page. This page only cares that you did not pay them to re-run zap-baseline.py.

Ask for hours on the flows you cannot unit-test in an afternoon: refund, gift card, partner webhook, admin impersonation, CSV export. A person who spends the week confirming Strict-Transport-Security is present has sold you a scan. Send that week back. Keep the hours for the flow.

OWASP API Security Top 10 2023 is still the current API list on 22 August 2026. project page. There is no 2025 API edition. API1 is still object-level authorization. A spider that never swaps the session scores that green. The person is the one who uses bobSid on Alice’s orderId.

PCI keeps the words apart

PCI SSC post dated 11 June 2024. PCI DSS v4.0.1 is a limited revision of v4.0. No requirements added or deleted. v4.0 retired on 31 December 2024. Future-dated items became mandatory on 31 March 2025. The public split every QSA still enforces is enough: an ASV scan is one artifact. A human application review is another. A clean scan report does not retire the review.

If a vendor sells you “PCI pentest” and the deliverable is a vulnerability export with a cover sheet, ask which artifact the QSA will accept. Then ask to see a finding that is not a CVE. If they cannot show one from a prior redacted report, you are buying a scan.

Write the two artifacts into the compliance folder with different names. scan-asv-2026-03.pdf is the ASV job. review-checkout-2026-09.pdf is the human writeup plus the retest addendum. A single file named pentest-q1.pdf that is only plugin ids is how the8472’s piggy bank gets into the audit zip. Keep the filenames honest even if a salesperson will not.

Run the tripwire you already own

Commit rules.tsv next to the app. FAIL the alerts you mean. IGNORE the ones you have already ticketed. The ZAP page has the Docker line and the workflow. This page only names the policy: staging you own, no production customers, exit 1 on FAIL.

# rules.tsv identifiers stay 10010, 10011, 90022
10010	FAIL	(Cookie No HttpOnly Flag)
10011	FAIL	(Cookie Without Secure Flag)
90022	FAIL	(Application Error Disclosure)
10035	IGNORE	(Strict-Transport-Security, ticketed SEC-188)

The numbers are ZAP alert ids. baseline docs. 10010, 10011, and 90022 are the three this page FAILs. If you use a different scanner, keep the same idea: fail closed on a missing cookie flag and on a 500 that talks. Do not fail the pipeline on a pile of INFO noise you have not triaged.

The proof that the tripwire still sees a miss:

# On staging you operate. Strip one FAIL header, expect exit 1.
docker run --rm -t \
 -v "$(pwd):/zap/wrk:rw" \
 ghcr.io/zaproxy/zaproxy:stable \
 zap-baseline.py -t "$STAGING_ORIGIN" -c rules.tsv
# Restore X-Content-Type-Options. Expect exit 0.

If the job reports 0 URLs, the spider never reached the app. That is a missed target, not a secure app. Fix compose, then read the report. Full details and the GitHub Action sit on the ZAP guide.

When the invoice is worth it

Buy the person when you cannot write the test yourself yet, or when a second pair of eyes on a money flow is cheaper than a public bug. Do not buy the person to discover HttpOnly is missing. The tripwire already does that.

Write roe.yml first. Mint alice@shop.example and bob@shop.example. Name STAGING_ORIGIN. Hold a slice of pay for retest. The scope page is the loop. The types page is the evidence by surface. This page is only the split.

// test/object-replay.spec.js the scan will not write this
const request = require("supertest");
const app = require("../src/app");

test("Bob cannot read Alice order", async () => {
 const aliceSid = process.env.ALICE_SID;
 const bobSid = process.env.BOB_SID;
 const created = await request(app)
.post("/orders")
.set("Cookie", aliceSid)
.send({ sku: "SKU-1", qty: 1 });
 const replay = await request(app)
.get(`/orders/${created.body.id}`)
.set("Cookie", bobSid);
 expect(replay.status).toBe(404);
});

Identifiers stay aliceSid, bobSid, STAGING_ORIGIN, rules.tsv, and zap-baseline.py. If a questionnaire asks “do you pentest,” answer with two sentences: weekly baseline on staging, human review on the last money-flow change, dated. Do not tick one box for both.

A cheap questionnaire reply that stays honest:

# security-questionnaire.answers.yml
vulnerability_scanning:
 tool: zap-baseline.py
 cadence: every_week
 target: STAGING_ORIGIN
 policy: rules.tsv
 last_green: "2026-08-18"
human_review:
 last_engagement: checkout-web-2026q3
 scope_file: roe.yml
 last_retest: "2026-09-22"
 not_the_same_as: vulnerability_scanning

If procurement only allows one line, put the human review on that line and attach the weekly job as a separate exhibit. Never the reverse. A tripwire exhibit cannot carry a review question.

Questions we keep getting

Does a green ZAP job replace a hired review?

No. It replaces a forgotten cookie flag and a leaked 500. It does not replace two accounts or a person reading refund. Call it a tripwire on the ticket.

Can an ASV scan satisfy a pentest line on a form?

Not honestly. An ASV scan is a scan. If the form has two lines, fill both. If it has one line and means a person, do not attach Nessus.

Should I run an active full scan on production?

No. Keep zap-baseline.py on staging. Schedule any active job on a throwaway dataset. Production customer traffic stays out of that schedule.

Gilad David Maayan / About Author

Gilad David Maayan is a technology writer who has worked with over 150 technology companies including SAP, Imperva, Samsung NEXT, NetApp and Ixia, producing technical and thought leadership content that elucidates technical solutions for developers and IT leadership.

LinkedIn