Skip to content
QA Knowledge Hub

Security testing basics: interview questions for testers

Updated 2026-11-13 · 17 min read

Thirty security testing questions a functional or automation tester is expected to handle, with answers that stay practical: what to check, how to check it safely, and how to report it. The API checks run against the free ShopLite app.

Most QA roles do not expect you to be a penetration tester. They do expect you to catch the security defects that sit inside ordinary features: a user who can open someone else's order, an OTP that can be guessed, a token that still works after logout, an error page that prints a stack trace. This page covers what interviewers ask testers about security, with checks you can run against the free ShopLite practice app on your own machine.

The basics

1. What is security testing, and what is a tester's part in it?

Testing that the system protects data and functions from people who should not have them, and keeps working when someone sends hostile input. A functional tester's part: include negative and abuse cases in normal test design (other users' ids, missing tokens, tampered values, very long input), run basic checks in API suites, and raise anything suspicious with the security team. Deep testing (penetration tests, code audits) is usually done by specialists.

2. What is the CIA triad?

Confidentiality (only the right people can see data), Integrity (data cannot be changed without permission, or changes are detected), and Availability (the service works when needed). Most security defects break one of them: seeing another customer's statement breaks confidentiality, changing the price in a request breaks integrity, and a request that crashes the server breaks availability.

3. What is the difference between a vulnerability, a threat and a risk?

A vulnerability is a weakness (the order API does not check who owns the order). A threat is someone or something that could use it (a logged-in customer who changes the id in the URL). Risk combines how likely that is and how bad the result would be. Testers find vulnerabilities; the team decides priority by risk.

4. What is the OWASP Top 10? Name a few items.

A list, published by the OWASP foundation, of the most important web application security risk categories, updated every few years. The 2025 edition starts with A01 Broken Access Control, then Security Misconfiguration, Software Supply Chain Failures, Cryptographic Failures and Injection, and ends with A10 Mishandling of Exceptional Conditions. It is an awareness document, not a test plan, but it is a good checklist of where to look. Say which edition you are quoting, because many courses still teach the 2021 list.

5. What are SAST, DAST, SCA and penetration testing?

SAST (static application security testing) scans source code without running it. DAST (dynamic) attacks the running application from outside, as a scanner would. SCA (software composition analysis) checks third-party libraries for known vulnerabilities. Penetration testing is a person, or a team, trying to break in with skill and creativity, usually against an agreed scope. Teams combine them: SAST and SCA on every commit, DAST on a test environment, a pen test before big releases.

6. How is vulnerability scanning different from penetration testing?

A scanner runs known checks automatically and reports possible issues, including false positives that someone must confirm. A penetration tester chains small weaknesses into a real attack, such as using an information leak to guess an id and then an access-control gap to read the data. Scans are cheap and frequent; pen tests are deeper, slower and need a defined scope and permission.

7. What is the difference between authentication and authorization?

Authentication proves who you are (password, OTP, fingerprint). Authorization decides what you are allowed to do once known (a customer may view their own orders, an admin may refund). Many serious bugs are authorization bugs in apps whose login works perfectly. There is a full comparison in authentication vs authorization.

Testing web apps and APIs

8. How do you test for broken access control?

Use two accounts of the same role and one of a lower role. With user A's session, try to read, change or delete user B's objects by changing ids in URLs, query strings and request bodies (this kind of bug is often called IDOR, insecure direct object reference). Then try admin-only actions with a normal user, and every protected endpoint with no token. A script that does these checks against ShopLite:

// Run with: node access-checks.mjs   (Node 18+; ShopLite on http://localhost:3001)
import assert from "node:assert/strict";

const BASE = process.env.BASE_URL ?? "http://localhost:3001";

