Penetration Testing Fundamentals
Deliberately probing systems for vulnerabilities before attackers do.
Overview
Penetration testing (pen testing) is a controlled, authorised attack simulation that identifies security vulnerabilities before malicious actors do. It differs from vulnerability scanning (automated tool-based) by involving human creativity and chained exploit attempts. Types: black box (no prior knowledge), white box (full access), and grey box (partial knowledge). Results are documented in a report with severity ratings and remediation guidance.
Origin
Tiger teams (US Air Force, 1970s) were early red teams that tested base security. The term "penetration testing" appears in RAND Corporation reports (1970). Bug bounty programmes (Netscape, 1995; Google, 2010; HackerOne, 2012) created a market for responsible vulnerability disclosure. PTES (Penetration Testing Execution Standard, 2012) and OWASP Testing Guide formalised methodologies.
Examples
Automated DAST scanning in CI with OWASP ZAP
// .github/workflows/security-scan.yml
// name: DAST Security Scan
// on:
// pull_request:
// branches: [main]
//
// jobs:
// zap-scan:
// runs-on: ubuntu-latest
// services:
// app:
// image: ghcr.io/my-org/my-app:pr-${{ github.event.number }}
// ports: ['3000:3000']
// options: --health-cmd "curl -f http://localhost:3000/health"
//
// steps:
// - name: Run OWASP ZAP baseline scan
// uses: zaproxy/action-baseline@v0.12.0
// with:
// target: 'http://localhost:3000'
// rules_file_name: '.zap/rules.tsv'
// cmd_options: '-a -j -T 60'
// fail_action: false # Set to true to break the build on findings
//
// - name: Upload ZAP report
// uses: actions/upload-artifact@v4
// with:
// name: zap-report
// path: report_html.html
// .zap/rules.tsv - configure false positive suppression
// 10021 IGNORE (Application Error Disclosure) .*health.*ZAP baseline scan checks for common vulnerabilities (missing headers, exposed stack traces, insecure cookies) without active attack attempts. Active scan (zaproxy/action-full-scan) sends attack payloads but takes longer and may cause side effects on stateful endpoints.
Manual authentication testing checklist in Ruby console
# Manual pen test verification script (run in test environment only)
# Tests for common authentication vulnerabilities
require 'net/http'
require 'json'
BASE_URL = 'https://app.staging.example.com'
# Test 1: Verify rate limiting on login endpoint
def test_rate_limiting(http)
puts "Testing rate limiting on /api/v1/auth/login..."
responses = 20.times.map do
req = Net::HTTP::Post.new('/api/v1/auth/login', 'Content-Type' => 'application/json')
req.body = { email: 'test@example.com', password: 'wrong-password' }.to_json
http.request(req).code
end
rate_limited = responses.count { |c| c == '429' }
puts rate_limited > 0 ? "PASS: Rate limited after #{20 - rate_limited} attempts" : "FAIL: No rate limiting detected"
end
# Test 2: Verify session invalidation on logout
def test_session_invalidation(http)
puts "Testing session invalidation..."
login_resp = login(http, 'user@example.com', 'correct-password')
token = JSON.parse(login_resp)['token']
logout(http, token)
reuse_resp = http.get('/api/v1/me', 'Authorization' => "Bearer #{token}")
puts reuse_resp.code == '401' ? 'PASS: Token invalidated after logout' : "FAIL: Token still valid after logout"
endScripted tests verify specific security controls consistently across environments. This supplements automated DAST by testing semantic security properties (rate limit counts, session lifetime, token reuse after logout) that scanners miss.
Use Cases
- 01Pre-launch security validation for new applications or major features before production release
- 02Annual compliance requirement for PCI DSS (Requirement 11.3.1: annual penetration testing), SOC 2, and ISO 27001
- 03Post-incident testing to verify that remediated vulnerabilities are fixed and that the attacker's kill chain has been broken
- 04Third-party vendor assessment: requiring suppliers to provide pen test reports as part of vendor risk management
When Not to Use
- //Do not substitute automated scanning for a manual pen test; scanners have high false-positive rates and miss business logic vulnerabilities entirely
- //Do not pen test production without explicit written authorisation and a rollback plan; active exploit attempts can cause data corruption or service disruption
- //Do not treat a clean pen test report as a permanent security certification; a one-time test reflects a point-in-time snapshot; continuous testing (bug bounty, DAST in CI) provides ongoing assurance
Technical Notes
- CVSS (Common Vulnerability Scoring System, v3.1) is the standard for quantifying vulnerability severity on a 0-10 scale based on attack vector, complexity, privileges required, user interaction, and impact. Critical (9.0-10.0) vulnerabilities require immediate remediation
- Burp Suite Professional (PortSwigger) is the standard intercepting proxy for manual web pen testing; its scanner, intruder, and repeater tools allow systematic testing of authentication, authorisation, and injection points
- Bug bounty programmes (HackerOne, Bugcrowd) provide continuous pen testing by security researchers. The scope (in-scope domains, excluded systems, payout table) must be explicitly defined before launch
- Threat modelling (STRIDE, LINDDUN, PASTA frameworks) before pen testing focuses the scope on the highest-risk attack surfaces; without it, pen testers spend time on low-risk areas and miss critical paths
More in Safety