feat: Enhance sensitive data redaction with expanded key list #39
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build, Run and Validate | |
permissions: | |
contents: read | |
pull-requests: write | |
on: | |
push: | |
branches: | |
- main | |
pull_request: | |
branches: | |
- main | |
workflow_dispatch: | |
jobs: | |
build-run-validate: | |
name: Build Run and validate | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout Code | |
uses: actions/checkout@v3 | |
- name: Install Dependencies | |
run: | | |
sudo apt update | |
sudo apt install -y wget git build-essential curl python3 python3-pip | |
- name: Install Go 1.23.4 | |
uses: actions/setup-go@v4 | |
with: | |
go-version: '1.23.4' | |
- name: Validate Go Installation | |
run: | | |
go version | |
if ! go version | grep -q "go1.23.4"; then | |
echo "Go installation failed or incorrect version" | |
exit 1 | |
fi | |
- name: Clone caddy-waf Repository | |
run: | | |
git clone https://github.com/fabriziosalmi/caddy-waf.git | |
cd caddy-waf | |
- name: Validate Repository Cloning | |
run: | | |
if [ ! -d "caddy-waf" ]; then | |
echo "Repository cloning failed" | |
exit 1 | |
fi | |
- name: Install Go Dependencies | |
run: | | |
cd caddy-waf | |
go mod tidy | |
go get -v github.com/fabriziosalmi/caddy-waf github.com/caddyserver/caddy/v2 github.com/oschwald/maxminddb-golang | |
- name: Download GeoLite2 Country Database | |
run: | | |
cd caddy-waf | |
wget https://git.io/GeoLite2-Country.mmdb | |
- name: Validate GeoLite2 Download | |
run: | | |
cd caddy-waf | |
if [ ! -f "GeoLite2-Country.mmdb" ]; then | |
echo "GeoLite2 database download failed" | |
exit 1 | |
fi | |
- name: Install Python Dependencies | |
run: | | |
python3 -m venv venv | |
source venv/bin/activate | |
pip install --upgrade pip | |
pip install tqdm requests | |
- name: Cache Python Dependencies | |
id: cache-pip | |
uses: actions/cache@v3 | |
with: | |
path: ~/.cache/pip | |
key: pip-${{ runner.os }}-${{ hashFiles('**/requirements.txt') }} | |
restore-keys: | | |
pip-${{ runner.os }}- | |
- name: Retrieve and Initialize IP and DNS Blacklists | |
run: | | |
cd caddy-waf | |
source ../venv/bin/activate # Activate the virtual environment | |
echo "Running get_blacklisted_ip.py..." | |
python3 get_blacklisted_ip.py | |
if [ $? -ne 0 ]; then | |
echo "Failed to retrieve or initialize IP blacklist" | |
exit 1 | |
fi | |
echo "IP blacklist retrieved and initialized successfully." | |
echo "Running get_blacklisted_dns.py..." | |
python3 get_blacklisted_dns.py | |
if [ $? -ne 0 ]; then | |
echo "Failed to retrieve or initialize DNS blacklist" | |
exit 1 | |
fi | |
echo "DNS blacklist retrieved and initialized successfully." | |
- name: Build Caddy with caddy-waf | |
run: | | |
cd caddy-waf | |
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest | |
xcaddy build --with github.com/fabriziosalmi/caddy-waf=./ | |
- name: Validate Build | |
run: | | |
cd caddy-waf | |
if [ ! -f "caddy" ]; then | |
echo "Caddy build failed" | |
exit 1 | |
fi | |
- name: Create Dynamic Files | |
run: | | |
cd caddy-waf | |
# Create a valid JWT token for testing | |
echo "Creating valid.jwt..." | |
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" > valid.jwt | |
# Create a sample JSON file for testing | |
echo "Creating sample.json..." | |
echo '{"key": "value"}' > sample.json | |
echo "Dynamic files created successfully." | |
- name: Test Caddy Run and Validate WAF Provisioning | |
run: | | |
cd caddy-waf | |
chmod +x caddy | |
./caddy run > caddy_output.log 2>&1 & | |
sleep 5 | |
if ! pgrep -f "caddy run"; then | |
echo "Caddy run failed" | |
cat caddy_output.log | |
exit 1 | |
fi | |
if ! grep -q "WAF middleware provisioned successfully" caddy_output.log; then | |
echo "WAF provisioning log not found" | |
cat caddy_output.log | |
exit 1 | |
fi | |
echo "Caddy WAF build and run successful with WAF middleware provisioned" | |
- name: Run Phase-Specific Curl Tests | |
run: | | |
cd caddy-waf | |
# Phase 1: Allow legitimate traffic (User-Agent) | |
echo "Testing Phase 1: Allow legitimate traffic..." | |
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -A "Mozilla/5.0" http://localhost:8080) | |
if [ "$RESPONSE" != "200" ]; then | |
echo "Failed: Legitimate request was blocked. Expected HTTP 200, got $RESPONSE" | |
exit 1 | |
else | |
echo "Success: Legitimate request allowed (HTTP 200)." | |
fi | |
# Phase 1: Block known vulnerability scanners (User-Agent) | |
echo "Testing Phase 1: Block known vulnerability scanners..." | |
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -A "nikto" http://localhost:8080) | |
if [ "$RESPONSE" != "403" ]; then | |
echo "Failed: Vulnerability scanner request was not blocked. Expected HTTP 403, got $RESPONSE" | |
exit 1 | |
else | |
echo "Success: Vulnerability scanner request blocked (HTTP 403)." | |
fi | |
# Phase 2: Block NoSQL injection in body | |
echo "Testing Phase 2: Block NoSQL injection..." | |
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X POST -d '{"$gt": ""}' http://localhost:8080) | |
if [ "$RESPONSE" != "403" ]; then | |
echo "Failed: NoSQL injection request was not blocked. Expected HTTP 403, got $RESPONSE" | |
exit 1 | |
else | |
echo "Success: NoSQL injection request blocked (HTTP 403)." | |
fi | |
# Phase 3: Block HTTP response splitting (Headers) | |
echo "Testing Phase 3: Block HTTP response splitting..." | |
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -H "X-Forwarded-For: 127.0.0.1\r\nInjected-Header: value" http://localhost:8080) | |
if [ "$RESPONSE" != "403" ]; then | |
echo "Failed: HTTP response splitting request was not blocked. Expected HTTP 403, got $RESPONSE" | |
exit 1 | |
else | |
echo "Success: HTTP response splitting request blocked (HTTP 403)." | |
fi | |
# Phase 4: Block JWT tampering (Headers) | |
echo "Testing Phase 4: Block JWT tampering..." | |
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" http://localhost:8080) | |
if [ "$RESPONSE" != "403" ]; then | |
echo "Failed: JWT tampering request was not blocked. Expected HTTP 403, got $RESPONSE" | |
exit 1 | |
else | |
echo "Success: JWT tampering request blocked (HTTP 403)." | |
fi | |
echo "All phase-specific WAF rule tests passed successfully!" | |
- name: Clean Up | |
if: always() | |
run: | | |
pkill -f "caddy run" || true | |
echo "Cleaned up running Caddy instances" |