Chuyển đến nội dung chính

Lesson 30: Capstone Project — End-to-end Performance Test & Pentest

Comprehensive project: plan, perform performance test + pentest, analyze results, write professional reports — apply all knowledge of 29 lessons.

🔒 DevSecOps — Lesson 30 Lesson 30: Capstone Project — End-to-end Performance Test & Pentest

Performance Testing & Pentest: Enterprise Standard Process 2026

Part 6: Report & Professional Process

xdev.asia

1. Capstone Project Overview

Capstone Project — End-to-end Performance Test & Pentest

Target Application: E-Commerce Platform (microservices)
  ├── Frontend: React SPA
  ├── API Gateway: Kong / Nginx
  ├── Auth Service: JWT + OAuth2
  ├── Product Service: REST API (Node.js)
  ├── Order Service: REST API (Java Spring Boot)
  ├── Payment Service: REST API (Go)
  ├── Database: PostgreSQL + Redis
  ├── Message Queue: RabbitMQ
  └── Infrastructure: Docker + Kubernetes

Timeline:  12 ngày (2 tuần làm việc + 2 ngày cuối tuần)

  Ngày 1-2    │ Planning & Scoping
  Ngày 3-4    │ Performance Test Design & Execution
  Ngày 5-6    │ Performance Analysis & Tuning
  Ngày 7-8    │ Penetration Testing — Recon & Scanning
  Ngày 9-10   │ Penetration Testing — Exploitation & Post-exploitation
  Ngày 11     │ Report Writing
  Ngày 12     │ Presentation & Remediation Plan

2. Phase 1: Planning & Scoping (Day 1-2)

# Security & Performance Assessment — Project Charter

## 1. Engagement Overview
- **Client**: XDev Corp
- **Application**: E-Commerce Platform v3.2
- **Type**: Performance Test + Gray-box Pentest
- **Timeline**: 12 working days
- **Team**: 2 performance engineers + 2 pentesters

## 2. Scope

### In Scope
| Asset               | Type          | Environment |
|---------------------|---------------|-------------|
| app.xdev.example    | Web App       | Staging     |
| api.xdev.example    | REST API      | Staging     |
| *.xdev.example      | Subdomains    | Staging     |
| K8s cluster         | Infrastructure| Staging     |
| PostgreSQL          | Database      | Staging     |

### Out of Scope
- Production environment
- Third-party payment gateway (Stripe)
- Physical security
- Social engineering

## 3. Rules of Engagement
- Testing hours: 08:00 – 22:00 ICT
- No DoS/DDoS against production
- Performance tests max 500 VUs on staging
- Data: Use synthetic test data only
- Emergency contact: [email protected]

## 4. Success Criteria
### Performance
- Homepage load < 2s (P95)
- API response < 200ms (P95)
- Support 300 concurrent users
- Zero errors under normal load

### Security
- No Critical/High findings in OWASP Top 10
- All APIs properly authenticated
- No sensitive data exposure
- Container images free of Critical CVEs

## 5. Deliverables
- Performance Test Report (PDF + Dashboard)
- Pentest Report (Technical + Executive)
- Remediation roadmap with SLA
- Retest confirmation (after fixes)

3. Phase 2: Performance Testing (Day 3-6)

3.1 Test Design

// k6-capstone/scenarios/smoke-test.js

import http from 'k6/http';
import { check, sleep, group } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';

// Custom metrics
const errorRate = new Rate('errors');
const homepageTime = new Trend('homepage_duration');
const searchTime = new Trend('search_duration');
const checkoutTime = new Trend('checkout_duration');

const BASE_URL = __ENV.BASE_URL || 'https://staging.xdev.example';

export const options = {
  scenarios: {
    // Smoke test — verify scripts work
    smoke: {
      executor: 'constant-vus',
      vus: 1,
      duration: '1m',
    },
  },
  thresholds: {
    http_req_duration: ['p(95)<2000'],
    errors: ['rate<0.01'],
  },
};

