SiamCafe · Blog
OWASP ZAP Home Lab Setup — ตั้ง Lab ทดสอบ Security ที่บ้าน
บทความ

OWASP ZAP Home Lab Setup — ตั้ง Lab ทดสอบ Security ที่บ้าน

เผยแพร่ 28 พฤษภาคม 2569

OWASP ZAP Home Lab

OWASP ZAP Home Lab Setup — ตั้ง Lab ทดสอบ Security ที่บ้าน

OWASP ZAP Home Lab Security Scanner Automated Scanning API Testing CI/CD Vulnerability Analysis OWASP Top 10 SQL Injection XSS CSRF Production

Scan TypeDurationCoverageUse CaseRisk Detection
Baseline Scan1-2 minPassive onlyEvery PR / commitLow-Medium findings
Full Scan10-30 minActive + PassiveNightly / weeklyAll risk levels
API Scan5-15 minAPI endpointsAPI changesAPI-specific vulns
Ajax Spider10-20 minSPA / JavaScriptFrontend changesClient-side vulns
Authenticated Scan15-45 minBehind loginWeeklyAuth-specific vulns

Lab Setup with Docker

=== Docker Compose Home Lab ===

docker-compose.yml

version: '3.8'

services:

zap:

image: owasp/zap2docker-stable

ports:

  • "8080:8080"
  • "8090:8090"

command: zap-webswing.sh

networks:

  • security-lab

dvwa:

image: vulnerables/web-dvwa

ports:

  • "8081:80"

environment:

MYSQL_DATABASE: dvwa

networks:

  • security-lab

juice-shop:

image: bkimminich/juice-shop

ports:

  • "3000:3000"

networks:

  • security-lab

webgoat:

image: webgoat/webgoat

ports:

  • "8082:8080"

networks:

  • security-lab

networks:

security-lab:

driver: bridge

Start lab

docker-compose up -d

ZAP CLI Quick Scan

docker run -t owasp/zap2docker-stable zap-baseline.py \

-t http://dvwa:80 \

-r report.html

ZAP Full Scan

docker run -t owasp/zap2docker-stable zap-full-scan.py \

-t http://juice-shop:3000 \

-r full-report.html \

-J full-report.json

ZAP API Scan

docker run -t owasp/zap2docker-stable zap-api-scan.py \

-t http://api-server:8000/openapi.json \

-f openapi \

-r api-report.html

from dataclasses import dataclass

@dataclass

class LabTarget:

name: str

image: str

port: int

purpose: str

difficulty: str

targets = [

LabTarget("DVWA", "vulnerables/web-dvwa", 8081,

"Classic vulnerable web app, adjustable difficulty", "Beginner"),

LabTarget("Juice Shop", "bkimminich/juice-shop", 3000,

"Modern OWASP Top 10, CTF challenges", "Beginner-Advanced"),

LabTarget("WebGoat", "webgoat/webgoat", 8082,

"Tutorial-style vulnerability learning", "Beginner"),

LabTarget("Mutillidae", "citizenstig/nowasp", 8083,

"OWASP Top 10 practice", "Intermediate"),

LabTarget("HackTheBox", "Custom VMs", 0,

"Real-world CTF challenges", "Advanced"),

]

print("=== Lab Targets ===")

for t in targets:

print(f" [{t.name}] Image: {t.image} | Port: {t.port}")

print(f" Purpose: {t.purpose}")

print(f" Difficulty: {t.difficulty}")

Automated Scanning

=== ZAP Automation Framework ===

automation.yaml

env:

contexts:

  • name: "My App"

urls: ["http://target:8080"]

authentication:

method: "form"

parameters:

loginUrl: "http://target:8080/login"

loginRequestData: "username={%username%}&password={%password%}"

verification:

method: "response"

loggedInRegex: "\\QWelcome\\E"

users:

  • name: "test-user"

credentials:

username: "admin"

password: "password"

jobs:

OWASP ZAP Home Lab Setup — ตั้ง Lab ทดสอบ Security ที่บ้าน
  • type: spider

parameters:

context: "My App"

user: "test-user"

maxDuration: 5

  • type: spiderAjax

parameters:

context: "My App"

maxDuration: 5

  • type: passiveScan-wait

parameters:

maxDuration: 10

  • type: activeScan

parameters:

context: "My App"

user: "test-user"

maxDuration: 30

  • type: report

parameters:

template: "traditional-html"

reportDir: "/zap/reports/"

reportFile: "scan-report"

Run automation

docker run -v $(pwd):/zap/wrk/:rw \

owasp/zap2docker-stable \

zap.sh -cmd -autorun /zap/wrk/automation.yaml

@dataclass

class VulnFinding:

risk: str

name: str

cwe: str

count: int

action: str

