Skip to content

Security Testing Methodologies

Alex Stojcic edited this page Apr 3, 2025 · 2 revisions

Security Testing Methodologies

Security testing is a critical part of application development that helps identify and address vulnerabilities before attackers can exploit them. This guide covers comprehensive security testing methodologies, tools, and best practices for web applications.

Security Testing Overview

Types of Security Testing

Test Type Description When to Use
Vulnerability Assessment Scan for known vulnerabilities Regularly throughout development
Penetration Testing Simulate attacks to exploit vulnerabilities Pre-release, major changes
Static Application Security Testing (SAST) Analyze source code for security issues During development, CI/CD
Dynamic Application Security Testing (DAST) Test running applications for vulnerabilities Integration testing, staging
Interactive Application Security Testing (IAST) Combine SAST and DAST Advanced CI/CD pipelines
Software Composition Analysis (SCA) Analyze dependencies for vulnerabilities Throughout development
Security Code Review Manual review of code for security issues Critical security components

Security Testing Pyramid

Similar to the test pyramid, security testing should follow a structured approach:

    /\
   /  \
  /    \   Manual Penetration Testing
 /      \
/________\  DAST / API Security Testing
|        |
|        |  IAST / Fuzzing
|________|
|        |
|        |  SAST / SCA / Secret Scanning
|________|
  • Base layers: Automated, fast, frequent (SAST, SCA)
  • Middle layers: Semi-automated, targeted (IAST, API testing)
  • Top layers: Manual, expert-driven (penetration testing)

Vulnerability Scanning

OWASP ZAP (Zed Attack Proxy)

OWASP ZAP is a free, open-source security tool for finding vulnerabilities in web applications.

Basic ZAP Scan

# Install ZAP via Docker
docker pull owasp/zap2docker-stable

Run automated scan

docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-baseline.py
-t https://example.com -g gen.conf -r testreport.html

Integrating ZAP with CI/CD (GitHub Actions)

# .github/workflows/zap-scan.yml
name: OWASP ZAP Integration

on: push: branches: [ main ] pull_request: branches: [ main ] schedule: - cron: '0 0 * * 0' # Weekly scan

jobs: zap_scan: runs-on: ubuntu-latest name: Scan the application steps: - name: Checkout uses: actions/checkout@v2

  - name: ZAP Scan
    uses: zaproxy/action-baseline@v0.7.0
    with:
      target: 'https://staging.example.com'
      rules_file_name: '.zap/rules.tsv'
      cmd_options: '-a'

Nuclei for Vulnerability Scanning

Nuclei is a fast, template-based vulnerability scanner focusing on extensive coverage.

# Install Nuclei
GO111MODULE=on go get -v github.com/projectdiscovery/nuclei/v2/cmd/nuclei

Run scan with common vulnerabilities

nuclei -u https://example.com -t nuclei-templates/

Use specific templates

nuclei -u https://example.com -t nuclei-templates/cves/ -t nuclei-templates/vulnerabilities/

Generate HTML report

nuclei -u https://example.com -t nuclei-templates/ -o report.html -me html

Static Application Security Testing (SAST)

SonarQube for Code Analysis

# Run SonarQube with Docker
docker run -d --name sonarqube -p 9000:9000 sonarqube:latest

Run SonarScanner for JavaScript project

docker run --rm -e SONAR_HOST_URL="http://localhost:9000"
-v "$(pwd):/usr/src"
sonarsource/sonar-scanner-cli
-Dsonar.projectKey=my-project
-Dsonar.sources=.
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info

SonarQube configuration file (sonar-project.properties):

# Project settings
sonar.projectKey=my-project
sonar.projectName=My Project
sonar.projectVersion=1.0

Path to source directories

sonar.sources=src sonar.tests=tests

Exclude files from analysis

sonar.exclusions=node_modules/,/.spec.ts,**/.test.ts

Language

sonar.language=js sonar.javascript.lcov.reportPaths=coverage/lcov.info

Encoding of the source files

sonar.sourceEncoding=UTF-8

Security-focused rules

