Security Testing: A Comprehensive QA Guide

Feb 2026 Nirajan Bohara 12 min read

Introduction

In an era where data breaches cost companies millions of dollars and damage brand reputation irreparably, security testing has become integral to quality assurance. As a QA engineer, understanding security vulnerabilities and how to test for them is no longer optional—it's essential.

This comprehensive guide covers the critical aspects of security testing, from understanding common vulnerabilities to implementing practical testing strategies that protect your applications from threats.

Important Note

Always ensure you have proper authorization before conducting security testing. Unauthorized security testing is illegal. Test only on systems you own or have explicit written permission to test.

What is Security Testing?

Security testing is the process of identifying vulnerabilities, weaknesses, and threats in a system to ensure data confidentiality, integrity, and availability. Unlike functional testing that focuses on "does it work?", security testing asks "can someone break it?" and "how can they misuse it?"

The OWASP Top 10: Critical Vulnerabilities

The Open Web Application Security Project (OWASP) maintains a list of the top 10 most critical web application security risks. Understanding these is fundamental for any QA professional.

1. Broken Access Control

What it is:

Broken access control occurs when users can access resources or perform actions they shouldn't have permission to do.

How to test:

  • Try accessing user resources of other users (IDOR - Insecure Direct Object Reference)
  • Attempt to access admin pages as a regular user
  • Change user IDs in URLs to see if you can view other accounts
  • Test role-based access controls (RBAC)

Example:

// Vulnerable: User 123 accesses user 456 profile // Original URL: /api/users/123 // Attacker tries: /api/users/456 // If successful, attacker can view/modify another user's data

2. Cryptographic Failures

What it is:

Sensitive data exposure due to weak encryption, improper use of cryptographic algorithms, or unencrypted data transmission.

How to test:

  • Check if sensitive data (passwords, tokens) is transmitted over HTTPS
  • Look for hardcoded credentials in code or configuration files
  • Test if passwords are properly hashed (not plain text in database)
  • Verify strong encryption algorithms are used (AES-256, not MD5)

Testing Approach:

// Test 1: Check for HTTPS // Use browser dev tools to verify all requests use https:// // Test 2: Check password storage // Database inspection should never reveal plain text passwords // Passwords should be hashed with bcrypt, PBKDF2, or Argon2 // Test 3: Verify strong SSL/TLS // Use nmap or testssl.sh to verify TLS version nmap --script ssl-enum-ciphers example.com

3. Injection (SQL Injection, Command Injection)

What it is:

Injection attacks occur when unvalidated input is sent to an interpreter as part of a command or query.

