Security Testing
Verify that a system protects data, maintains functionality as intended, and resists unauthorised access, disclosure, or modification. A significant portion of security bugs can be found by functional testers — without specialist tools.
1 The Hook
An Auckland online retailer launches a customer order-history page. Every functional test passes: you log in, you see your own orders, you can’t see the page when logged out. The order page URL is /orders/1001. Sign-off given.
One curious tester — not a security specialist, just someone thinking like an attacker — changes the URL to /orders/1002. Another customer’s order appears: their name, delivery address, and what they bought. No special tools, no exploit kit, just editing a number in the address bar. Because the page checked “are you logged in?” but never “is this order actually yours?”, every customer’s personal information was one keystroke away from anyone with an account. Under NZ law that exposure is a notifiable privacy breach, and it would have shipped because the happy-path tests all went green.
This is the core shift in security testing: functional testing asks “does it do what it’s supposed to?” Security testing asks “what happens when I deliberately try to make it do something it’s not supposed to?” The most damaging defects are invisible to anyone who only walks the intended path — and a large share of them can be found defensively, by a tester with a browser and a habit of asking “what if I change this?”
Security testing is the deliberate act of probing your own system as an attacker would — not to break it, but to find the gaps before release; use it any time a feature touches personal data, authentication, or user-supplied input. The checks that matter most (IDOR, session expiry, verbose errors, XSS) require no specialist tools — only a browser, two test accounts, and the habit of asking "what if I change this?". The mistake testers most often make is testing with a single account: one account can only confirm you see your own data, never that another user's data is protected.
From the field
A NZ health organisation ran OWASP ZAP against their patient portal and got a clean report. Three months later a pen test found an IDOR vulnerability: changing a numeric ID in the URL exposed other patients appointment history. ZAP does not test business logic — it tests known patterns. The pen test cost $15,000; the regulatory notification process cost considerably more. Automated scanning finds common vulnerabilities; it does not replace thinking like an attacker.
The most expensive lesson I keep watching teams repeat: they get a penetration test booked for six weeks out and treat that as permission to skip security checks in the sprint. The pentester arrives, finds six critical IDORs in three hours, and suddenly there is a two-week rework spike the week before go-live. Every single one of those findings was something a tester with two accounts could have caught in Sprint 2. The pentest is not your safety net — it is your last resort. Run the browser checklist every sprint that touches auth or personal data. Brief the pentester on what changed since the last engagement. Treat their report as confirmation you missed something, not as the primary discovery mechanism.
2 The Rule
Security testing is asking what happens when you behave as an attacker would — so don’t only test the intended path. Probe access control, input handling, error messages and sessions by deliberately misusing them, because the worst defects only appear off the happy path.
3 The Analogy
Walking the perimeter of a building, not just the front door.
A building owner who only ever tests the front door — key works, door opens — learns nothing about whether the place is secure. A diligent caretaker walks the whole perimeter: jiggling the side gate, checking the fire exit hasn’t been propped open, seeing if the ground-floor windows latch, noticing the spare key under the mat. They’re not breaking in; they’re finding the ways someone else could, so the gaps get fixed before anyone with bad intent arrives.
Security testing is that perimeter walk. You’re not attacking the system for real — you’re defensively checking the side doors (changed an ID), the propped-open fire exit (a session still valid after logout), and the key under the mat (a verbose error message leaking file paths), so they’re closed before release.
Common Mistake vs What Works
Security testing is booked as a one-off penetration test at the end of the project. The security team receives a ticket, arrives with fresh eyes, and finds critical IDORs and session bugs in the first session. Release is blocked. Developers are surprised. Everyone scrambles.
Shift security left: run SAST on every commit, include an OWASP dependency scan in CI, and have one developer-led threat model conversation per new feature that touches auth or personal data. Functional testers run the browser checklist (IDOR, session expiry, verbose errors, XSS) every sprint. The penetration test becomes a final confirmation — not the first time anyone has thought about security. No surprises at release, and no NZD$10,000 Privacy Act exposure sitting undetected until go-live.
What it is
Security testing evaluates whether a system protects its data and functionality against threats. It covers confidentiality (only authorised users see data), integrity (data isn’t altered without authorisation), and availability (the system stays up under attack).
Security testing is a spectrum. At one end, functional testers check basic things like whether admin URLs require login and whether error messages reveal stack traces. At the other end, specialist penetration testers (pentesters) use advanced tools and techniques to probe for deeper vulnerabilities. Most teams need both — and functional testers can find a surprising number of critical bugs before a pentester ever arrives.
The distinction that matters: security testing is not just about what the application is supposed to do. It’s about what happens when you deliberately try to make it do something it’s not supposed to. Thinking like an attacker is the core skill.
When to use it
- Before any release involving user data, authentication, or personal information
- Before releasing payment functionality (PCI-DSS requirements apply)
- When new endpoints are added that accept user-supplied input
- When authentication or session management code is changed
- In NZ, whenever a system stores or processes personal information — Privacy Act 2020 requires “reasonable security safeguards”
OWASP Top 10
The Open Web Application Security Project (OWASP) maintains a list of the ten most critical web application security risks. Understanding these helps you think like an attacker and know what to look for.
| # | Risk | What it means in practice |
|---|---|---|
| A01 | Broken Access Control | User A can view or modify User B’s data. Example: changing ?orderId=1001 to ?orderId=1002 shows another NZ customer’s order. The most common critical vulnerability in production systems. |
| A02 | Cryptographic Failures | Sensitive data is inadequately protected. Passwords stored in plain text; credit card numbers logged; pages served over HTTP instead of HTTPS; weak TLS configuration. |
| A03 | Injection | User-supplied data is interpreted as code. SQL injection via a search box; XSS (cross-site scripting) where a review field stores <script>alert(1)</script> and it executes when another user views it. |
| A04 | Insecure Design | Fundamental design flaws. Example: a “forgot password” flow that emails the user their actual password (meaning it was never hashed); no rate limiting on a login endpoint. |
| A05 | Security Misconfiguration | Default credentials left enabled (admin/admin); verbose error messages that show stack traces with file paths; directory listing enabled on a web server; debug mode left on in production. |
| A06 | Vulnerable Components | Using outdated libraries with known CVEs (Common Vulnerabilities and Exposures). A critical vulnerability in an npm package or Java library can compromise the entire application. |
| A07 | Auth and Session Failures | Session tokens that never expire; tokens that remain valid after logout; weak password requirements; no multi-factor authentication on high-value accounts. |
| A08 | Software Integrity Failures | No verification of third-party scripts loaded from CDNs; a compromised npm package silently published under the same name; no code signing for auto-update mechanisms. |
| A09 | Logging & Monitoring Failures | No audit trail for admin actions (who deleted that customer record?); failed login attempts not logged; no alerting when abnormal access patterns occur. |
| A10 | SSRF | Server-Side Request Forgery. The server fetches URLs supplied by users — allowing an attacker to make the server request internal resources (AWS metadata endpoints, internal APIs) that should never be publicly accessible. |
NZ context: Privacy Act 2020
In New Zealand, the Privacy Act 2020 requires organisations to have reasonable security safeguards to protect personal information. Unlike its predecessor, the 2020 Act introduced mandatory breach notification: if a privacy breach occurs and is likely to cause serious harm to affected individuals, the organisation must notify both the Privacy Commissioner and the affected individuals as soon as practicable.
The Privacy Commissioner has the power to investigate complaints, issue compliance notices, and refer cases to the Human Rights Review Tribunal. Penalties of up to NZD$10,000 per offence can apply.
What this means for testers: if you discover a vulnerability during testing — especially one that could expose personal information — treat it as a high-priority defect and ensure it is tracked, addressed, and verified before release. Document your finding clearly: what data was accessible, under what conditions, and what the potential harm is.
What functional testers can check
You don’t need Burp Suite or specialist training to find these bugs. A browser and some curiosity is sufficient:
| Check | How to do it | What a bug looks like |
|---|---|---|
| IDOR (Insecure Direct Object Reference) | Find a URL with an ID (e.g. /orders/1001). Log in as a different user. Try /orders/1001 — can you see the first user’s order? |
Any response other than 403 Forbidden is a critical bug |
| HTTPS everywhere | Try loading http:// versions of all pages. Check for mixed content warnings in browser DevTools. |
Any page that loads over HTTP, or loads resources (scripts, images) over HTTP on an HTTPS page |
| Verbose error messages | Submit malformed data; try accessing non-existent URLs; trigger server errors. Check the response body. | Stack traces, file paths (/var/www/html/app.php), database table names in error messages |
| Session expiry after logout | Log in. Copy a session cookie or auth token. Log out. Try using the copied token to make a request. | A 200 response after logout means the session was not invalidated server-side |
| Session expiry after inactivity | Log in. Leave the session idle for 30 minutes. Try to perform an action. | Session still valid after a long period of inactivity |
| XSS in input fields | Submit <script>alert(1)</script> in text fields (name, address, review, search). Save and view the result in a browser. |
An alert box appears, or the script tag appears unescaped in the HTML source |
| Unauthenticated admin access | Copy an admin URL (e.g. /admin/users). Open a private/incognito window and paste it without logging in. |
Page loads instead of redirecting to the login page |
Common bugs
- IDOR — changing
?customerId=123to?customerId=124returns another customer’s personal data. Extremely common and often critical. - Verbose error messages — a 500 response that includes a Java stack trace or internal file paths; attackers use this to understand the system architecture
- No rate limiting on login — allows an attacker to try thousands of password combinations (brute force) without being blocked
- Missing CSRF tokens — state-changing forms (change email, change password, transfer money) without CSRF tokens can be triggered by malicious sites if a victim is already logged in
- Password stored in plain text — detectable if “forgot password” sends you your actual password rather than a reset link
- Auth token in URL — tokens in query parameters (
?token=abc123) are logged by web servers, proxies, and browser history, leaking credentials
Tools
- OWASP ZAP (free) — automated scanner that crawls your application and identifies common vulnerabilities; good starting point for teams without a dedicated pentester
- Burp Suite Community (free) — intercepting proxy that lets you inspect and modify requests/responses; used by professional pentesters and advanced testers
- Browser DevTools — built into every browser; use the Network tab to inspect requests/responses, the Application tab to view cookies and storage, and the Console to spot JavaScript errors
Tips
Think like an attacker. As a functional tester, you can find a significant portion of security bugs without specialised tools — just by thinking like an attacker. What would happen if I changed this ID? What if I remove the auth header? What if I submit a script tag? What if I try to access this admin URL when logged out? These questions cost nothing and catch critical issues.
- Raise security bugs as high priority — a bug that exposes personal data is more critical than a bug that breaks a feature. Make sure your defect severity model reflects this.
- Don’t just test happy paths — the most dangerous bugs are found when you deliberately behave as a malicious user would
- Check error messages carefully — they frequently reveal internal implementation details that are useful to an attacker and should never be exposed to end users
- Include security testing in your Definition of Done — at minimum, the functional-tester security checklist above should be completed before any user story is marked done
4 Industry Reality
- Security testing is rarely scheduled as a formal phase — most teams expect functional testers to fold it into their existing test pass. You will be doing OWASP spot-checks while also writing regression tests for the same sprint, under the same time pressure.
- The IDOR check (change an ID in the URL) is the single highest-value thing a functional tester can do and takes under five minutes. In practice, it is routinely skipped because testers only test their own account, never swapping sessions. Senior testers build a two-account habit from day one.
- Developers often push back on security findings as “edge cases” or “not our threat model.” In NZ, referencing the Privacy Act 2020 — specifically mandatory breach notification and the potential NZD$10,000-per-offence penalties — reframes the conversation from technical taste to legal obligation.
- Most teams do not have a dedicated security team. OWASP ZAP is free and takes an hour to set up, but the real barrier is organisational: someone has to own it. In practice, the QA lead often becomes the de-facto security triage person by default.
- Pentest reports come back after code is “done.” Findings that a functional tester could have caught in Sprint 3 (verbose error messages, no session expiry) land as critical findings in a penetration test report six weeks before go-live, causing expensive rework. Preventive checklists save significant cost.
5 When to Use It — and When Not To
✓ Use it when
- Any feature handles personal information — names, addresses, Revenue NZ numbers, health records. Privacy Act 2020 obligation applies regardless of system size.
- Authentication, session management, or authorisation code has changed — these are the highest-risk areas per OWASP and warrant explicit security checks every time.
- New endpoints accept user-supplied input (search, file upload, form fields) — injection and XSS risk is introduced at these integration points.
- The system exposes record IDs or sequential identifiers in URLs, API responses, or redirect parameters — IDOR is almost always worth a two-minute check.
- You are releasing to NZ government, health, or financial services — NZISM, Health Information Privacy Code, and PCI-DSS requirements layer on top of the baseline.
✗ Skip it when
- A dedicated specialist penetration test is already contracted for the same sprint or release. Avoid duplicating effort; focus your time on functional coverage and hand off the security surface to them — but do brief them on what changed.
- The feature is entirely read-only, unauthenticated, and handles no personal data (e.g. a public marketing page). Basic HTTPS checks still apply, but deep security exploration is not warranted.
- You are testing a purely internal admin tool with no external exposure and access locked to a small, trusted internal network — proportionate risk assessment applies.
- The system stores no personal information and has no authentication layer at all — a simple static site with no user accounts has almost no relevant security surface for a functional tester.
- You are under no time budget whatsoever and have already performed a full security review in the previous sprint with no changes to the auth or data layer since. Re-testing unchanged surfaces is low ROI.
Context guide
How the right level of security testing effort changes based on project context.
| Context | Priority | Why |
|---|---|---|
| Benefits NZ, Revenue NZ, CoverNZ, HealthNZ — citizen-facing portals holding benefit, tax, health, or CoverNZ records | Essential | Privacy Act 2020 mandatory breach notification applies. An IDOR exposing another citizen’s payments or medical history is both a critical defect and a notifiable breach. Full OWASP checklist plus IDOR cross-account testing required every release. |
| NZ banks and KiwiSaver providers — platforms handling financial transactions and retirement savings | Essential | PCI-DSS requirements apply alongside Privacy Act obligations. Session management, IDOR, and input handling must be verified on every sprint that touches transaction or account features. MFA and rate limiting on login are non-negotiable. |
| NZ government SaaS applications under the NZISM | High | NZISM mandates reasonable security controls proportionate to classification. Functional testers should run the full browser checklist; a structured OWASP ZAP passive scan is expected before sign-off on any release touching official information. |
| NZ airlines, telcos, and large commercial platforms with customer accounts and loyalty data | High | High-volume systems with large PII footprints. IDOR on booking or account history pages would expose flight itineraries, contact details, and loyalty balances at scale. Browser checklist plus session testing on every auth-touching sprint. |
| Internal B2B tools with no public exposure and no personal data (e.g. an internal reporting dashboard) | Medium | Internal tools can become external-facing over time, and insider threats still apply. Run IDOR, session, and verbose-error checks at minimum; skip deep penetration-test investment unless the data warrants it. |
| Static marketing sites with no authentication, no user input, and no personal data stored | Low | Very small security surface. Confirm HTTPS is enforced and security headers are present, then move on. No session or IDOR testing needed when there are no user accounts or personal data. |
Trade-offs
What you gain and what you give up when you choose security testing.
| Advantage | Disadvantage | Use instead when… |
|---|---|---|
| Catches critical IDOR, session, and XSS defects weeks before a penetration test — avoiding expensive late rework sprints and Privacy Act breach notification costs. | Only covers the surface a tester can reach with a browser. Business logic and chained exploits require specialist tooling and adversarial expertise that functional testers do not have. | A contracted penetration test is already scheduled for the same sprint — avoid duplicating effort; hand off a brief on what changed since the last engagement instead. |
| No specialist tools required — the full browser checklist (IDOR, HTTPS, verbose errors, session expiry, XSS) takes under 20 minutes with DevTools and two test accounts. | Requires two test accounts for every IDOR check; teams that provision only one test account per environment cannot meaningfully test access control boundaries. | The feature is a fully static, unauthenticated page with no user input and no personal data — HTTPS header checks suffice and deep security exploration is not warranted. |
| Framing findings against the Privacy Act 2020 reframes a “low priority edge case” conversation into a “notifiable breach risk” conversation, which typically accelerates fix prioritisation in NZ organisations. | Over-reporting can cause alert fatigue — flagging theoretical risks on low-sensitivity systems as “critical” erodes the team’s trust in security findings when a genuine high-risk issue arrives. | Automated DAST scanning (OWASP ZAP) is already running in CI on every build — invest tester time in business-logic access control checks that scanners cannot reach. |
| Integrating security checks into the Definition of Done shifts discovery left — the cost to fix a session bug found in Sprint 3 is a fraction of the cost to fix it in a penetration test report six weeks before go-live. | Adding security to every sprint increases test cycle time. On high-velocity teams, the checklist must be scoped to changed surfaces only — re-testing unchanged code with no auth changes provides diminishing returns. | The system has no authentication layer and stores no personal data — a quick HTTPS and header check is proportionate; a full security pass would be over-investment. |
Enterprise reality
How Security Testing changes when 200–300 developers are shipping to production across 10+ squads in a NZ enterprise
- Manual pen-testing gets replaced by continuous automated scanning — SAST tools (Checkmarx, Semgrep) run in CI on every pull request, and DAST tools (OWASP ZAP, Burp Suite Enterprise) run nightly against staging, so no squad can merge without a clean security gate.
- Compliance obligations are non-negotiable at scale: the NZ Privacy Act 2020 mandates breach notification within 72 hours, the NZISM (NZ Information Security Manual) governs government agencies, and any squad touching card payments must satisfy PCI DSS — which means quarterly ASV scans, segmented cardholder data environments, and annual pen-tests by a QSA. Large NZ government agencies run independent security assurance programmes to satisfy Treasury risk requirements.
- Tooling gets centralised: at the scale of large NZ financial services organisations, a dedicated AppSec team owns a Veracode or Snyk licence and ingests results into a SIEM (Splunk or Microsoft Sentinel) — individual squads consume findings via dashboards rather than running their own tools, and secrets-scanning (Truffleog, GitHub Advanced Security) is enforced organisation-wide at the SCM level.
- A single unpatched critical CVE in a shared library can cascade across dozens of services: when Log4Shell hit in December 2021, NZ enterprises with 50+ Java services had to co-ordinate emergency patches across every squad simultaneously — organisations without a software bill of materials (SBOM) couldn't even enumerate their exposure within 48 hours, let alone remediate it.
◆ What I would do
Professional judgment — when to reach for security testing, when to skip it, and what to watch for.
The bottom line: Security testing is not a phase at the end of a project — it is a habit built into every sprint that touches auth, personal data, or user input. Two test accounts, a 20-minute browser checklist, and the habit of asking “what if I change this?” will catch the majority of critical findings before a penetration test ever does.
6 Best Practices
- ✓ Always test with two accounts, not one. Create “User A” and “User B” test accounts at the start of any project with authentication. Every IDOR check requires you to swap sessions, not just change a number. One account tests nothing.
- ✓ Make a browser-only security checklist part of your Definition of Done. Five checks (IDOR, HTTPS, verbose errors, session expiry, XSS) take under 20 minutes and catch the most common critical findings before a pentester ever arrives.
- ✓ Raise security bugs one severity level higher than your default. A bug that exposes another user’s personal information is more critical than a bug that breaks a feature. If you would normally log it as High, log it as Critical. This signals urgency to developers and product owners.
- ✓ Document security findings with what data was exposed, not just the URL. “IDOR on /orders” is weak. “IDOR on /orders/{id} — exposes name, delivery address, and order history of any registered customer; tested with accounts 1001 and 1002 in staging” gives developers and legal teams what they need.
- ✓ Always test logout by reusing a copied token, not just by clicking the button. Clicking logout clears client-side state. The question is whether the token is invalidated server-side. Copy the session cookie before logging out, then replay a request with it. A 200 response is a bug.
- ✓ Check error messages at all boundary conditions, not just obvious failure cases. Error messages leak internals when you submit malformed input, hit non-existent URLs, send wrong content-types to APIs, or trigger arithmetic errors. Add these to your input testing pass.
- ✓ In NZ, explicitly frame security findings against the Privacy Act 2020 when they involve personal data. This reframes the conversation from “edge case” to “notifiable breach risk” and typically accelerates priority decisions in ways that a purely technical bug description does not.
- ✓ Use OWASP ZAP as a passive scanner, not just a tool for specialists. Running it in proxy mode against a normal test session takes almost no extra effort and catches common misconfigurations (missing security headers, insecure cookies, exposed server info) automatically.
- ✓ Verify security fixes, not just that the bug is closed. After a developer fixes an IDOR, retest with both accounts. After a verbose error fix, retrigger the same error condition. It is common for one fix to close the obvious path but leave a related path open.
- ✓ Brief the development team on your security testing scope before each sprint. Security testing is most effective when developers know what you will look for and can raise concerns during implementation, not after. A ten-minute sync beats a surprise critical bug post-merge.
7 Common Misconceptions
❌ Myth: Security testing requires a specialist pentester and tools like Burp Suite — functional testers cannot do it meaningfully.
Reality: A significant proportion of the most common and most critical vulnerabilities — IDOR (Broken Access Control), verbose error messages (Security Misconfiguration), session-not-invalidated-on-logout (Auth Failures), and stored XSS (Injection) — can be found with a browser, two test accounts, and deliberate misuse of inputs. Pentesters use advanced tools to go deeper, but functional testers routinely catch the bugs that slip through developer review precisely because they think about inputs and state transitions. OWASP ZAP adds an automated layer at near-zero setup cost. The absence of a pentester is not a reason to skip security checks.
❌ Myth: If the happy-path tests pass and the login works, security is fine.
Reality: This is the exact failure mode that produces critical production incidents. Happy-path testing confirms the system does what it is supposed to; security testing asks what happens when you deliberately try to make it do something it is not supposed to. The Auckland retailer example in The Hook illustrates this precisely: every functional test passed, login worked correctly, and yet any customer could read any other customer’s order with a single URL edit. Access control, session management, and input handling failures are invisible to happy-path testing by design — they only appear when you step off the intended path.
❌ Myth: XSS is a theoretical risk — in practice it just shows an alert box and is low priority.
Reality: The alert(1) proof-of-concept is only used to confirm the injection point. In a real attack, the same injection executes JavaScript that steals session tokens, redirects users to phishing pages, logs keystrokes on a login form, or makes authenticated API requests on behalf of the victim. Stored XSS (where the payload is saved in the database and executes for every user who views that page) can compromise thousands of sessions from a single injected string. A review field that reflects <script>alert(1)</script> is a critical vulnerability, not a cosmetic one.
8 Now You Try
Three graded exercises — spot, fix, then build. Everything here is defensive: you’re finding gaps in your own system so they’re closed before release. Write your answer, run it for AI feedback, then compare to the model answer.
During testing of a NZ council portal you observe four things: (a) changing /rates/4501 to /rates/4502 shows another ratepayer’s account; (b) the “forgot password” email contains your actual password; (c) a 500 error page prints a full stack trace with server file paths; (d) your session cookie still works after you log out. For each, name the OWASP Top 10 category it maps to and why it matters for a system holding personal information.
Show model answer
OWASP mapping: (a) Changing /rates/4501 to /rates/4502 shows another account → A01 Broken Access Control (an IDOR). The system checks you're logged in but not that the record is yours. It exposes other ratepayers' personal information — under the Privacy Act 2020 that's a notifiable breach risk. Fix: enforce per-record ownership checks server-side; return 403. (b) "Forgot password" emails your actual password → A02 Cryptographic Failures (and arguably A04 Insecure Design). If the system can email your password, it isn't hashed — so a database leak exposes every password. Fix: store passwords hashed (e.g. bcrypt/argon2) and send a one-time reset link, never the password. (c) Stack trace with file paths in a 500 page → A05 Security Misconfiguration. Verbose errors hand an attacker the system's internal structure (paths, frameworks, table names). Fix: show a generic error to users; log the detail server-side only; disable debug mode in production. (d) Session still valid after logout → A07 Identification and Authentication Failures. Logout must invalidate the session server-side, not just clear it client-side. Fix: destroy/revoke the session token on logout so a copied token stops working.
A developer describes a NZ banking app’s login below. It has three security weaknesses that a defensive tester should raise. Identify each and state the fix.
“There’s no limit on login attempts. After login we put the session token in the URL like
?token=abc123 so it’s easy to pass around. Failed logins say ‘wrong password’ if the email exists and ‘no such user’ if it doesn’t.”
Identify the weaknesses and give the fix for each:
Show model answer
Three weaknesses (all A07 Auth/Session, with an A02 element):
1. No rate limiting on login — allows unlimited password guessing (brute force / credential stuffing).
Fix: rate-limit and lock out after repeated failures; add CAPTCHA and/or MFA on a banking app.
2. Session token in the URL (?token=abc123) — tokens in URLs are logged by servers, proxies, and browser history, and leak via the Referer header, so credentials are exposed.
Fix: put the session token in a secure, HttpOnly, SameSite cookie — never in the URL.
3. Different messages for "wrong password" vs "no such user" — user enumeration: an attacker can discover which emails are registered.
Fix: return a single generic message ("email or password is incorrect") regardless of which part failed.
A senior would add: enforce MFA on a high-value banking account and confirm tokens are invalidated on logout and expire on inactivity.
A NZ government service handling personal information is about to release a new authenticated “view my submissions” feature. The NZISM expects reasonable security controls and the Privacy Act requires safeguarding personal information. Design a defensive security checklist a functional tester can run with just a browser — cover access control, transport security, error handling, sessions, and input handling. For each item, give the check and what a bug looks like.
Show model answer
Defensive functional-tester security checklist (browser only): 1. Access control (IDOR) — Check: log in as User A, then request User B's submission by changing an ID in the URL or request. Bug: any response other than 403/blocked — User B's data is returned. 2. Transport security (HTTPS) — Check: try the http:// version of pages and watch DevTools for mixed content. Bug: a page loads over HTTP, or an HTTPS page pulls scripts/images over HTTP. 3. Error handling — Check: submit malformed input and hit non-existent URLs; read the response body. Bug: stack traces, server file paths, framework versions, or database table names exposed to the user. 4. Sessions — Check: log in, copy the session token/cookie, log out, then reuse it; also leave a session idle. Bug: the copied token still works after logout, or the session never expires on inactivity. 5. Input handling (XSS) — Check: enter into name/address/search fields, save, then view the result. Bug: the alert fires, or the tag appears unescaped in the page source. These are all defensive checks on your own system. A senior would also fold this list into the Definition of Done and raise any finding that exposes personal information as a high-priority, Privacy-Act-relevant defect.
How this has changed
The field moved. Here is how Security Testing evolved from its origins to current practice.
Security testing is a specialised, manual discipline. Penetration testers are hired for large projects. Most development teams do not test for security — they rely on network perimeters and assume internal code is safe.
OWASP founded. The OWASP Top 10 first published in 2004 gives development and QA teams a common vocabulary for web application security risks. Security testing begins entering mainstream QA practice.
DAST tools (OWASP ZAP, Burp Suite) become accessible to QA teams. SAST tools integrate into IDEs and CI pipelines. DevSecOps movement pushes security left — security gates added to build pipelines rather than being a pre-launch activity.
Supply chain attacks (SolarWinds, Log4j) make dependency scanning mandatory. Software Bill of Materials (SBOM) becomes a procurement and compliance requirement. Security testing expands from the application to the entire software supply chain.
AI systems introduce new attack surfaces — prompt injection, model extraction, data poisoning. OWASP Top 10 for LLM Applications (2023) and ISO/IEC 42119 provide emerging frameworks. Security testing scope now includes model behaviour, not just application code.
Self-Check
Click each question to reveal the answer.
Why teams fail here
- DAST scanner results are treated as the complete security test — business logic vulnerabilities go untested
- Security testing is a phase at the end of the project rather than threat modelling from the start
- Testers check authentication exists but do not test authorisation boundaries between users and roles
- Third-party dependencies are never scanned for known CVEs, only the application code is reviewed
Q1: What is the fundamental difference between functional testing and security testing?
Functional testing asks “does the system do what it’s supposed to?” Security testing asks “what happens when I deliberately try to make it do something it’s not supposed to?” The mindset shift — thinking like an attacker while staying defensive — is the core skill, because the worst defects only appear off the intended path.
Q2: What is an IDOR, how do you test for it defensively, and which OWASP category is it?
An Insecure Direct Object Reference lets a user reach another user’s record by changing an identifier (e.g. /orders/1001 → /orders/1002). Test it by logging in as one user and requesting another user’s data by ID — you should get a 403, not the data. It maps to A01 Broken Access Control, the most common critical web vulnerability.
Q3: Why are verbose error messages a security problem, and what should happen instead?
Stack traces, file paths, framework versions, and database table names in an error response hand an attacker a map of the system’s internals. Users should see a generic error message, the detail should be logged server-side only, and debug mode must be off in production. This is A05 Security Misconfiguration.
Q4: How can you tell, defensively, that passwords are not being hashed?
If the “forgot password” flow emails you your actual password, the system must be storing it in a recoverable form rather than a one-way hash — so a database leak would expose every password. A correct design sends a one-time reset link and stores passwords hashed. This relates to A02 Cryptographic Failures.
Q5: In the NZ context, why should a security finding that exposes personal information be treated as high priority?
The Privacy Act 2020 requires reasonable security safeguards and mandatory notification of breaches likely to cause serious harm, and frameworks like the NZISM expect appropriate controls on systems handling personal or official information. So a vulnerability exposing personal data is both a technical defect and a legal exposure — document it clearly (what data, conditions, potential harm), fix it, and verify before release.
Q: Your team is testing a new “view my payments” feature on an Benefits NZ portal. Each payment record has a sequential integer ID visible in the URL. You only have one test account. What should you do before sign-off, and why?
A: Request a second test account from the development team specifically to perform an IDOR check — log in as Account A, copy a payment URL, then request it while authenticated as Account B. If Account B can see Account A’s payment data, that is an A01 Broken Access Control critical defect. Benefits NZ systems hold personal financial information; under the Privacy Act 2020 exposing another citizen’s benefit or payment history would be a notifiable breach. A single test account cannot test authorisation boundaries by definition — it only confirms you can see your own data.
Q: What is the key difference between security testing and penetration testing, and when does a functional tester’s role end?
A: Security testing by a functional tester is defensive and browser-based: checking IDOR, HTTPS, session expiry, verbose errors, and XSS with two test accounts and no specialist tools. Penetration testing is an adversarial engagement performed by a trained specialist using tools like Burp Suite to exploit vulnerabilities at a deeper technical level — exploiting chained weaknesses, fuzzing APIs, bypassing authentication mechanisms. A functional tester’s role ends where specialist tooling or offensive knowledge is needed; the handoff point is briefing the pentester on what changed since the last engagement so they focus their time on new attack surface.
Q: A developer says “we don’t need to do security testing on this sprint — it’s just an internal admin tool on a private network.” What is wrong with this reasoning and how do you respond?
A: The assumption that network location equals security is a common trap. Internal tools routinely become external-facing over time, are accessed via VPN by compromised endpoints, or are reached by insiders with malicious intent. IDOR and session bugs on an internal admin tool can expose all customer records to any logged-in staff member — not just external attackers. In a NZ context, the Privacy Act 2020 applies to internal breaches too; a staff member accessing another person’s CoverNZ claim or Revenue NZ record via an IDOR on an “internal” portal is still a notifiable privacy breach. A proportionate check — IDOR, verbose errors, session expiry — takes under 20 minutes and is always warranted when the tool touches personal information.
Q: In a job interview you are asked “how do you test session management?” What four checks should you name, and what does a bug look like for each?
A: Four checks interviewers expect: (1) Session invalidation on logout — copy the session cookie before clicking logout, then replay a request using it; a bug is a 200 response instead of 401/redirect. (2) Session expiry on inactivity — log in, leave the browser idle for 30 minutes, then perform an action; a bug is the session still being valid. (3) Session fixation — note the session ID before login and after; a bug is the ID not rotating on successful authentication. (4) Concurrent sessions — log in on two browsers simultaneously; depending on the security model, a bug may be that both sessions remain active when one should force logout. For NZ systems like RealMe-integrated portals or KiwiSaver providers, session lifetime must be proportionate to the sensitivity of the data held.
Related techniques
Practice this technique: Try Test Lead Practice 03 — Security surface.
NZ context — Privacy Act 2020 and security obligations
The New Zealand Privacy Act 2020 (effective December 2020) replaced the 1993 Act and introduced mandatory breach notification. Under the Act, organisations must notify the Privacy Commissioner and affected individuals of a privacy breach that causes or is likely to cause serious harm — within 72 hours is best practice (the Act requires “as soon as practicable”).
Key testing implications:
- Data at rest — is personal information (name, DOB, Revenue NZ number, bank account) encrypted in the database?
- Data in transit — is all PII transmitted over HTTPS?
- Right to access and correction — can users view and correct their personal data?
- Data minimisation — is the system collecting only what it needs?
- Retention — does the system delete data when it’s no longer needed?
For security testing in a NZ context, OWASP Top 10 remains the technical baseline, but compliance with the Privacy Act adds the legal requirement. A SQL injection vulnerability that exposes customer records is both a technical security failure AND a Privacy Act breach notifiable to the Privacy Commissioner.
Testers working on NZ government or health systems also need to be aware of the Health Information Privacy Code 2020, which has stricter rules for health data.
9 OWASP Top 10 — NZ Context
The table below maps each OWASP Top 10 entry to a realistic NZ government or enterprise scenario, with the defensive check a functional tester can run without specialist tools.
| Rank | Vulnerability | NZ example | How to test (defensively) |
|---|---|---|---|
| A01 | Broken Access Control | Benefits NZ case worker accessing another worker’s client records by changing a case ID in the URL | Log in as Worker A. Request a record belonging to Worker B by changing the ID. Expect a 403 — any data returned is a critical bug. |
| A02 | Cryptographic Failures | HealthNZ system logging NHI numbers in plain-text application logs accessible to all devs | Check log files for PII. Verify all pages load over HTTPS. Check TLS version in DevTools (Security tab) — TLS 1.0/1.1 is a finding. |
| A03 | Injection | Revenue NZ search bar accepting raw SQL, returning internal database errors on malformed input | Enter SQL payloads such as ' or 1=1-- in search and form fields and observe the response. Use authorised scanning tools (OWASP ZAP) for broader coverage. |
| A04 | Insecure Design | KiwiSaver provider portal with no limit on login attempts, making credential-stuffing attacks trivial | Raise during design review and threat modelling — not something you can patch after the fact. Check: is there a rate limit on login? Is MFA available on high-value accounts? |
| A05 | Security Misconfiguration | AWS S3 bucket containing NZDF tender documents left publicly readable due to a default permission oversight | Check HTTP response headers in DevTools (Network tab): are X-Frame-Options, Content-Security-Policy, and Strict-Transport-Security present? Try /phpmyadmin and common admin paths. Check for directory listing. |
| A06 | Vulnerable Components | A NZ SaaS platform running an npm package with a known critical CVE unpublicised for months | Run npm audit or OWASP Dependency-Check in CI. Flag any High or Critical CVEs on packages the application uses in production. |
| A07 | Auth and Session Failures | RealMe-integrated portal where the session token is not invalidated on logout, so a copied token still grants access | Log in. Copy the session cookie. Log out. Replay a request using the copied cookie — a 200 response means the session was not invalidated server-side. Also test idle-timeout. |
| A08 | Software and Data Integrity Failures | CI/CD pipeline pulling npm packages without a lock file, allowing a dependency substitution attack | Verify package-lock.json or yarn.lock is committed and used in CI. Check that third-party scripts loaded from CDNs use Subresource Integrity (SRI) hashes. Review CI/CD pipeline integrity controls. |
| A09 | Logging and Monitoring Failures | A NZ health system breach was discovered weeks after it occurred because no alerts were configured for abnormal access patterns | Trigger known attack patterns (e.g. repeated failed logins, IDOR attempts) and verify that alerts fire and log entries are created. Confirm admin actions are audited with timestamps and user identity. |
| A10 | Server-Side Request Forgery (SSRF) | A document preview feature that fetches any URL provided by the user, allowing an attacker to probe internal services | Submit internal IP addresses (e.g. http://169.254.169.254/, http://localhost/) or internal hostnames as URL inputs. A response that differs from external URLs indicates SSRF risk. |
10 Security Testing Workflow for QA Engineers
Security testing is not a single activity — it is a repeatable process. Follow these steps in order whenever a feature touches personal data, authentication, or user-supplied input.
- Get written authorisation. Never test security without explicit written permission. The scope must be defined: which environments, which endpoints, which test accounts. Without this, testing is unauthorised access — even with good intent. This applies even on your own organisation’s systems.
- Passive reconnaissance. Map the public-facing attack surface before touching any inputs. Inspect HTTP response headers (look for security headers or their absence), read error messages on obvious bad requests, review any exposed API documentation. This costs nothing and informs everything that follows.
- Input validation testing. Work through every input field and parameter: try XSS payloads (
<script>alert(1)</script>), SQL injection probes (',1=1--), path traversal strings (../../../etc/passwd), and oversized inputs. Observe whether inputs are reflected unencoded or cause error messages with implementation detail. - Auth and session testing. Attempt login bypass (empty credentials, SQL in username). Check for session fixation (does the session ID change after successful login?). Test token predictability (are session IDs sequential or guessable?). Confirm sessions expire after inactivity and are invalidated server-side on logout.
- Access control testing. Test horizontal escalation: as User A, request User B’s data by changing record IDs (IDOR). Test vertical escalation: as a standard user, attempt to reach admin-only URLs and functions. Every endpoint that returns or modifies data needs both checks.
- Evidence capture. Screenshot every finding. Capture the full HTTP request and response (from DevTools Network tab or a proxy). Record the exact steps to reproduce. Vague security bugs get deprioritised — precise evidence with request/response pairs gets fixed.
- Responsible disclosure. Log every finding in the defect tracker immediately with severity, reproduction steps, and what data was exposed. Share with the development lead and, if personal data is involved, flag to your privacy or security officer. Do not share details externally, post on social media, or discuss outside the team until the issue is resolved and sign-off given.
Security testing is NOT penetration testing. QA engineers test defensively in authorised systems — using browsers, test accounts, and a checklist. Penetration testing is an adversarial engagement performed by a trained specialist who actively exploits vulnerabilities using purpose-built tools. The two complement each other: defensive testing catches the common issues early; a pentest finds what remains. For a full penetration test in NZ, engage a specialist — look for CHECK-certified testers or organisations accredited through CREST NZ.
↑ Go Deeper
This technique is foundational. Once you understand it, these specialised tracks take you into real-world depth: