Security Testing Basics
Security bugs are not exotic. They are everywhere. Learn to spot SQL injection, XSS, broken authentication, and exposed data — without tools, just careful manual testing.
The Hook — The Data Breach Nobody Tested
A NZ healthcare provider launched a patient portal. A tester noticed that changing the URL from /patient/123 to /patient/124 showed another patient's medical records. No authentication check. The team said "that's a bug for the developer." The security team didn't catch it. It shipped. Within weeks, a journalist logged in as patient 1, downloaded all 50,000 patient records, and published them. The story made national news.
This is not a rare exploit. This is an access control bug — one of the OWASP Top 10 most common security failures. A QA tester would have found it in 30 seconds by changing a URL parameter.
The Rule
Security testing is investigating whether the app protects user data, prevents unauthorized access, and resists common attacks. You are testing like an attacker, not like a user following happy-path workflows.
A security tester asks: "What if I do the wrong thing? What if I cheat? What happens?"
- What if I submit SQL instead of a username?
- What if I change a URL parameter to access someone else's data?
- What if I put a script tag in a comment?
- What if I try to log in as admin with a blank password?
- What if I intercept the request and modify the price before sending it?
OWASP Top 3 Vulnerabilities (for Testers)
1. Broken Access Control (IDOR)
What it is: Users can access data they shouldn't. Changing a URL ID or parameter reveals another user's information.
Example: /profile/123 shows your profile. Change it to /profile/999 and see someone else's.
How to test:
- Log in as user A. View your profile URL:
/profile/123 - Log in as user B in a different browser or incognito tab. Note their profile URL:
/profile/456 - Go back to user A's browser. Manually change the URL to
/profile/456 - If you see user B's profile, that's a critical bug. This is IDOR (Insecure Direct Object Reference)
NZ impact: If a banking app has IDOR, attackers can see all account balances for all customers by looping through user IDs.
2. SQL Injection
What it is: Submitting SQL code in a form field tricks the database into executing malicious queries.
Example: Username field says "Enter your username." You type: admin' --
This can bypass login: the SQL becomes SELECT * FROM users WHERE username='admin'--' (the -- comments out the password check).
How to test:
- Find any form input: login, search, feedback, etc.
- Try injecting SQL keywords:
' OR '1'='1 - Try comment syntax:
admin' -- - Try union queries:
' UNION SELECT username, password FROM users -- - If the app returns unexpected data or errors, you may have found SQL injection
Signs of vulnerability: Database error messages visible to the user, unexpected data returned, login bypassed.
3. Cross-Site Scripting (XSS)
What it is: Injecting JavaScript code into the app so it runs in other users' browsers.
Example: A comment field accepts <script>alert('hacked')</script>. When another user views the comment, the script runs.
How to test:
- Find any user input field: comment, profile, bio, feedback, etc.
- Try entering HTML tags:
<h1>test</h1> - Try JavaScript:
<script>alert('XSS')</script> - Try img tags:
<img src=x onerror="alert('XSS')"> - Submit the input and reload the page
- If the HTML/JavaScript renders instead of being escaped, that's XSS
Impact: An attacker can steal session cookies, redirect users, or phish for passwords.
Security Testing Checklist
Authentication & Access
- ☐ Can I log in with a blank username and password?
- ☐ Can I reset someone else's password knowing only their email?
- ☐ If I change the URL ID (e.g., /user/123 → /user/999), can I see another user's data?
- ☐ Can I remain logged in after changing my own password?
- ☐ Can I access admin pages if I'm logged in as a regular user?
Data Exposure
- ☐ Are passwords stored in plain text in the form? (Check HTML source)
- ☐ Are API responses unencrypted? (Check Network tab)
- ☐ Are sensitive fields (email, SSN, card number) visible in URLs or form hidden fields?
- ☐ Does the page cache sensitive data? (Check browser cache)
Input Validation
- ☐ Can I submit SQL keywords:
' OR '1'='1 - ☐ Can I submit HTML tags:
<h1> - ☐ Can I submit JavaScript:
<script> - ☐ Can I submit very long strings (buffer overflow)?
- ☐ Can I submit special characters:
; : \ / " ' --
Using DevTools to Spot Bugs
Check the HTML source (Ctrl+U or right-click → View Page Source):
- Look for
<input type="password" value="mypassword">— password hardcoded in HTML. Critical bug. - Look for
<input type="hidden" name="price" value="100">— price hardcoded. An attacker can change it. - Look for comments with secrets:
<!-- TODO: remove test admin account -->
Check the Network tab (F12 → Network):
- Click a request and check the Response tab. Is sensitive data visible in plain text?
- Check if the connection is HTTPS (secure) or HTTP (unencrypted). Never HTTP for login.
- Look at the URL parameters. Is the API key visible?
/api/data?key=abc123is exposed.
Common Mistakes
❌ Only Testing the Happy Path
Security bugs only appear when you try to break the app. A tester who only tests valid inputs will never find SQL injection or access control bugs.
❌ Assuming the App Validates Because You Tested One Field
Just because the login field validates doesn't mean the comment field does. Test every input field independently.
❌ Not Checking URLs and Hidden Fields
Some of the easiest bugs to find: change a URL ID, or inspect a hidden form field that contains the price. Don't just test visible inputs.
❌ Not Reporting Security Bugs
If you find a security bug, report it immediately and privately. Do not post it on social media or tell colleagues casually. Notify the security team directly.
Senior engineer insight
The shift that changed everything for me was treating access control like a different user's eyes, not just a different role. I started every IDOR test by opening two browser sessions side by side — one as user A, one as user B — and then deliberately doing user B's actions from user A's session. In a NZ government portal project, this revealed that a logged-in citizen could pull any other citizen's pending consent documents just by guessing sequential IDs. It was live for six months and the dev team had no idea because automated tests only ran as the same user.
Most common mistake: Grad testers test whether an unauthenticated user can access a page, but forget to test whether an authenticated user with the wrong account can access another authenticated user's data — that's where the real IDOR bugs hide.
From the field
A NZ health sector client was rushing a provider portal to meet a Ministry of Health go-live date. The team assumed their ORM (object-relational mapper) handled SQL injection automatically — it did for most queries, but a single raw SQL string was used for a legacy report export. During exploratory security testing, a tester entered a single quote in the date-range filter and got a database stack trace back in the browser, including the table name and column names. That trace gave enough information to craft a union injection that could extract provider email addresses and Revenue NZ numbers from the same database.
The fix took an afternoon. The NZ Privacy Act 2020 exposure — had it been exploited — would have triggered mandatory breach notification to the Privacy Commissioner and potentially affected 4,000 registered providers. The lesson: never assume your framework handles all injection paths; test every input field in every form, including filters and exports that testers normally skip because they "just generate reports."
Why teams fail here
- They scope security testing to a dedicated "security sprint" at the end, so IDOR and injection bugs in features built months earlier are never re-checked after the original developer leaves.
- They assume HTTPS means "secure" — encryption in transit says nothing about what data the server is leaking, who can access it, or whether inputs are sanitised on the backend.
- They rely on a penetration test report from twelve months ago and treat it as current assurance, not realising new features shipped since then have introduced fresh attack surface.
- Grad testers report security bugs through the normal bug tracker without flagging severity — a critical IDOR sits in a backlog column labelled "nice to have" for three sprints until it ships to production.
Key takeaway
Security testing is not a specialisation you grow into — it is the habit of asking "what happens if I lie to this system?" on every feature, every sprint, before anyone else has to answer that question in court.
Interview Questions
What NZ hiring managers ask about Security Testing Basics at the Grad level.
Q1. What is SQL injection, and how would you test a login form for it?
Strong answer: SQL injection is when an attacker inserts SQL code into a user input field, and the database executes it. On a login form I would try inputs like: ' OR '1'='1 in the username or password field. If the application is vulnerable, this might log me in without a valid password by making the SQL query always return true. I would also try: ' OR 1=1--, admin'-- , and other common payloads. A secure application should sanitise inputs and use parameterised queries — the test input should be treated as data, not SQL.
Q2. What is the difference between authentication and authorisation?
Strong answer: Authentication verifies who you are — logging in with a username and password, or MFA. Authorisation determines what you are allowed to do — which pages, data, and actions your account has permission to access. A common security bug is broken authorisation: you are authenticated correctly (you are who you say you are) but you can access resources you should not be allowed to see. Testing: log in as a standard user, then try to access admin-only URLs directly. If you reach them, authorisation is broken.
Q3. Why should you never log sensitive data like passwords or credit card numbers?
Strong answer: Logs are often stored less securely than the main database — they may be accessible to more people, sent to third-party log aggregators, stored indefinitely, or inadvertently shared in support tickets. Sensitive data in logs violates NZ Privacy Act 2020 (IPP 5 — data must be stored securely with access controls appropriate to its sensitivity). If logs are ever breached, exposed, or accidentally shared, sensitive data in them causes a privacy breach. As a tester, I check that test runs do not produce logs containing personal data, credentials, or payment card information.
Self-Check
- You notice the URL shows /customer/789. You change it to /customer/790 and see another customer's data. What is this called?
IDOR (Insecure Direct Object Reference). It's broken access control. Critical security bug. - In a search box, you try entering: ' OR '1'='1. The search returns all records. What happened?
SQL injection. The input was not escaped, so your SQL was executed directly on the database. Critical bug. - In a comment field, you post: <script>alert('hack')</script>. Every user who views the comment sees the alert. What is this?
Cross-Site Scripting (XSS). The script runs in every user's browser. Critical bug. - You find the login form has a hidden field: <input type="hidden" name="role" value="admin">. Is this a security issue?
Yes. An attacker can change the value to "admin" before submitting, potentially gaining unauthorized access. - The page loads over HTTP (not HTTPS). Is this a security issue?
Yes. All data sent over HTTP is unencrypted. Anyone on the network can intercept passwords and session tokens.