async function call(method, path, { token, body } = {}) {
  const res = await fetch(BASE + path, {
    method,
    headers: {
      "content-type": "application/json",
      ...(token ? { authorization: `Bearer ${token}` } : {}),
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  const text = await res.text();
  return { status: res.status, json: text ? JSON.parse(text) : null };
}

async function login(email, password) {
  const res = await call("POST", "/api/auth/login", { body: { email, password } });
  assert.equal(res.status, 200, `login as ${email}`);
  return res.json.token;
}

await call("POST", "/api/_reset");
const asha = await login("[email protected]", "Demo@1234");
const ravi = await login("[email protected]", "Second@123");

// Asha places an order.
await call("POST", "/api/cart/items", { token: asha, body: { productId: 2, qty: 1 } });
const order = await call("POST", "/api/orders", {
  token: asha,
  body: {
    address: { line1: "12 MG Road", city: "Pune", pincode: "411001", phone: "9000000001" },
    paymentMethod: "upi",
  },
});
assert.equal(order.status, 201);

// 1. No token: the order must not be readable.
assert.equal((await call("GET", `/api/orders/${order.json.id}`)).status, 401);

// 2. Another signed-in user must not read it either (403 or 404 are both acceptable designs).
const peek = await call("GET", `/api/orders/${order.json.id}`, { token: ravi });
assert.ok([403, 404].includes(peek.status), `Ravi read Asha's order: ${peek.status}`);

// 3. The profile must not leak secrets.
const me = await call("GET", "/api/me", { token: asha });
for (const key of Object.keys(me.json)) assert.doesNotMatch(key, /password|hash|token/i, `profile exposes ${key}`);

// 4. After logout the old token must stop working.
await call("POST", "/api/auth/logout", { token: asha });
assert.equal((await call("GET", "/api/me", { token: asha })).status, 401);

console.log("all access checks passed");

Against ShopLite's fixed build (BUGS=none npm start) it prints all access checks passed (run on Node 24). Run it against the default build with bugs switched on and see what it finds.

Likely follow-up: Should the API answer 403 or 404 when you ask for someone else's order? Both are defensible. 404 hides whether the order exists; 403 is more honest about the reason. What matters is that the data is not returned and the behaviour is consistent.

9. What is SQL injection, and how does a tester check for it?

It happens when user input is pasted into a SQL statement, so the input can change the query itself. A tester tries input containing quote characters and SQL fragments (a single ', or ' OR '1'='1) in search boxes, login fields, filters and API parameters, and watches for database errors, different result counts, or a login that succeeds without the right password. The fix is parameterised queries, never string building. In an authorised test environment, scanners and tools like sqlmap go further; on a shared environment, ask first because some payloads change data.

10. What is cross-site scripting (XSS), and what are its types?

Untrusted input ends up in a page as executable script. Stored XSS: the payload is saved (a product review, a profile name) and runs for every viewer. Reflected XSS: the payload comes back in the response to the same request (a search term echoed on the results page). DOM-based XSS: client-side JavaScript writes the input into the page unsafely. A tester enters harmless markers such as <b>x</b> or "><img src=x onerror=alert(1)> and checks whether they render as markup or appear as text. Output encoding, a Content-Security-Policy and avoiding unsafe DOM writes are the defences.

11. What is CSRF, and how do cookies affect it?

Cross-site request forgery tricks a signed-in user's browser into sending a request to your site from another site, carrying the user's cookies, for example a hidden form that changes their email. It matters for apps that use cookie sessions. Defences are anti-CSRF tokens on state-changing requests and the cookie SameSite attribute. Apps that send a bearer token in a header (not a cookie) are not exposed in the same way, which is a nice point to make in an interview.

12. What do you check in session management?

The session id or token changes after login (so a token set before login cannot be reused), logout makes the old token unusable on the server (not just deleted from the browser), sessions expire after inactivity and after an absolute time, tokens never appear in URLs or logs, and changing the password ends other sessions where the requirements say so. Check 4 in the script above covers the logout case.

13. What security tests would you run on a login page?

Error messages that do not reveal whether the email exists ("email or password is incorrect" rather than "no such user"); lockout or rate limiting after repeated failures; no password in the URL, logs or responses; passwords sent only over HTTPS; the same response time and message for known and unknown users where practical; and the forgot-password flow not leaking accounts either. A quick automated check for the lockout part:

const BASE = process.env.BASE_URL ?? "http://localhost:3001";
const statuses = [];
for (let i = 0; i < 10; i++) {
  const res = await fetch(`${BASE}/api/auth/login`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ email: "[email protected]", password: `Wrong@${i}000` }),
  });
  statuses.push(res.status);
}
console.log(statuses.join(" "));
if (!statuses.includes(429)) {
  console.error("no lockout or rate limit after 10 wrong passwords");
  process.exit(1);
}

Against the fixed ShopLite build it prints 401 401 401 401 401 429 429 429 429 429. The right threshold and status code come from your requirements; reset the app or account afterwards. The login page test cases list the functional side.

14. How do you security-test OTP verification?

Check that an OTP expires (try it after the stated validity), works only once, is tied to the phone number and the action it was sent for, is limited in attempts (otherwise a six-digit code can be brute-forced), and that resending is rate-limited so nobody can flood a user with SMS. Also check that the OTP is not returned in the API response or visible in the browser's network tab, which happens more often than you would expect in test builds that reach production. See the OTP verification test cases.

HttpOnly stops page JavaScript from reading the cookie, which limits the damage of XSS. Secure sends it only over HTTPS. SameSite controls whether it goes with cross-site requests: Strict (same site only), Lax (also top-level navigations with safe methods such as following a link), or None (always, and it must then also be Secure). Some browsers treat a cookie without SameSite as Lax, but not all, so a session cookie should set it explicitly. Check them in the browser's developer tools under the Application or Storage tab.

16. Which security headers do you check, and how?

Content-Security-Policy (limits where scripts and other resources may load from), Strict-Transport-Security (tells browsers to use HTTPS only; meaningful on HTTPS responses), X-Content-Type-Options: nosniff, a Referrer-Policy, and protection against being framed by other sites (frame-ancestors in the CSP, or the older X-Frame-Options). A small script makes the check repeatable:

const url = process.argv[2] ?? "http://localhost:3001/";
const res = await fetch(url);
const wanted = ["content-security-policy", "strict-transport-security", "x-content-type-options", "referrer-policy"];
for (const name of wanted) console.log(`${res.headers.has(name) ? "present" : "MISSING"}  ${name}`);
console.log(`set-cookie: ${res.headers.get("set-cookie") ?? "(none on this response)"}`);

Missing headers are configuration findings, not proof of an exploitable bug; report them with the page and the header, and let the team decide.

17. What do you check about HTTPS?

That every page and API is served over HTTPS, HTTP redirects to HTTPS, certificates are valid and not expired, there is no mixed content (an HTTPS page loading scripts over HTTP), and test tools are not quietly configured to ignore certificate errors in the pipeline that tests production-like environments. For certificate errors you meet while testing, see SSL handshake errors in API tests.

18. How would you find sensitive data exposure?

Read full API responses, not just the fields the UI shows: password hashes, internal ids, other users' emails, full card or Aadhaar numbers, or OTPs in a response are defects even when the screen hides them. Also check logs, error messages, browser storage (local storage holding tokens or personal data), URLs (which end up in browser history and server logs) and downloaded files. Check 3 in the script in question 8 is a simple automated version.

19. How do you test file upload securely?

Try files that do not match the allowed types (an .html or .svg file renamed to .jpg), files larger than the limit, empty files, very long and odd file names (../../x.jpg, names with quotes), and check where the file is served from: it should not execute as code or render as a page on the main domain. Check that one user cannot fetch another user's uploads by guessing the URL. The file upload test cases include more.

20. Why is client-side validation not enough?

Because anyone can bypass the browser and call the API directly with Postman, curl or a script. Client-side checks are for user experience; the server must validate everything again. A standard tester move: find a field the form restricts (quantity 1 to 10, a disabled price field) and send the out-of-range or changed value straight to the API.

21. What would you test in a JWT-based API?

That tokens expire (the exp claim is honoured), a token with a changed payload (role edited from user to admin) is rejected because the signature no longer matches, a token signed with no algorithm or the wrong key is rejected, and that no secrets sit in the payload (it is only encoded, not encrypted, so anyone can read it). Also check what happens on logout, since a stateless JWT stays valid until it expires unless the server keeps a revocation list.

Likely follow-up: How do you read a JWT? Split it at the dots and Base64URL-decode the first two parts; the third is the signature. Never paste production tokens into public websites to decode them.

22. What is CORS, and is a CORS error a security bug?

CORS is how a browser decides whether a script on one origin may read a response from another. A CORS error in your browser console is usually a configuration issue, not a vulnerability. The security bug is the opposite: an API that returns Access-Control-Allow-Origin echoing any origin together with credentials allowed, so any website can read a signed-in user's data. More in CORS errors explained for testers.

23. How do you test rate limiting?

Send a burst of requests to sensitive endpoints (login, OTP send, password reset, coupon apply, search) and check that the service starts refusing, usually with status 429 and ideally a Retry-After header, and that the limit is per user or per client as designed. Do this only in a test environment and agree on it first, because it looks like an attack and can affect shared environments.

24. Why do error messages matter for security?

Detailed errors (stack traces, SQL statements, framework versions, internal paths) tell an attacker how the system is built, and unhandled errors can leave things half-done or "fail open". The 2025 OWASP list has a category for mishandling exceptional conditions. Testers check that errors are generic for users, detailed only in server logs, and that a failure (payment gateway timeout, database down) leaves the system in a safe state, such as an order marked unpaid, not confirmed.

25. What is dependency or supply-chain risk, and how do testers help?

Most apps are built from third-party packages, and a known vulnerability in one of them is a vulnerability in your app. Teams run dependency scanners in CI (for Node projects npm audit is the built-in starting point; other ecosystems have their own) and act on the results. Testers can make sure the scan runs, its results are visible, and test tools themselves (browser drivers, plugins) come from trusted sources.

Tools and process

26. Which security tools should a QA tester know?

A proxy that sits between browser and server so you can see and change requests: Burp Suite (commercial, with a free Community edition) and ZAP (open source) are the usual ones, and ZAP can also run automated scans. Browser developer tools for cookies, storage and network traffic. Postman or code for API abuse cases. Dependency scanners for libraries. Knowing what each is for matters more than knowing every feature.

27. How would you add security checks to a CI pipeline?

Fast checks on every pull request: dependency scanning, secret scanning (no keys committed), static analysis, and your own API tests that cover access control and auth. Slower checks on a schedule against a test environment: an automated DAST scan. Fail the build on high-severity findings and track the rest, otherwise the report becomes noise everyone ignores. The CI/CD questions cover pipelines in general.

28. You find that one customer can see another customer's orders. What do you do?

Stop at proof: record one request and response showing the problem with test accounts, and do not keep reading more data than needed. Report it straight away through the agreed private channel (a restricted security ticket, not a public channel), with steps, the accounts used, and the impact in plain words ("any signed-in user can read any order, including address and phone"). Mark it critical. Then add an automated check like question 8 so it cannot come back.

29. How do you decide the severity of a security bug?

Think about what an attacker gains, how easy it is, and how many users it touches. Reading or changing other users' data, taking over accounts, or paying less than the price are critical. Missing headers or verbose version strings are usually low on their own. Many teams use a scoring system such as CVSS or an internal matrix; use your team's, and explain the impact rather than just quoting a score.

30. You have 30 minutes to security-test a new "update profile" API. What do you check?

Can I update another user's profile by changing the id? Can I set fields I should not, such as role, isVerified or walletBalance, by adding them to the request body (mass assignment)? Is input validated on the server (length, format, script tags in the name)? Does a missing or expired token get 401? Does the response leak fields it should not? Does changing the email or phone require re-verification? Those six checks catch most real defects in this kind of endpoint.

Check yourself

  1. A logged-in user changes /api/orders/41 to /api/orders/42 and sees someone else's order. Which OWASP 2025 category is that?
  2. Which cookie attribute stops page JavaScript from reading a session cookie?
  3. Why is a JWT payload not a safe place for a secret?
  4. A form allows quantity 1 to 10. How do you check the server enforces it?
  5. What status code usually signals that a rate limit was hit?

Answers. (1) A01 Broken Access Control. (2) HttpOnly. (3) It is only Base64URL-encoded, so anyone holding the token can read it. (4) Send 0, 11 and -1 directly to the API, bypassing the form, and expect a 400-range error. (5) 429 Too Many Requests.

Practise it

Start the free ShopLite app locally, run the script from question 8 against the fixed build and then the default build, and write up anything it finds with the bug report template. The README says which areas have planted bugs, including authentication and access control.

Quick answers

Do QA testers need to know penetration testing?

Not for most QA roles. Interviewers expect you to know the common weaknesses, include basic security checks in your functional and API tests, and recognise when to involve a security specialist. Penetration testing is a separate skill and needs written authorisation.

Which OWASP Top 10 should I quote in an interview?

The current list at owasp.org is the 2025 edition, which starts with Broken Access Control. Many teams and courses still use the 2021 list; say which edition you mean.

Is it legal to try SQL injection on a website?

Only on systems you are explicitly authorised to test, such as your employer's test environment or a practice app on your own machine. Testing other people's sites without permission can be a crime.

Sources

Want a project you can show in interviews?

The portfolio project kit walks you through testing a deliberately buggy app with Selenium or Playwright and API tests, then explaining it. The app itself is free.