sonar.issue.ignore.multicriteria=e1 sonar.issue.ignore.multicriteria.e1.ruleKey=* sonar.issue.ignore.multicriteria.e1.resourceKey=**/*.test.js

ESLint Security Plugin

# Install ESLint security plugins
npm install eslint eslint-plugin-security --save-dev

ESLint configuration (.eslintrc.js):

module.exports = {
  'plugins': [
    'security'
  ],
  'extends': [
    'plugin:security/recommended'
  ],
  'rules': {
    'security/detect-buffer-noassert': 'error',
    'security/detect-child-process': 'error',
    'security/detect-disable-mustache-escape': 'error',
    'security/detect-eval-with-expression': 'error',
    'security/detect-no-csrf-before-method-override': 'error',
    'security/detect-non-literal-fs-filename': 'error',
    'security/detect-non-literal-regexp': 'error',
    'security/detect-non-literal-require': 'error',
    'security/detect-object-injection': 'error',
    'security/detect-possible-timing-attacks': 'error',
    'security/detect-pseudoRandomBytes': 'error',
    'security/detect-unsafe-regex': 'error'
  }
};

Semgrep for Security Rules

Semgrep is a lightweight static analysis tool for finding bugs and enforcing code standards.

# Install Semgrep
pip install semgrep

Run scan with security rules

semgrep --config=p/security-audit src/

Scan with specific ruleset

semgrep --config=p/owasp-top-ten src/

Generate JSON report

semgrep --config=p/security-audit --json > security-report.json

Custom Semgrep rule for finding hardcoded secrets:

# .semgrep/hardcoded-secrets.yml
rules:
  - id: hardcoded-api-key
    pattern: |
      $X = "sk_live_"
    message: "Hardcoded API key detected"
    languages: [javascript, typescript, python]
    severity: ERROR
  • id: hardcoded-jwt-secret patterns:
    • pattern-either:
      • pattern: | $JWT_SECRET = "..."
      • pattern: | $JWT_KEY = "..." message: "Hardcoded JWT secret detected" languages: [javascript, typescript, python] severity: ERROR

Dynamic Application Security Testing (DAST)

OWASP ZAP Full Scan

# Run ZAP Active Scan (more thorough than baseline)
docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-full-scan.py \
    -t https://staging.example.com -g gen.conf -r full-report.html

Scan with authentication

docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-full-scan.py
-t https://staging.example.com
-z "auth.loginurl=https://staging.example.com/login
auth.username=test@example.com
auth.password=Password123
auth.auto=true"
-r authenticated-report.html

Using OWASP ZAP for API Testing

# Create an OpenAPI definition file (openapi.json)
# Then use it to test the API
docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-api-scan.py \
    -t https://api.example.com -f openapi -f openapi.json \
    -r api-report.html

Software Composition Analysis (SCA)

Using OWASP Dependency-Check

# Run Dependency Check with Docker
docker run --rm \
    -v $(pwd):/src \
    -v $(pwd)/reports:/report \
    owasp/dependency-check \
    --scan /src \
    --format "HTML" \
    --project "My Project" \
    --out /report

Using Snyk for Dependency Analysis

# Install Snyk
npm install -g snyk

Authenticate

snyk auth

Test for vulnerabilities

snyk test

Test with JSON output

snyk test --json > snyk-results.json

Monitor project continuously

snyk monitor

Fix vulnerabilities where possible

snyk wizard

Fuzzing and Input Testing

API Fuzzing with Postman

// Newman (Postman CLI) with fuzzing collection
const newman = require('newman');

// Load fuzzing data const fuzzingData = require('./fuzzing-data.json');

// For each fuzzing test case fuzzingData.forEach(testCase => { newman.run({ collection: require('./api-collection.json'), environment: require('./environment.json'), iterationData: [testCase], reporters: ['cli', 'json'], reporter: { json: { export: ./reports/fuzzing-${testCase.name}.json } } }, function (err) { if (err) { throw err; } console.log(Completed fuzzing test: ${testCase.name}); }); });

Example fuzzing test cases (fuzzing-data.json):

[
  {
    "name": "sql-injection",
    "endpoint": "/api/users",
    "input": {
      "username": "admin' OR 1=1--",
      "email": "test@example.com"
    }
  },
  {
    "name": "xss-attack",
    "endpoint": "/api/comments",
    "input": {
      "content": "<script>alert('XSS')</script>"
    }
  },
  {
    "name": "nosql-injection",
    "endpoint": "/api/products",
    "input": {
      "id": {"$gt": ""}
    }
  }
]

Using AFL++ for Fuzzing

American Fuzzy Lop (AFL++) is a powerful fuzzing tool:

# Install AFL++
git clone https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
make
sudo make install

Instrument your program

afl-gcc -o my_program my_program.c

Start fuzzing

afl-fuzz -i input_dir -o output_dir -- ./my_program @@

Penetration Testing

Methodology: OWASP Testing Guide

The OWASP Testing Guide provides a comprehensive methodology for web application penetration testing:

  1. Information Gathering

    • Identify IP ranges, domains, technologies
    • Fingerprint web servers, frameworks
    • Map application architecture
  2. Configuration Management Testing

    • Test file extensions handling
    • Review old/backup files
    • Check for security headers
    • Test HTTP methods
  3. Authentication Testing

    • Test credential transport
    • Check default/weak credentials
    • Test authentication bypasses
    • Test session management
  4. Authorization Testing

    • Test path traversal
    • Test for privilege escalation
    • Check for insecure direct object references
  5. Session Management Testing

    • Test session fixation
    • Check cookie attributes
    • Test session timeout
  6. Data Validation Testing

    • Test for SQL injection
    • Cross-site scripting (XSS)
    • CSRF vulnerabilities
    • Command injection
  7. Denial of Service Testing

    • Resource consumption
    • User lockout
    • Distributed testing
  8. Business Logic Testing

    • Test workflows and workflows bypasses
    • Test for abuse of functionality
  9. Client-side Testing

    • DOM-based vulnerabilities
    • JavaScript execution
    • Local storage issues

Automated Penetration Testing Tools

Metasploit Framework

# Start Metasploit
msfconsole

Web application scanning

use auxiliary/scanner/http/dir_scanner set RHOSTS target.example.com set THREADS 10 run

Vulnerability scanning

use auxiliary/scanner/http/wordpress_scanner set RHOSTS blog.example.com run

Burp Suite

Burp Suite workflow (manual steps):

  1. Set up proxy and capture requests
  2. Spider the target application
  3. Use the Active Scanner on found endpoints
  4. Manual verification of discovered issues
  5. Exploitation of confirmed vulnerabilities
  6. Report generation

Continuous Security Testing in CI/CD

GitHub Actions Security Pipeline

# .github/workflows/security.yml
name: Security Pipeline

on: push: branches: [ main, develop ] pull_request: branches: [ main, develop ] schedule: - cron: '0 0 * * 0' # Weekly scan

jobs: security-sast: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2

  - name: SonarCloud Scan
    uses: SonarSource/sonarcloud-github-action@master
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
  
  - name: Run Semgrep
    uses: returntocorp/semgrep-action@v1
    with:
      config: p/security-audit

dependency-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2

  - name: Snyk Test
    uses: snyk/actions/node@master
    env:
      SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
    with:
      args: --severity-threshold=high
  
  - name: OWASP Dependency Check
    uses: dependency-check/Dependency-Check_Action@main
    with:
      project: 'My Project'
      path: '.'
      format: 'HTML'
      out: 'reports'
      args: &gt;
        --suppression suppression.xml

dynamic-testing: runs-on: ubuntu-latest needs: [security-sast, dependency-check] if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v2

  - name: Deploy to Testing
    run: ./deploy-to-test.sh
  
  - name: ZAP API Scan
    uses: zaproxy/action-api-scan@v0.1.0
    with:
      target: 'https://test-api.example.com'
      api_definition: 'openapi.json'
      format: 'json'
      fail_action: false
  
  - name: Upload Security Reports
    uses: actions/upload-artifact@v2
    with:
      name: security-reports
      path: reports/

GitLab CI Security Pipeline

# .gitlab-ci.yml
stages:
  - build
  - test
  - sast
  - dast
  - deploy

variables: DOCKER_DRIVER: overlay2 SAST_ANALYZER_IMAGE: gitlab/gitlab-sast:latest DAST_ANALYZER_IMAGE: gitlab/gitlab-dast:latest

include:

  • template: Security/SAST.gitlab-ci.yml
  • template: Security/Dependency-Scanning.gitlab-ci.yml
  • template: Security/Container-Scanning.gitlab-ci.yml
  • template: Security/DAST.gitlab-ci.yml
  • template: Security/Secret-Detection.gitlab-ci.yml

Enable SAST analyzers

sast: variables: SAST_EXCLUDED_PATHS: "node_modules, dist, coverage, vendor" SCAN_KUBERNETES_MANIFESTS: "true"

Custom dependency scanning

dependency_scanning: variables: DS_EXCLUDED_PATHS: "test, tests, spec, specs"

DAST configuration

dast: variables: DAST_WEBSITE: https://staging.example.com DAST_FULL_SCAN_ENABLED: "true" DAST_ZAP_USE_AJAX_SPIDER: "true" DAST_AUTH_URL: https://staging.example.com/login DAST_USERNAME: test@example.com DAST_PASSWORD: $DAST_PASSWORD DAST_USERNAME_FIELD: "email" DAST_PASSWORD_FIELD: "password" artifacts: paths: - gl-dast-report.json

Custom security job

custom_security_scan: stage: sast image: python:3.9 script: - pip install semgrep - semgrep --config=p/security-audit --json > semgrep-report.json artifacts: paths: - semgrep-report.json

Security Testing Report Templates

Vulnerability Report Format

# Security Vulnerability Report

Summary

  • Vulnerability: SQL Injection in User Search API
  • Severity: Critical (CVSS 9.8)
  • Affected Component: /api/v1/users/search endpoint
  • Status: Confirmed
  • Discovered: 2023-04-15
  • Reported: 2023-04-16

Description

The user search API endpoint is vulnerable to SQL injection attacks through the 'name' parameter. This allows an attacker to execute arbitrary SQL commands against the database.

Proof of Concept

Request:

GET /api/v1/users/search?name=test' OR 1=1--


Response:
```json
{
  "users": [
    {"id": 1, "name": "Admin User", "email": "admin@example.com"},
    {"id": 2, "name": "Test User", "email": "test@example.com"},
    ...
  ]
}

Impact

An attacker can:

  • Access sensitive user data
  • Potentially modify or delete database contents
  • Potentially execute code on the database server

Remediation Steps

  1. Implement parameterized queries for all database operations
  2. Validate and sanitize all user inputs
  3. Implement proper error handling to prevent information disclosure

Example Fix:

// BEFORE (vulnerable)
const query = `SELECT * FROM users WHERE name LIKE '%${name}%'`;

// AFTER (secure) const query = SELECT * FROM users WHERE name LIKE $1; const params = [%${name}%];

References

Clone this wiki locally