findings = [

VulnFinding("High", "SQL Injection", "CWE-89", 3,

"Use parameterized queries, input validation"),

VulnFinding("High", "Cross-Site Scripting (XSS)", "CWE-79", 5,

"Output encoding, Content Security Policy"),

VulnFinding("Medium", "Missing Security Headers", "CWE-693", 8,

"Add X-Frame-Options, CSP, HSTS headers"),

VulnFinding("Medium", "CSRF Token Missing", "CWE-352", 2,

"Implement anti-CSRF tokens"),

VulnFinding("Low", "Cookie without HttpOnly", "CWE-1004", 4,

"Set HttpOnly flag on session cookies"),

VulnFinding("Info", "Server Information Disclosure", "CWE-200", 1,

"Remove server version headers"),

]

print("\n=== Scan Findings ===")

for f in findings:

print(f" [{f.risk}] {f.name} (CWE: {f.cwe}) — {f.count} instances")

print(f" Action: {f.action}")

CI/CD Integration

=== GitHub Actions ZAP Scan ===

.github/workflows/zap-scan.yml

name: OWASP ZAP Security Scan

on:

pull_request:

branches: [main]

schedule:

  • cron: '0 2 * * *' # Nightly full scan

jobs:

baseline-scan:

if: github.event_name == 'pull_request'

runs-on: ubuntu-latest

steps:

  • uses: actions/checkout@v4
  • name: Start application

run: docker-compose up -d app

  • name: ZAP Baseline Scan

uses: zaproxy/action-baseline@v0.10.0

with:

target: 'http://localhost:8080'

rules_file_name: '.zap/rules.tsv'

fail_action: 'true'

  • uses: actions/upload-artifact@v4

with:

name: zap-baseline-report

path: report_html.html

full-scan:

if: github.event_name == 'schedule'

runs-on: ubuntu-latest

steps:

  • uses: actions/checkout@v4
  • name: Start application

run: docker-compose up -d app

  • name: ZAP Full Scan

uses: zaproxy/action-full-scan@v0.9.0

with:

target: 'http://localhost:8080'

rules_file_name: '.zap/rules.tsv'

  • name: Send to Slack

if: failure()

uses: slackapi/slack-github-action@v1

with:

payload: '{"text": "ZAP Full Scan found vulnerabilities!"}'

.zap/rules.tsv — Custom policy

10016 IGNORE (Web Browser XSS Protection Not Enabled)

10017 IGNORE (Cross-Domain JavaScript Source File Inclusion)

10021 WARN (X-Content-Type-Options Header Missing)

40012 FAIL (Cross Site Scripting - Reflected)

40014 FAIL (Cross Site Scripting - Persistent)

40018 FAIL (SQL Injection)

@dataclass

class CIPolicy:

risk: str

pr_action: str

nightly_action: str

sla: str

policies = [

CIPolicy("Critical", "Block merge", "Alert on-call + create P1 ticket", "Fix within 24 hours"),

CIPolicy("High", "Block merge", "Alert team + create P2 ticket", "Fix within 1 week"),

CIPolicy("Medium", "Warning comment", "Create P3 ticket", "Fix within 1 month"),

CIPolicy("Low", "Info only", "Log to dashboard", "Fix in next quarter"),

CIPolicy("Info", "Ignore", "Log to dashboard", "Best effort"),

]

print("CI/CD Security Policy:")

for p in policies:

print(f" [{p.risk}] PR: {p.pr_action} | Nightly: {p.nightly_action}")

print(f" SLA: {p.sla}")

เคล็ดลับ

  • Baseline: เริ่มด้วย Baseline Scan ทุก PR เร็วและไม่ Intrusive
  • Isolated: รัน Lab ใน Docker Network แยก ไม่ Scan ระบบอื่น
  • Auth: ตั้ง Authentication Context สำหรับ Scan หลัง Login
  • Policy: กำหนด Rules ว่า Finding ไหน FAIL ไหน WARN ไหน IGNORE
  • Legal: Scan เฉพาะระบบที่ได้รับอนุญาต ไม่ Scan ระบบคนอื่น

OWASP ZAP คืออะไร

Open Source Security Scanner OWASP Active Passive Spider Fuzzer SQL Injection XSS CSRF OWASP Top 10 GUI CLI API CI/CD ฟรี

ตั้ง Home Lab อย่างไร

Docker Desktop ZAP DVWA Juice Shop WebGoat Docker Compose Network แยก Browser Proxy 8080 Certificate HTTPS Interception

Automated Scan ทำอย่างไร

CLI API zap-baseline.py 1-2 นาที zap-full-scan.py 10-30 นาที zap-api-scan.py OpenAPI Context Authentication Alert Threshold Report HTML JSON

ใช้ใน CI/CD อย่างไร

GitHub Actions GitLab CI Jenkins Docker owasp/zap2docker Baseline PR Full Nightly Report Slack Email Policy FAIL WARN IGNORE

สรุป

OWASP ZAP Home Lab Docker DVWA Juice Shop Automated Scanning Baseline Full API CI/CD GitHub Actions Policy Vulnerability OWASP Top 10 Production Security