export function setup() {
  // Login and get token
  const loginRes = http.post(`${BASE_URL}/api/auth/login`, JSON.stringify({
    email: '[email protected]',
    password: 'TestP@ss2026!',
  }), { headers: { 'Content-Type': 'application/json' } });

  check(loginRes, { 'login successful': (r) => r.status === 200 });
  return { token: loginRes.json('token') };
}

export default function (data) {
  const headers = {
    'Authorization': `Bearer ${data.token}`,
    'Content-Type': 'application/json',
  };

  // User journey: Browse → Search → View → Add to Cart → Checkout
  group('01_Homepage', () => {
    const res = http.get(`${BASE_URL}/`);
    homepageTime.add(res.timings.duration);
    check(res, { 'homepage 200': (r) => r.status === 200 });
    errorRate.add(res.status !== 200);
    sleep(2);
  });

  group('02_Search', () => {
    const res = http.get(`${BASE_URL}/api/products?q=laptop&page=1`, { headers });
    searchTime.add(res.timings.duration);
    check(res, {
      'search 200': (r) => r.status === 200,
      'has results': (r) => r.json('data.length') > 0,
    });
    errorRate.add(res.status !== 200);
    sleep(1);
  });

  group('03_ViewProduct', () => {
    const res = http.get(`${BASE_URL}/api/products/prod-001`, { headers });
    check(res, { 'product 200': (r) => r.status === 200 });
    errorRate.add(res.status !== 200);
    sleep(1);
  });

  group('04_AddToCart', () => {
    const res = http.post(`${BASE_URL}/api/cart/items`, JSON.stringify({
      product_id: 'prod-001',
      quantity: 1,
    }), { headers });
    check(res, { 'add cart 200': (r) => r.status === 200 || r.status === 201 });
    errorRate.add(res.status >= 400);
    sleep(1);
  });

  group('05_Checkout', () => {
    const res = http.post(`${BASE_URL}/api/orders`, JSON.stringify({
      payment_method: 'test_card',
      shipping_address: {
        street: '123 Test St',
        city: 'Ho Chi Minh',
        country: 'VN',
      },
    }), { headers });
    checkoutTime.add(res.timings.duration);
    check(res, { 'checkout success': (r) => r.status === 200 || r.status === 201 });
    errorRate.add(res.status >= 400);
    sleep(2);
  });
}
// k6-capstone/scenarios/load-test.js

import { smoke } from './smoke-test.js';

export { setup, default } from './smoke-test.js';

export const options = {
  scenarios: {
    // Ramp-up load test
    load: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: 50 },    // Ramp up
        { duration: '5m', target: 50 },    // Steady state
        { duration: '2m', target: 150 },   // Peak load
        { duration: '5m', target: 150 },   // Sustained peak
        { duration: '2m', target: 300 },   // Stress point
        { duration: '5m', target: 300 },   // Sustained stress
        { duration: '3m', target: 0 },     // Ramp down
      ],
    },
  },
  thresholds: {
    http_req_duration: ['p(95)<2000', 'p(99)<5000'],
    errors: ['rate<0.05'],
    homepage_duration: ['p(95)<1500'],
    search_duration: ['p(95)<500'],
    checkout_duration: ['p(95)<3000'],
  },
};

3.2 Execution & Analysis

# Run performance tests with Grafana dashboards

# Smoke test (verify scripts)
k6 run --out influxdb=http://localhost:8086/k6 \
  k6-capstone/scenarios/smoke-test.js

# Load test (main test)
k6 run --out influxdb=http://localhost:8086/k6 \
  --out json=results/load-test.json \
  k6-capstone/scenarios/load-test.js

# Results analysis
k6 run --summary-export=results/summary.json \
  k6-capstone/scenarios/load-test.js
Performance Test Results Summary:

Scenario: Load Test — E-Commerce Platform
VUs: 0 → 50 → 150 → 300 → 0
Duration: 24 minutes