How to test:

  • Test form fields with SQL keywords ('; DROP TABLE users; --)
  • Try command injection payloads (ls, whoami, etc.)
  • Test search boxes for injection vulnerabilities
  • Use parameterized queries in your code

SQL Injection Example:

// Vulnerable query const query = "SELECT * FROM users WHERE username = '" + username + "'"; // Attack payload in username field: ' OR '1'='1 // Resulting query executes as: SELECT * FROM users WHERE username = '' OR '1'='1'; // This returns ALL users! // Safe approach using parameterized query: const query = "SELECT * FROM users WHERE username = ?"; db.query(query, [username]);

4. Insecure Design

What it is:

Missing or ineffective design controls during the application design phase, including business logic flaws.

How to test:

  • Test password reset functionality (can you reset another user's password?)
  • Try manipulating business logic (e.g., changing price before checkout)
  • Test rate limiting on login attempts
  • Check for authorization bypass on critical functions

Real-world Example:

// Scenario: E-commerce discount bypass // Vulnerable code checks discount AFTER price calculation: const price = item.price; const finalPrice = price - discount; // User might manipulate discount // Fix: Validate discount on server, never trust client input const discount = validateDiscountCode(code); // Server-side validation const finalPrice = price - discount;

5. Security Misconfiguration

What it is:

Insecure default configurations, incomplete setups, unpatched systems, and exposed sensitive files.

How to test:

  • Check for debug mode enabled in production
  • Look for default credentials (admin/admin)
  • Try accessing .git, .env, config files
  • Check server headers for version disclosure
  • Test directory listing (should be disabled)

Tools & Techniques:

// Check server headers curl -I https://example.com // Look for: Server: Apache/2.4.41, X-Powered-By: PHP/7.4.3 // These disclose software versions // Check for common files /admin /.git /.env /config.php /web.config /.htaccess

6. Vulnerable and Outdated Components

What it is:

Using libraries, frameworks, and components with known vulnerabilities.

How to test:

  • Identify all third-party libraries and their versions
  • Use tools like OWASP Dependency-Check
  • Run npm audit or composer audit
  • Check for outdated packages with known CVEs
// Check for vulnerable dependencies npm audit // Check composer packages composer audit // Use OWASP Dependency-Check dependency-check --scan ./node_modules

7. Authentication & Session Management Flaws

What it is:

Weak authentication mechanisms, session token exposure, or session handling vulnerabilities.

How to test:

  • Attempt brute force on login (check for rate limiting)
  • Test password reset links (are they guessable?)
  • Check session tokens in browser storage (avoid localStorage for sensitive data)
  • Test session timeout functionality
  • Verify tokens are invalidated on logout

Testing Checklist:

// 1. Check token storage // DON'T use localStorage for tokens localStorage.setItem('token', jwt); // VULNERABLE // DO use httpOnly cookies response.cookie('token', jwt, { httpOnly: true, secure: true, sameSite: 'strict' }); // 2. Check token expiration // JWT should have short expiration (15 minutes) const token = jwt.sign(payload, secret, { expiresIn: '15m' }); // 3. Test logout // Tokens should be invalidated on logout

8. Software and Data Integrity Failures

What it is:

Lack of integrity checks for software and data, leading to unauthorized modifications.

How to test:

  • Verify digital signatures on downloads
  • Check data integrity with checksums/hashes
  • Intercept API responses to see if they're validated
  • Test for man-in-the-middle attack possibilities

9. Logging & Monitoring Failures

What it is:

Insufficient logging and monitoring of security events, making breach detection difficult.

How to test:

  • Check if failed login attempts are logged
  • Verify suspicious activities trigger alerts
  • Test if logs cannot be tampered with
  • Ensure logs contain sufficient details for forensics

10. Server-Side Request Forgery (SSRF)

What it is:

Attacker tricks the server into making unintended requests to internal resources.

How to test:

  • Test URL parameters for SSRF (try localhost, 127.0.0.1)
  • Attempt to access internal IP ranges (10.0.0.0/8, 172.16.0.0/12)
  • Try accessing cloud metadata endpoints (AWS, GCP, Azure)
// Vulnerable code that fetches URL from user input app.get('/fetch-url', (req, res) => { const url = req.query.url; fetch(url).then(r => res.send(r)); // VULNERABLE! }); // Attacker payload: // /fetch-url?url=http://localhost:8080/admin // /fetch-url?url=http://169.254.169.254/latest/meta-data/ // Fix: Whitelist allowed domains const allowedDomains = ['example.com', 'api.example.com']; const url = new URL(req.query.url); if (!allowedDomains.includes(url.hostname)) { return res.status(403).send('Forbidden'); }

Security Testing Methodologies

1. Static Application Security Testing (SAST)

SAST analyzes source code without running the application to find vulnerabilities.

2. Dynamic Application Security Testing (DAST)

DAST tests the running application to find runtime vulnerabilities.

3. Manual Penetration Testing

Human testers actively try to break the system using creativity and experience.

Practical Security Testing Tools

1. OWASP ZAP (Free)

A free, open-source penetration testing tool perfect for finding security vulnerabilities.

// Start ZAP in daemon mode zaproxy.sh -daemon -port 8090 // Run automated scan curl "http://localhost:8090/JSON/ascan/action/scan/?url=http://example.com" // Get report curl "http://localhost:8090/OTHER/core/other/htmlreport/" > report.html

2. Burp Suite Community Edition (Free)

Professional-grade web vulnerability scanner with free community edition.

3. SonarQube (Open Source)

Continuous code quality and security analysis.

// Analyze code with SonarQube sonar-scanner \ -Dsonar.projectKey=myapp \ -Dsonar.sources=src \ -Dsonar.host.url=http://localhost:9000 \ -Dsonar.login=YOUR_TOKEN

Creating a Security Testing Checklist

Develop a comprehensive checklist for your application:

SECURITY TESTING CHECKLIST Authentication & Authorization: ☐ Default credentials changed ☐ Password requirements enforced (min length, complexity) ☐ Session timeout implemented ☐ CSRF protection implemented ☐ CORS properly configured ☐ Role-based access control working Data Protection: ☐ HTTPS enabled everywhere ☐ Sensitive data encrypted at rest ☐ No sensitive data in logs ☐ SQL injection prevention tested ☐ XSS prevention tested ☐ File upload validation implemented Configuration: ☐ Debug mode disabled in production ☐ Error messages don't expose system details ☐ Security headers configured (CSP, X-Frame-Options, etc.) ☐ Dependencies updated and no known vulnerabilities ☐ Configuration files not exposed Monitoring: ☐ Login attempts logged ☐ Failed transactions logged ☐ Suspicious activity alerts configured ☐ Log retention policy implemented

Security Testing in CI/CD Pipeline

Integrate security testing into your CI/CD pipeline:

// GitHub Actions example name: Security Tests on: [push, pull_request] jobs: security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Run SAST run: npm install -g snyk && snyk test - name: Check dependencies run: npm audit --audit-level=moderate - name: Run OWASP ZAP scan run: | docker run -t owasp/zap2docker-stable zap-baseline.py \ -t http://localhost:3000 - name: SonarQube analysis run: sonar-scanner

Real-World Security Testing Example

Banking Application Test Scenario

Test Case: Transfer Funds Vulnerability Prerequisites: Two user accounts (User A, User B) Steps: 1. User A logs in and initiates transfer of $500 to User B 2. Intercept the POST request to /api/transfer 3. Check request body - does it contain recipient's ID? 4. Modify recipient ID to different user 5. Replay the request 6. Verify if transfer went to wrong recipient Expected Result: Transfer should FAIL with proper error message Actual Result (vulnerable): Transfer succeeds to modified recipient! Security Issues Found: - No server-side validation of recipient - Client-side controls insufficient - Business logic flaw in transfer function

Conclusion

Security testing is a critical responsibility for QA engineers. By understanding the OWASP Top 10, using appropriate tools, and implementing systematic testing approaches, you can significantly improve the security posture of your applications.

Remember: Security is not a feature that can be added later—it must be built in from the beginning. Collaborate with developers, use automation where possible, and stay updated with the latest security trends and vulnerabilities.

Back to Blogs