-
Notifications
You must be signed in to change notification settings - Fork 6
IBX-11181: Filtered client-supplied X-Forwarded-* headers in Varnish VCL #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 4.6
Are you sure you want to change the base?
Changes from all commits
1fa648c
c978b5a
4341459
552ac38
15d27f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -81,6 +81,22 @@ jobs: | |||||
| - name: Run test suite | ||||||
| run: composer run-script --timeout=600 test | ||||||
|
|
||||||
| varnish-vcl-tests: | ||||||
| name: Varnish VCL tests | ||||||
| runs-on: "ubuntu-24.04" | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| timeout-minutes: 10 | ||||||
|
|
||||||
| steps: | ||||||
| - uses: actions/checkout@v7 | ||||||
|
|
||||||
| - name: Build varnishtest image | ||||||
| run: docker build -t ibexa-varnishtest:7 tests/varnish | ||||||
|
|
||||||
| - name: Run varnishtest suite | ||||||
| env: | ||||||
| IMAGE_VARNISH7: ibexa-varnishtest:7 | ||||||
| run: tests/varnish/run.sh varnish7.vcl | ||||||
|
|
||||||
| integration-tests: | ||||||
| name: "REST integration tests" | ||||||
| uses: ibexa/rest/.github/workflows/integration-tests-callable.yaml@4.6 | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,6 +47,32 @@ | |
| AUTOMATION_CLIENT_INSTALLATION: ${{ secrets.AUTOMATION_CLIENT_INSTALLATION }} | ||
| AUTOMATION_CLIENT_SECRET: ${{ secrets.AUTOMATION_CLIENT_SECRET }} | ||
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | ||
| varnish7-trusted-proxy: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question. |
||
| name: "Varnish 7 integration tests (trusted proxy)" | ||
| uses: ibexa/gh-workflows/.github/workflows/browser-tests.yml@main | ||
| with: | ||
| project-edition: 'oss' | ||
| setup: "doc/docker/base-dev.yml:doc/docker/varnish7.yml:doc/docker/varnish-trusted-proxy.yml:doc/docker/selenium.yml" | ||
| test-suite: '--mode=standard --profile=httpCache --suite=varnish-trusted-proxy' | ||
| test-setup-phase-1: '--mode=standard --profile=httpCache --suite=setup' | ||
| secrets: | ||
| AUTOMATION_CLIENT_ID: ${{ secrets.AUTOMATION_CLIENT_ID }} | ||
| AUTOMATION_CLIENT_INSTALLATION: ${{ secrets.AUTOMATION_CLIENT_INSTALLATION }} | ||
| AUTOMATION_CLIENT_SECRET: ${{ secrets.AUTOMATION_CLIENT_SECRET }} | ||
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | ||
| varnish6-trusted-proxy: | ||
| name: "Varnish 6 integration tests (trusted proxy)" | ||
| uses: ibexa/gh-workflows/.github/workflows/browser-tests.yml@main | ||
|
Check failure on line 65 in .github/workflows/browser-tests.yaml
|
||
| with: | ||
| project-edition: 'oss' | ||
| setup: "doc/docker/base-dev.yml:doc/docker/varnish.yml:doc/docker/varnish-trusted-proxy.yml:doc/docker/selenium.yml" | ||
| test-suite: '--mode=standard --profile=httpCache --suite=varnish-trusted-proxy' | ||
| test-setup-phase-1: '--mode=standard --profile=httpCache --suite=setup' | ||
| secrets: | ||
| AUTOMATION_CLIENT_ID: ${{ secrets.AUTOMATION_CLIENT_ID }} | ||
| AUTOMATION_CLIENT_INSTALLATION: ${{ secrets.AUTOMATION_CLIENT_INSTALLATION }} | ||
| AUTOMATION_CLIENT_SECRET: ${{ secrets.AUTOMATION_CLIENT_SECRET }} | ||
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | ||
| varnish6-translation-aware: | ||
| name: "Varnish integration tests (translation-aware)" | ||
| uses: ibexa/gh-workflows/.github/workflows/browser-tests.yml@main | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "recipesEndpoint": "", | ||
| "packages": [ | ||
| { | ||
| "requirement": "dev-IBX-11181-Trusted_Proxies_is_not_set_on_Ibexa_Cloud as 4.6.x-dev", | ||
| "repositoryUrl": "https://github.com/ibexa/docker", | ||
| "package": "ibexa/docker", | ||
| "shouldBeAddedAsVCS": false | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| @varnish6 @varnish7 | ||
| Feature: As a site administrator I want Varnish to drop reverse proxy headers sent by clients | ||
|
|
||
| # The application trusts X-Forwarded-* as soon as framework.trusted_proxies is configured, so a | ||
| # client must not be able to set them. Varnish strips them for every client that is not listed | ||
| # in the trusted_proxies ACL - which is every client here, as the ACL deliberately does not | ||
| # contain the Docker network. | ||
| # | ||
| # The rendered page reports the headers the application received, since that cannot be observed | ||
| # from the response alone. See src/bundle/Resources/views/tests/cache/proxy_headers.html.twig. | ||
|
|
||
| @admin | ||
| Scenario Outline: Client supplied reverse proxy headers never reach the application | ||
| Given I create "proxyHeadersContentType" Content items in root in "eng-GB" | ||
| | name | | ||
| | <itemName> | | ||
| And I am viewing the pages on siteaccess "site" as "<user>" "<password>" | ||
| And I set request header "X-Forwarded-Host" to "evil.example" | ||
| And I set request header "X-Forwarded-Proto" to "https" | ||
| And I set request header "X-Forwarded-Port" to "443" | ||
| And I set request header "X-Forwarded-Prefix" to "/admin" | ||
| And I set request header "X-Forwarded-For" to "6.6.6.6" | ||
| And I set request header "X-Client-IP" to "6.6.6.6" | ||
| And I set request header "Client-Cdn" to "fastly" | ||
| And I set request header "Forwarded" to "for=6.6.6.6;host=evil.example;proto=https" | ||
| When I visit "<itemName>" on siteaccess "site" | ||
| # A cache hit would show the headers of whichever request populated the cache | ||
| And response headers contain | ||
| | Header | Value | | ||
| | x-cache | MISS | | ||
| Then I should see "XFHOST:-" | ||
| And I should see "XFPROTO:-" | ||
| And I should see "XFPREFIX:-" | ||
| And I should see "FORWARDED:-" | ||
| And I should see "XCLIENTIP:-" | ||
| And I should see "CLIENTCDN:-" | ||
| # Derived by the VCL from the stripped X-Forwarded-Proto, not taken from the client | ||
| And I should see "XFPORT:80" | ||
| # X-Forwarded-For is overwritten with the real client IP rather than unset | ||
| And I should not see "6.6.6.6" | ||
| And I should not see "evil.example" | ||
|
|
||
| Examples: | ||
| | user | password | itemName | | ||
| | admin | publish | ProxyProbeAdmin | | ||
| | anonymous | | ProxyProbeAnonymous | | ||
|
|
||
| # Runs only with the varnish-trusted-proxy overlay applied, where the app container is added to the | ||
| # trusted_proxies ACL. Guards against the filtering degrading into a blanket strip, which would | ||
| # break every setup with a TLS terminator, load balancer or CDN in front of Varnish. | ||
| @admin @trustedProxy | ||
| Scenario: Reverse proxy headers from a trusted proxy do reach the application | ||
| Given I create "proxyHeadersContentType" Content items in root in "eng-GB" | ||
| | name | | ||
| | ProxyProbeTrusted | | ||
| And I am viewing the pages on siteaccess "site" as "anonymous" "" | ||
| And I set request header "X-Forwarded-Host" to "upstream.example" | ||
| And I set request header "X-Forwarded-Proto" to "https" | ||
| And I set request header "X-Forwarded-Prefix" to "/admin" | ||
| And I set request header "X-Client-IP" to "203.0.113.9" | ||
| And I set request header "Client-Cdn" to "fastly" | ||
| When I visit "ProxyProbeTrusted" on siteaccess "site" | ||
| And response headers contain | ||
| | Header | Value | | ||
| | x-cache | MISS | | ||
| Then I should see "XFHOST:upstream.example" | ||
| And I should see "XFPROTO:https" | ||
| And I should see "XFPREFIX:/admin" | ||
| And I should see "XCLIENTIP:203.0.113.9" | ||
| And I should see "CLIENTCDN:fastly" | ||
| # Derived by the VCL from the trusted X-Forwarded-Proto | ||
| And I should see "XFPORT:443" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| {# Renders the reverse proxy headers as the application received them. | ||
|
|
||
| Used by features/varnish/proxyHeaders.feature to assert what Varnish forwarded to the backend, | ||
| which cannot be observed from the response alone. Test fixture, not part of the public API. #} | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <title>Proxy headers received by the application</title> | ||
| </head> | ||
| <body> | ||
| <div id="proxy-headers"> | ||
| <div>XFF:{{ app.request.headers.get('x-forwarded-for')|default('-') }}</div> | ||
| <div>XFHOST:{{ app.request.headers.get('x-forwarded-host')|default('-') }}</div> | ||
| <div>XFPROTO:{{ app.request.headers.get('x-forwarded-proto')|default('-') }}</div> | ||
| <div>XFPORT:{{ app.request.headers.get('x-forwarded-port')|default('-') }}</div> | ||
| <div>XFPREFIX:{{ app.request.headers.get('x-forwarded-prefix')|default('-') }}</div> | ||
| <div>FORWARDED:{{ app.request.headers.get('forwarded')|default('-') }}</div> | ||
| <div>XCLIENTIP:{{ app.request.headers.get('x-client-ip')|default('-') }}</div> | ||
| <div>CLIENTCDN:{{ app.request.headers.get('client-cdn')|default('-') }}</div> | ||
| </div> | ||
| </body> | ||
| </html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alongosz is this setup aligned with the current, org-wise CI adjustments?