Results:
  ┌──────────────────────┬────────┬────────┬────────┬────────┬─────────┐
  │ Metric               │ Avg    │ P50    │ P90    │ P95    │ P99     │
  ├──────────────────────┼────────┼────────┼────────┼────────┼─────────┤
  │ Homepage             │ 320ms  │ 280ms  │ 520ms  │ 780ms  │ 1,200ms │
  │ Search API           │ 180ms  │ 150ms  │ 350ms  │ 480ms  │ 920ms   │
  │ Product Detail       │ 95ms   │ 80ms   │ 180ms  │ 250ms  │ 450ms   │
  │ Add to Cart          │ 120ms  │ 100ms  │ 220ms  │ 310ms  │ 580ms   │
  │ Checkout             │ 450ms  │ 380ms  │ 850ms  │ 1,200ms│ 2,500ms │
  └──────────────────────┴────────┴────────┴────────┴────────┴─────────┘

  Total Requests: 142,380
  Success Rate:   97.2%
  Error Rate:     2.8% ⚠️ (threshold: 5%)

  Throughput: ~98 req/s avg, peak 156 req/s

Bottlenecks Identified:
  1. [HIGH] Checkout P99 = 2.5s → Order Service DB connection pool exhaustion
  2. [MEDIUM] Search at 300 VUs → PostgreSQL full table scan on products
  3. [LOW] Homepage TTFB increases linearly → Missing CDN cache headers

4. Phase 3: Penetration Testing (October 7)

4.1 Reconnaissance

# Subdomain enumeration
amass enum -d xdev.example -o recon/subdomains.txt

# Port scan
nmap -sV -sC -p- --min-rate=1000 \
  -oA recon/full-scan staging.xdev.example

# Technology fingerprinting
whatweb https://staging.xdev.example

# API discovery
# Check API docs
curl -s https://api.xdev.example/swagger.json | jq '.paths | keys[]'
curl -s https://api.xdev.example/openapi.json | jq '.paths | keys[]'

# Directory brute-force
feroxbuster -u https://api.xdev.example \
  -w /usr/share/wordlists/dirb/common.txt \
  --filter-status 404 -o recon/dirs.txt

# Kubernetes recon (if accessible)
kubectl get pods --all-namespaces 2>/dev/null
kubectl get services --all-namespaces 2>/dev/null

4.2 Vulnerability Scanning__HTMLTAG_90___
# Nuclei scan
nuclei -u https://staging.xdev.example \
  -t cves/ -t vulnerabilities/ -t misconfiguration/ \
  -severity critical,high,medium \
  -o results/nuclei-scan.txt \
  -json -json-export results/nuclei-scan.json

# ZAP full scan
docker run --rm -v $(pwd)/results:/zap/wrk \
  ghcr.io/zaproxy/zaproxy:stable zap-full-scan.py \
  -t https://staging.xdev.example \
  -r zap-report.html \
  -J zap-report.json \
  -c zap-config.prop

# Container image scan
trivy image --severity HIGH,CRITICAL \
  --format json --output results/trivy-images.json \
  registry.xdev.example/ecommerce-api:latest

# K8s cluster scan
trivy k8s --report summary cluster
kubeaudit all -f /path/to/manifests/

4.3 Manual Testing — Findings

Pentest Findings Summary — E-Commerce Platform

Total: 18 findings    Critical: 2    High: 4    Medium: 7    Low: 5

─────────────────────────────────────────────────────────────────────

[CRITICAL] Finding #1: Broken Object-Level Authorization (BOLA)
  CWE-639 | CVSS v4.0: 9.1
  Endpoint: GET /api/orders/{orderId}
  Issue: Any authenticated user can view any order by changing orderId
  Impact: Full access to all customer orders, PII exposure

  PoC:
    # User A's token can access User B's order
    curl -H "Authorization: Bearer USER_A_TOKEN" \
      https://api.xdev.example/api/orders/ORD-0042

  Remediation: Implement ownership check in Order Service
    if (order.userId !== req.user.id) return 403;

