name: Update Patterns permissions: contents: write # Commit changes, push updates statuses: write # Update commit statuses actions: read # Required for checking out the repository packages: write # For GitHub Packages (if used) on: schedule: - cron: '0 0 * * *' # Daily at midnight UTC workflow_dispatch: # Manual trigger jobs: update-owasp-waf: runs-on: ubuntu-latest steps: - name: ๐Ÿšš Checkout Repository uses: actions/checkout@v3 with: fetch-depth: 0 # get full git history - name: โš™๏ธ Set Up Python 3.11 uses: actions/setup-python@v4 with: python-version: '3.11' - name: ๐Ÿ“ฆ Cache pip dependencies uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} restore-keys: | ${{ runner.os }}-pip- - name: ๐Ÿ“ฅ Install Dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: ๐Ÿ•ท๏ธ Run OWASP Scraper run: python owasp2json.py - name: ๐Ÿ”„ Convert OWASP to Nginx WAF run: python json2nginx.py - name: ๐Ÿ”„ Convert OWASP to Apache WAF run: python json2apache.py - name: ๐Ÿ”„ Convert OWASP to Traefik WAF run: python json2traefik.py - name: ๐Ÿ”„ Convert OWASP to HAProxy WAF run: python json2haproxy.py - name: ๐Ÿ”„ Generate Bad Bot Blockers run: python badbots.py - name: ๐Ÿš€ Commit and Push Changes (if any) run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add . # Check if there are any changes *before* committing. if ! git diff --quiet --exit-code; then git commit -m "Update WAF rules [$(date +'%Y-%m-%d')]" git push else echo "No changes to commit." fi continue-on-error: true # Continue even if no changes - name: ๐Ÿ“ฆ Create Zip Archives run: | mkdir -p dist (cd waf_patterns/nginx && zip -r ../../dist/nginx_waf.zip .) (cd waf_patterns/apache && zip -r ../../dist/apache_waf.zip .) (cd waf_patterns/traefik && zip -r ../../dist/traefik_waf.zip .) (cd waf_patterns/haproxy && zip -r ../../dist/haproxy_waf.zip .) - name: ๐Ÿ—‘๏ธ Delete Existing 'latest' Tag and Release (if they exist) run: | # Delete local tag git tag -d latest || true # Delete remote tag (force) git push --delete origin latest || true # Delete release, --yes for confirmation gh release delete latest --yes || true env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: ๐Ÿ“ Generate release notes if: success() run: | set -euo pipefail BUILD_DATE=$(date -u +'%Y-%m-%d') # Latest CRS tag (falls back to v4.0 if API is unreachable) CRS_REF=$(curl -sfL https://api.github.com/repos/coreruleset/coreruleset/releases/latest \ | jq -r '.tag_name // "v4.0"' 2>/dev/null || echo "v4.0") # OWASP source coverage TOTAL_RULES=$(jq length owasp_rules.json) CATEGORIES=$(jq -r '.[].category' owasp_rules.json | sort -u | wc -l | tr -d ' ') # Bot pattern counts per backend NGINX_BOTS=$(grep -c '^\s*"~' waf_patterns/nginx/bots.conf || echo 0) APACHE_BOTS=$(grep -c '^SecRule REQUEST_HEADERS' waf_patterns/apache/bots.conf || echo 0) TRAEFIK_BOTS=$(grep -cE '^\s*"' waf_patterns/traefik/bots.toml || echo 0) HAPROXY_BOTS=$(grep -c '^acl' waf_patterns/haproxy/bots.acl || echo 0) # Archive sizes (human-readable) NGINX_SIZE=$(du -h dist/nginx_waf.zip | cut -f1) APACHE_SIZE=$(du -h dist/apache_waf.zip | cut -f1) TRAEFIK_SIZE=$(du -h dist/traefik_waf.zip | cut -f1) HAPROXY_SIZE=$(du -h dist/haproxy_waf.zip | cut -f1) # SHA-256 checksums NGINX_SHA=$(sha256sum dist/nginx_waf.zip | cut -d' ' -f1) APACHE_SHA=$(sha256sum dist/apache_waf.zip | cut -d' ' -f1) TRAEFIK_SHA=$(sha256sum dist/traefik_waf.zip | cut -d' ' -f1) HAPROXY_SHA=$(sha256sum dist/haproxy_waf.zip | cut -d' ' -f1) cat > release_notes.md <