fix(integration): resolve WAF test authentication order
Moves user registration/login before proxy host creation in the
Coraza integration test. The /api/v1/proxy-hosts endpoint requires
authentication, but the script was attempting to create the host
before logging in.
Changes:
- Move auth block after httpbin ready, before proxy host create
- Add -b ${TMP_COOKIE} to all proxy-host curl commands
- Remove duplicate auth block
Fixes CI failure in waf-integration.yml workflow.
This commit is contained in:
146
docs/plans/waf_integration_fix.md
Normal file
146
docs/plans/waf_integration_fix.md
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
# WAF Integration Test Fix Plan
|
||||||
|
|
||||||
|
## Status: Pending Implementation
|
||||||
|
|
||||||
|
## Problem Summary
|
||||||
|
|
||||||
|
The WAF integration test (`scripts/coraza_integration.sh`) fails with HTTP 401 because the proxy host creation endpoint requires authentication, but the script attempts to create the proxy host **before** registering and logging in.
|
||||||
|
|
||||||
|
## Root Cause Analysis
|
||||||
|
|
||||||
|
### Current Flow (Broken)
|
||||||
|
|
||||||
|
Looking at the script execution order:
|
||||||
|
|
||||||
|
1. **Lines 175-200**: Creates proxy host without authentication
|
||||||
|
- `curl -s -X POST ... http://localhost:8080/api/v1/proxy-hosts` (no cookie)
|
||||||
|
- Returns HTTP 401 Unauthorized
|
||||||
|
|
||||||
|
2. **Lines 202-210**: Registers user and logs in (too late)
|
||||||
|
- Creates `TMP_COOKIE` file
|
||||||
|
- Successfully authenticates
|
||||||
|
|
||||||
|
3. **Lines 217-227**: Creates WAF ruleset (correctly uses cookie)
|
||||||
|
- Uses `-b ${TMP_COOKIE}` ✓
|
||||||
|
|
||||||
|
### Evidence from CI Logs
|
||||||
|
|
||||||
|
```
|
||||||
|
{"client":"172.18.0.1","latency":"433.811µs","level":"info","method":"POST","msg":"handled request","path":"/api/v1/proxy-hosts","request_id":"26716960-4547-496b-8271-2acdcdda9872","status":401}
|
||||||
|
```
|
||||||
|
|
||||||
|
The 401 status confirms the proxy host endpoint now requires authentication.
|
||||||
|
|
||||||
|
## Required Changes
|
||||||
|
|
||||||
|
### 1. Move Authentication Before Proxy Host Creation
|
||||||
|
|
||||||
|
The user registration and login block (currently lines 207-210) must be moved **before** the proxy host creation (currently lines 175-200).
|
||||||
|
|
||||||
|
### 2. Add Cookie to Proxy Host Creation
|
||||||
|
|
||||||
|
The `CREATE_RESP` curl command on line 188 needs `-b ${TMP_COOKIE}` added.
|
||||||
|
|
||||||
|
### 3. Add Cookie to Fallback Update Command
|
||||||
|
|
||||||
|
The fallback `curl -s -X PUT` command on line 195 needs `-b ${TMP_COOKIE}` added.
|
||||||
|
|
||||||
|
### 4. Add Cookie to Unauthenticated Proxy Host List
|
||||||
|
|
||||||
|
The `curl -s http://localhost:8080/api/v1/proxy-hosts` on line 191 needs `-b ${TMP_COOKIE}` added.
|
||||||
|
|
||||||
|
## Detailed Line Changes
|
||||||
|
|
||||||
|
### Step 1: Add Authentication Block After API Ready Check (After Line 146)
|
||||||
|
|
||||||
|
Insert the following after the API ready check loop and **before** the proxy host creation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "Registering admin user and logging in to retrieve session cookie..."
|
||||||
|
TMP_COOKIE=$(mktemp)
|
||||||
|
curl -s -X POST -H "Content-Type: application/json" -d '{"email":"integration@example.local","password":"password123","name":"Integration Tester"}' http://localhost:8080/api/v1/auth/register >/dev/null || true
|
||||||
|
curl -s -X POST -H "Content-Type: application/json" -d '{"email":"integration@example.local","password":"password123"}' -c ${TMP_COOKIE} http://localhost:8080/api/v1/auth/login >/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Remove Duplicate Authentication Block (Lines 207-210)
|
||||||
|
|
||||||
|
Delete or comment out the existing authentication block that appears after proxy host creation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# REMOVE THESE LINES:
|
||||||
|
echo "Registering admin user and logging in to retrieve session cookie..."
|
||||||
|
TMP_COOKIE=$(mktemp)
|
||||||
|
curl -s -X POST -H "Content-Type: application/json" -d '{"email":"integration@example.local","password":"password123","name":"Integration Tester"}' http://localhost:8080/api/v1/auth/register >/dev/null || true
|
||||||
|
curl -s -X POST -H "Content-Type: application/json" -d '{"email":"integration@example.local","password":"password123"}' -c ${TMP_COOKIE} http://localhost:8080/api/v1/auth/login >/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Add Cookie to Proxy Host Creation (Line 188)
|
||||||
|
|
||||||
|
Change:
|
||||||
|
```bash
|
||||||
|
CREATE_RESP=$(curl -s -w "\n%{http_code}" -X POST -H "Content-Type: application/json" -d "${PROXY_HOST_PAYLOAD}" http://localhost:8080/api/v1/proxy-hosts)
|
||||||
|
```
|
||||||
|
|
||||||
|
To:
|
||||||
|
```bash
|
||||||
|
CREATE_RESP=$(curl -s -w "\n%{http_code}" -X POST -H "Content-Type: application/json" -d "${PROXY_HOST_PAYLOAD}" -b ${TMP_COOKIE} http://localhost:8080/api/v1/proxy-hosts)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Add Cookie to Proxy Host List (Line 191)
|
||||||
|
|
||||||
|
Change:
|
||||||
|
```bash
|
||||||
|
EXISTING_UUID=$(curl -s http://localhost:8080/api/v1/proxy-hosts | grep -o '{[^}]*"domain_names":"integration.local"[^}]*}' | head -n1 | grep -o '"uuid":"[^"]*"' | sed 's/"uuid":"\([^"]*\)"/\1/')
|
||||||
|
```
|
||||||
|
|
||||||
|
To:
|
||||||
|
```bash
|
||||||
|
EXISTING_UUID=$(curl -s -b ${TMP_COOKIE} http://localhost:8080/api/v1/proxy-hosts | grep -o '{[^}]*"domain_names":"integration.local"[^}]*}' | head -n1 | grep -o '"uuid":"[^"]*"' | sed 's/"uuid":"\([^"]*\)"/\1/')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 5: Add Cookie to Proxy Host Update (Line 195)
|
||||||
|
|
||||||
|
Change:
|
||||||
|
```bash
|
||||||
|
curl -s -X PUT -H "Content-Type: application/json" -d "${PROXY_HOST_PAYLOAD}" http://localhost:8080/api/v1/proxy-hosts/$EXISTING_UUID
|
||||||
|
```
|
||||||
|
|
||||||
|
To:
|
||||||
|
```bash
|
||||||
|
curl -s -X PUT -H "Content-Type: application/json" -d "${PROXY_HOST_PAYLOAD}" -b ${TMP_COOKIE} http://localhost:8080/api/v1/proxy-hosts/$EXISTING_UUID
|
||||||
|
```
|
||||||
|
|
||||||
|
## Corrected Flow
|
||||||
|
|
||||||
|
After the fix, the script will execute in this order:
|
||||||
|
|
||||||
|
1. Build/start containers
|
||||||
|
2. Wait for API ready
|
||||||
|
3. **Register user and login** (create TMP_COOKIE)
|
||||||
|
4. Start httpbin backend container
|
||||||
|
5. **Create proxy host WITH cookie**
|
||||||
|
6. Create WAF ruleset with cookie
|
||||||
|
7. Enable WAF globally with cookie
|
||||||
|
8. Run WAF tests
|
||||||
|
9. Cleanup
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
After implementing the fix, the test should:
|
||||||
|
|
||||||
|
1. Return HTTP 201 (or 200 for update) for proxy host creation
|
||||||
|
2. Proceed to WAF ruleset creation successfully
|
||||||
|
3. Complete the full BLOCK mode and MONITOR mode tests
|
||||||
|
|
||||||
|
## Related Files
|
||||||
|
|
||||||
|
- `scripts/coraza_integration.sh` - Main integration test script
|
||||||
|
- `.github/skills/scripts/skill-runner.sh` - Skill runner that invokes the test
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The script already correctly uses authentication for:
|
||||||
|
- WAF ruleset creation (line 218)
|
||||||
|
- Security config updates (lines 223, 274)
|
||||||
|
- Proxy host deletion in cleanup (line 294)
|
||||||
|
- Only the proxy host creation and related fallback commands were missing authentication
|
||||||
18
scripts/coraza_integration.sh
Normal file → Executable file
18
scripts/coraza_integration.sh
Normal file → Executable file
@@ -176,6 +176,11 @@ for i in {1..20}; do
|
|||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
echo "Registering admin user and logging in to retrieve session cookie..."
|
||||||
|
TMP_COOKIE=$(mktemp)
|
||||||
|
curl -s -X POST -H "Content-Type: application/json" -d '{"email":"integration@example.local","password":"password123","name":"Integration Tester"}' http://localhost:8080/api/v1/auth/register >/dev/null || true
|
||||||
|
curl -s -X POST -H "Content-Type: application/json" -d '{"email":"integration@example.local","password":"password123"}' -c ${TMP_COOKIE} http://localhost:8080/api/v1/auth/login >/dev/null
|
||||||
|
|
||||||
echo "Creating proxy host 'integration.local' pointing to backend..."
|
echo "Creating proxy host 'integration.local' pointing to backend..."
|
||||||
PROXY_HOST_PAYLOAD=$(cat <<EOF
|
PROXY_HOST_PAYLOAD=$(cat <<EOF
|
||||||
{
|
{
|
||||||
@@ -189,26 +194,21 @@ PROXY_HOST_PAYLOAD=$(cat <<EOF
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
CREATE_RESP=$(curl -s -w "\n%{http_code}" -X POST -H "Content-Type: application/json" -d "${PROXY_HOST_PAYLOAD}" http://localhost:8080/api/v1/proxy-hosts)
|
CREATE_RESP=$(curl -s -w "\n%{http_code}" -X POST -H "Content-Type: application/json" -d "${PROXY_HOST_PAYLOAD}" -b ${TMP_COOKIE} http://localhost:8080/api/v1/proxy-hosts)
|
||||||
CREATE_STATUS=$(echo "$CREATE_RESP" | tail -n1)
|
CREATE_STATUS=$(echo "$CREATE_RESP" | tail -n1)
|
||||||
if [ "$CREATE_STATUS" != "201" ]; then
|
if [ "$CREATE_STATUS" != "201" ]; then
|
||||||
echo "Proxy host create failed or already exists; attempting to update existing host..."
|
echo "Proxy host create failed or already exists; attempting to update existing host..."
|
||||||
# Find the existing host UUID by searching for the domain in the proxy-hosts list
|
# Find the existing host UUID by searching for the domain in the proxy-hosts list
|
||||||
EXISTING_UUID=$(curl -s http://localhost:8080/api/v1/proxy-hosts | grep -o '{[^}]*"domain_names":"integration.local"[^}]*}' | head -n1 | grep -o '"uuid":"[^"]*"' | sed 's/"uuid":"\([^"]*\)"/\1/')
|
EXISTING_UUID=$(curl -s -b ${TMP_COOKIE} http://localhost:8080/api/v1/proxy-hosts | grep -o '{[^}]*"domain_names":"integration.local"[^}]*}' | head -n1 | grep -o '"uuid":"[^"]*"' | sed 's/"uuid":"\([^"]*\)"/\1/')
|
||||||
if [ -n "$EXISTING_UUID" ]; then
|
if [ -n "$EXISTING_UUID" ]; then
|
||||||
echo "Updating existing host $EXISTING_UUID with Coraza handler"
|
echo "Updating existing host $EXISTING_UUID with Coraza handler"
|
||||||
curl -s -X PUT -H "Content-Type: application/json" -d "${PROXY_HOST_PAYLOAD}" http://localhost:8080/api/v1/proxy-hosts/$EXISTING_UUID
|
curl -s -X PUT -H "Content-Type: application/json" -d "${PROXY_HOST_PAYLOAD}" -b ${TMP_COOKIE} http://localhost:8080/api/v1/proxy-hosts/$EXISTING_UUID
|
||||||
else
|
else
|
||||||
echo "Could not find existing host; create response:"
|
echo "Could not find existing host; create response:"
|
||||||
echo "$CREATE_RESP"
|
echo "$CREATE_RESP"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Registering admin user and logging in to retrieve session cookie..."
|
|
||||||
TMP_COOKIE=$(mktemp)
|
|
||||||
curl -s -X POST -H "Content-Type: application/json" -d '{"email":"integration@example.local","password":"password123","name":"Integration Tester"}' http://localhost:8080/api/v1/auth/register >/dev/null || true
|
|
||||||
curl -s -X POST -H "Content-Type: application/json" -d '{"email":"integration@example.local","password":"password123"}' -c ${TMP_COOKIE} http://localhost:8080/api/v1/auth/login >/dev/null
|
|
||||||
|
|
||||||
echo "Give Caddy a moment to apply configuration..."
|
echo "Give Caddy a moment to apply configuration..."
|
||||||
sleep 3
|
sleep 3
|
||||||
|
|
||||||
@@ -304,7 +304,7 @@ echo "Cleaning up..."
|
|||||||
|
|
||||||
# Delete the integration test proxy host from DB before stopping container
|
# Delete the integration test proxy host from DB before stopping container
|
||||||
echo "Removing integration test proxy host from database..."
|
echo "Removing integration test proxy host from database..."
|
||||||
INTEGRATION_UUID=$(curl -s http://localhost:8080/api/v1/proxy-hosts | grep -o '"uuid":"[^"]*"[^}]*"domain_names":"integration.local"' | head -n1 | grep -o '"uuid":"[^"]*"' | sed 's/"uuid":"\([^"]*\)"/\1/')
|
INTEGRATION_UUID=$(curl -s -b ${TMP_COOKIE} http://localhost:8080/api/v1/proxy-hosts | grep -o '"uuid":"[^"]*"[^}]*"domain_names":"integration.local"' | head -n1 | grep -o '"uuid":"[^"]*"' | sed 's/"uuid":"\([^"]*\)"/\1/')
|
||||||
if [ -n "$INTEGRATION_UUID" ]; then
|
if [ -n "$INTEGRATION_UUID" ]; then
|
||||||
curl -s -X DELETE -b ${TMP_COOKIE} "http://localhost:8080/api/v1/proxy-hosts/${INTEGRATION_UUID}?delete_uptime=true" >/dev/null
|
curl -s -X DELETE -b ${TMP_COOKIE} "http://localhost:8080/api/v1/proxy-hosts/${INTEGRATION_UUID}?delete_uptime=true" >/dev/null
|
||||||
echo "✓ Deleted integration proxy host ${INTEGRATION_UUID}"
|
echo "✓ Deleted integration proxy host ${INTEGRATION_UUID}"
|
||||||
|
|||||||
Reference in New Issue
Block a user