─────────────────────────────────────────────────────────────────────

[CRITICAL] Finding #2: SQL Injection in Search
  CWE-89 | CVSS v4.0: 9.3
  Endpoint: GET /api/products?q=PAYLOAD&sort=PAYLOAD
  Issue: sort parameter directly concatenated into SQL query
  Impact: Full database read/write, potential RCE

  PoC:
    GET /api/products?q=laptop&sort=name;SELECT+pg_sleep(5)--
    → Response delayed 5s = confirmed blind SQLi

    sqlmap -u "https://api.xdev.example/api/products?sort=name" \
      --headers="Authorization: Bearer TOKEN" --dbs

  Remediation: Use parameterized queries

─────────────────────────────────────────────────────────────────────

[HIGH] Finding #3: JWT Algorithm Confusion
  CWE-327 | CVSS v4.0: 8.2
  Issue: Auth service accepts "alg: none" in JWT header
  Impact: Authentication bypass, impersonate any user

  PoC:
    # Forge JWT with alg=none
    echo '{"alg":"none","typ":"JWT"}' | base64url
    echo '{"sub":"admin","role":"admin"}' | base64url
    # Token: eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiJ9.

  Remediation: Explicitly whitelist allowed algorithms
    jwt.verify(token, secret, { algorithms: ['RS256'] })

─────────────────────────────────────────────────────────────────────

