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.
- Tools: SonarQube, Checkmarx, Fortify, Snyk
- When to use: During development phase
- Advantages: Early detection, finds root causes
2. Dynamic Application Security Testing (DAST)
DAST tests the running application to find runtime vulnerabilities.
- Tools: OWASP ZAP, Burp Suite, Acunetix
- When to use: After deployment to test/staging
- Advantages: Tests actual runtime behavior
3. Manual Penetration Testing
Human testers actively try to break the system using creativity and experience.
- When to use: Critical applications, before major releases
- Advantages: Finds complex, non-obvious vulnerabilities
- Tools: Browser DevTools, Burp Suite, custom scripts
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.
- Proxy functionality for intercepting requests
- Scanner for automated vulnerability detection
- Intruder for attack payloads
- Repeater for manual request testing
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