{"id":40037761,"url":"https://github.com/le0developer/traefik-waf","last_synced_at":"2026-01-19T05:01:13.276Z","repository":{"id":331628549,"uuid":"1127663977","full_name":"Le0Developer/traefik-waf","owner":"Le0Developer","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-10T14:02:54.000Z","size":102,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-11T03:52:55.466Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Le0Developer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-04T11:01:01.000Z","updated_at":"2026-01-10T13:58:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Le0Developer/traefik-waf","commit_stats":null,"previous_names":["le0developer/traefik-waf"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/Le0Developer/traefik-waf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Le0Developer%2Ftraefik-waf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Le0Developer%2Ftraefik-waf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Le0Developer%2Ftraefik-waf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Le0Developer%2Ftraefik-waf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Le0Developer","download_url":"https://codeload.github.com/Le0Developer/traefik-waf/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Le0Developer%2Ftraefik-waf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28561842,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T03:31:16.861Z","status":"ssl_error","status_checked_at":"2026-01-19T03:31:15.069Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-19T05:01:11.383Z","updated_at":"2026-01-19T05:01:13.249Z","avatar_url":"https://github.com/Le0Developer.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# traefik-waf\n\nA very opinionated Web Application Firewall (WAF) for Traefik and **primarily\nfor myself**.\n\n## Demo\n\nYou can try out the WAF at https://wafdemo.leodev.xyz. It uses the OWASP Core\nRule Set (CRS) and has the Javascript challenge enabled.\n\n## Rules\n\nThis WAF uses [Coraza](https://coraza.io/) under the hood and doesn't ship with\nany rules by default. We recommend making a `rules` directory, filling it with\nthe rules from https://coraza.io/docs/tutorials/coreruleset/ and then mounting\nit to `/rules` in the container.\n\nYou must pass the environment variable `WAF_RULESET_ENABLED=true` to enable the\nruleset.\n\n## Javascript Check\n\nThis WAF includes a Javascript challenge to mitigate bots. It's disabled by\ndefault. To enable it, set the environment variable `WAF_REQUIREJS` to `true` or\nset the `x-waf-require-js` header to `1` in your requests (e.g. in a traefik\nmiddleware).\n\nThe challenge page will be served to clients that don't have a valid cookie. The\nchallenge is ~3.5kb in size (uncompressed) using the default settings.\n\nThe challenge will perform a proof-of-work check in the browser (using\n[jspowobfdata](https://github.com/le0developer/jspowobfdata)).\n\n## Customization\n\n### Partial customization\n\nYou can customize parts of the default challenge/blocked pages.\n\nYou can set the following environment variables to customize the pages:\n\n| Environment Variable | Description                   | Default Value            |\n| -------------------- | ----------------------------- | ------------------------ |\n| WAF_NAME             | Name of the WAF               | Web Application Firewall |\n| WAF_FOOTER_NAME      | Name shown in the footer      | Web Application Firewall |\n| WAF_FOOTER_URL       | URL linked in the footer name | This Github repository   |\n\nYou can also insert your own HTML into the `\u003chead\u003e` section of both pages by\nmounting a file to `/assets/head.html` in the container. This can be used for\nadding custom styles, meta tags or analytics scripts.\n\n### Full customization\n\nYou can customize the blocked page and the challenge page by mounting your own\nHTML files to `/assets/blocked.html` and `/assets/challenge.html` in the\ncontainer.\n\nThe `challenge.html` **MUST** include a `\u003c!--CHALLENGE--\u003e` marker where the\nchallenge script will be injected.\n\n### REF\n\nThe `\u003c!--REF--\u003e` marker in both HTML files will be replaced with a reference to\nthe current request ID for debugging purposes.\n\nWe will try to automatically detect this based on incoming request headers. We\nlook for:\n\n- `X-Request-ID`\n- `CF-Ray` (Cloudflare)\n- `CDN-Requestid` (Bunny.net)\n\nIf none or multiple headers are present, a WAF reference will be generated. This\nis to prevent the user from being able to manipulate the reference value by\nsending the header themselves.\n\nYou can also manually set the header to use by setting the `WAF_REF_HEADER`\nenvironment variable to the name of the header you want to use. You can also set\nthe header to an impossible value like `-` to always make the WAF generate a\nreference.\n\n## Logging\n\nBy default only WAF blocks are logged to stdout. You can increase the verbosity\nby setting the `WAF_VERBOSITY` environment variable to:\n\n| Level       | Blocks | New Challenges | Other Logs | Coraza Logs |\n| ----------- | ------ | -------------- | ---------- | ----------- |\n| 0           |        |                |            |             |\n| 1 (default) | ✓      |                |            |             |\n| 2           | ✓      | ✓              |            |             |\n| 3           | ✓      | ✓              | ✓          |             |\n| 4           | ✓      | ✓              | ✓          | ✓           |\n| 5           | ✓      | ✓              | ✓          | ✓ and TRACE |\n\n## Usage\n\n```yml\nservices:\n\ttraefik-waf:\n\t\timage: ghcr.io/le0developer/traefik-waf:latest\n\t\tenvironment:\n\t\t\t- WAF_RULESET_ENABLED=true\n\t\t\t- WAF_REQUIREJS=true\n\t\t\t- WAF_REF_HEADER=CF-Ray\n\t\tvolumes:\n\t\t\t- ./rules:/rules:ro\n\t\t\t- ./assets:/assets:ro\n\t\tlabels:\n\t\t\ttraefik.enable: true\n\t\t\ttraefik.http.routers.traefik-waf.rule: PathPrefix(`/.waf`)\n\t\t\ttraefik.http.routers.traefik-waf.middlewares: waf-replace-assets@docker\n\t\t\ttraefik.http.middlewares.waf-replace-assets.replacepathregex.regex: ^/\\.waf/(.*)\n\t\t\ttraefik.http.middlewares.waf-replace-assets.replacepathregex.replacement: /assets/$1\n\t\t\ttraefik.http.services.traefik-waf.loadbalancer.server.port: 8080\n\t\t\ttraefik.http.middlewares.waf.forwardauth.address: http://traefik-waf:8080\n\t\t\ttraefik.http.middlewares.waf.forwardauth.trustForwardHeader: true\n\t\t\ttraefik.http.middlewares.waf-requirejs.headers.customRequestHeaders.x-waf-require-js: \"1\"\n```\n\nAnd then use the `waf[@docker]` or `waf-requirejs[@docker]` middleware in your\nrouters (if y ou use `waf-requirejs`, it must be listed before the `waf`\nmiddleware).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fle0developer%2Ftraefik-waf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fle0developer%2Ftraefik-waf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fle0developer%2Ftraefik-waf/lists"}