[HIGH] Finding #4: SSRF via Image Upload
  CWE-918 | CVSS v4.0: 7.5
  Endpoint: POST /api/products/image
  Issue: URL parameter fetches remote images without validation
  Impact: Internal network scanning, cloud metadata access

  PoC:
    POST /api/products/image
    {"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}

  Remediation: Validate URL against allowlist, block internal IPs

─────────────────────────────────────────────────────────────────────

[HIGH] Finding #5: Exposed Kubernetes Dashboard
  Issue: K8s dashboard accessible without authentication
  URL: https://k8s.xdev.example/dashboard/
  Impact: Full cluster control, deploy malicious workloads

─────────────────────────────────────────────────────────────────────

[HIGH] Finding #6: Hardcoded Secrets in Container Image
  CWE-798 | CVSS v4.0: 7.8
  Issue: Database credentials found in Docker image layers
  Impact: Direct database access, data exfiltration

  PoC:
    docker save registry.xdev.example/ecommerce-api:latest | tar xf -
    grep -r "DB_PASSWORD" */layer.tar
    → Found: DB_PASSWORD=Pr0duction_P@ss!

  Remediation: Use K8s Secrets or Vault, multi-stage Docker builds

5. Phase 4: Report Writing (Day 11)

5.1 Executive Summary

# Executive Summary

## Overall Risk Rating: HIGH

XDev Corp's E-Commerce Platform was assessed through combined performance
testing and penetration testing from [date] to [date].

### Key Findings

| Category            | Critical | High | Medium | Low | Total |
|---------------------|----------|------|--------|-----|-------|
| Authentication      | 0        | 1    | 2      | 1   | 4     |
| Authorization       | 1        | 0    | 1      | 0   | 2     |
| Injection           | 1        | 0    | 1      | 0   | 2     |
| Infrastructure      | 0        | 2    | 1      | 2   | 5     |
| Data Protection     | 0        | 1    | 2      | 2   | 5     |
| **Total**           | **2**    | **4**| **7**  | **5**| **18**|

### Performance Assessment

| Criteria                    | Target  | Actual   | Status |
|-----------------------------|---------|----------|--------|
| Homepage P95                | < 2s    | 780ms    | ✅ PASS |
| API P95                     | < 200ms | 480ms    | ❌ FAIL |
| Concurrent users supported  | 300     | ~220     | ❌ FAIL |
| Error rate under load       | < 1%    | 2.8%    | ❌ FAIL |

### Business Impact
- **2 Critical findings** require immediate remediation (< 48h)
  - BOLA vulnerability exposes **all customer orders and PII**
  - SQL injection allows **full database compromise**
- Platform **cannot sustain 300 concurrent users** — checkout degrades at 200+ VUs
- Revenue impact: Estimated $X per hour of degraded checkout experience

### Priority Recommendations
1. **Immediate (48h)**: Fix SQL injection and BOLA vulnerabilities
2. **Short-term (1 week)**: Fix JWT algorithm confusion, SSRF, K8s dashboard
3. **Medium-term (30 days)**: Optimize database queries, increase connection pool
4. **Long-term (90 days)**: Implement WAF, SAST/DAST in CI/CD, load test automation

5.2 Remediation Roadmap__HTMLTAG_100___
Remediation Roadmap — Gantt Chart

Week 1 (Immediate):
  ████ SQL Injection fix + verify
  ████ BOLA authorization fix + verify
  ██── JWT algorithm whitelist

Week 2 (Short-term):
  ──██ JWT fix continue + verify
  ████ SSRF URL validation
  ████ K8s dashboard RBAC
  ██── Hardcoded secrets → Vault

Week 3-4 (Medium-term):
  ──████ Secrets rotation
  ████████ DB query optimization
  ████████ Connection pool tuning
  ████ CDN cache headers
  ████████ Retest all High findings

Month 2-3 (Long-term):
  ████████████████ WAF deployment
  ████████████████ SAST/DAST CI/CD
  ████████ k6 load test automation
  ████████ Security training for devs

Verification:
  - Retest Critical findings: Week 2
  - Retest High findings: Week 4
  - Full regression pentest: Month 3
  - Performance retest: After optimization

6. Automated Report Generation

# generate_capstone_report.py
# Combines performance + security results into single report

import json
from datetime import datetime
from pathlib import Path

def load_results():
    """Load all scan and test results"""
    results = {}

    # k6 performance results
    k6_path = Path("results/summary.json")
    if k6_path.exists():
        with open(k6_path) as f:
            results["performance"] = json.load(f)

    # Nuclei findings
    nuclei_path = Path("results/nuclei-scan.json")
    if nuclei_path.exists():
        with open(nuclei_path) as f:
            results["nuclei"] = [json.loads(line) for line in f]

    # ZAP findings
    zap_path = Path("results/zap-report.json")
    if zap_path.exists():
        with open(zap_path) as f:
            results["zap"] = json.load(f)

    # Trivy findings
    trivy_path = Path("results/trivy-images.json")
    if trivy_path.exists():
        with open(trivy_path) as f:
            results["trivy"] = json.load(f)

    return results

def generate_summary(results: dict) -> dict:
    """Generate combined summary"""
    summary = {
        "date": datetime.now().isoformat(),
        "performance": {
            "total_requests": results.get("performance", {}).get("metrics", {})
                .get("http_reqs", {}).get("count", 0),
            "error_rate": results.get("performance", {}).get("metrics", {})
                .get("errors", {}).get("rate", 0),
            "p95_duration": results.get("performance", {}).get("metrics", {})
                .get("http_req_duration", {}).get("p(95)", 0),
        },
        "security": {
            "critical": 0, "high": 0, "medium": 0, "low": 0
        }
    }

    # Count findings by severity
    for finding in results.get("nuclei", []):
        sev = finding.get("info", {}).get("severity", "low").lower()
        if sev in summary["security"]:
            summary["security"][sev] += 1

    return summary

def upload_to_defectdojo(results: dict, config: dict):
    """Upload all results to DefectDojo"""
    import requests as req

    base_url = config["defectdojo_url"]
    headers = {"Authorization": f"Token {config['defectdojo_token']}"}

    scan_files = [
        ("results/nuclei-scan.json", "Nuclei Scan"),
        ("results/zap-report.json", "ZAP Scan"),
        ("results/trivy-images.json", "Trivy Scan"),
    ]

    for filepath, scan_type in scan_files:
        if Path(filepath).exists():
            with open(filepath, "rb") as f:
                req.post(
                    f"{base_url}/api/v2/reimport-scan/",
                    headers=headers,
                    files={"file": f},
                    data={
                        "scan_type": scan_type,
                        "product_name": config["product_name"],
                        "engagement_name": config["engagement_name"],
                        "auto_create_context": "true",
                    }
                )

if __name__ == "__main__":
    results = load_results()
    summary = generate_summary(results)
    print(json.dumps(summary, indent=2))

7. Phase 5: Presentation & Handoff (Day 12)

Presentation Agenda — Capstone Results

1. Executive Summary (10 min)
   ├── Overall risk rating
   ├── Critical findings overview
   └── Performance vs targets

2. Performance Test Results (15 min)
   ├── Load test methodology
   ├── Results dashboard walkthrough
   ├── Bottleneck analysis
   └── Optimization recommendations

3. Penetration Test Results (20 min)
   ├── Scope and methodology
   ├── Critical/High findings deep-dive
   ├── Live demo: BOLA + SQLi exploitation
   └── Attack chain visualization

4. Combined Risk Analysis (10 min)
   ├── Performance under attack scenarios
   ├── Security vs performance trade-offs
   └── Business impact quantification

5. Remediation Roadmap (10 min)
   ├── Priority matrix
   ├── Timeline and ownership
   ├── SLA commitments
   └── Retest schedule

6. Q&A (15 min)

Deliverables Checklist:
  ☑ Performance Test Report (PDF)
  ☑ Pentest Report — Technical (PDF)
  ☑ Pentest Report — Executive (PDF)
  ☑ Raw scan data (encrypted ZIP)
  ☑ k6 test scripts (Git repo)
  ☑ Remediation Jira tickets (auto-created)
  ☑ Grafana dashboard access
  ☑ DefectDojo project access
  ☑ Retest schedule (calendar invites)

8. Summary of the entire Series

Performance Testing & Pentest: Quy trình Chuẩn Doanh nghiệp 2026

30 Bài học — 6 Phần — 120+ giờ học

Phần 1: Nền tảng Performance Testing (Bài 1-5)
  ✅ Load/Stress/Soak/Spike testing concepts
  ✅ k6, Gatling, Artillery
  ✅ Metrics: throughput, latency, error rate

Phần 2: Performance Testing Nâng cao (Bài 6-10)
  ✅ Database performance, caching strategies
  ✅ Distributed testing, cloud-scale
  ✅ APM integration, continuous testing

Phần 3: Pentest Foundations (Bài 11-15)
  ✅ PTES methodology, legal framework
  ✅ OWASP Top 10 (2025)
  ✅ Recon, scanning, web app testing

Phần 4: Pentest Nâng cao (Bài 16-20)
  ✅ Metasploit, cloud pentesting
  ✅ Container/K8s security
  ✅ API testing, AI-powered pentesting

Phần 5: Red/Blue/Purple Team (Bài 21-25)
  ✅ Adversary simulation, detection engineering
  ✅ Purple team collaboration
  ✅ Bug bounty, compliance frameworks

Phần 6: Báo cáo & Quy trình (Bài 26-30)
  ✅ CVSS v4.0 scoring
  ✅ Performance & Pentest report writing
  ✅ Automated reporting, remediation tracking
  ✅ Capstone: End-to-end project

Congratulations! 🎉
Bạn đã hoàn thành toàn bộ series. Hãy áp dụng kiến thức
vào dự án thực tế và tiếp tục cập nhật theo xu hướng 2026.
  • Capstone = Summary: Combine all knowledge from the previous 29 lessons
  • End-to-end workflow: Planning → Execution → Analysis → Report → Handoff
  • Performance + Security: Parallel evaluation, combined reporting
  • Automation: DefectDojo, Jira integration, automated report generation
  • Deliverables: PDF reports, dashboards, remediation tickets, retest plan

This is the last post of the series. Wishing you success on your Security & Performance Engineering journey!