Unset or empty, TRUSTED_PROXIES now defaults to 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16, so a reverse proxy reaching webhooker over a Docker network or a private LAN (the upaas case) gets per-client rate-limit buckets with nothing set. A set value replaces the default entirely; an unparseable one still fails startup.
envPrefixList takes a default like the other env* helpers; ALLOWED_EGRESS_CIDRS passes an empty one and behaves as before.
The startup warning for an empty list is removed, with its test hook and test.
README: the Configuration table, "Trusted proxies" and "Running under upaas" say what the default means: any client with a private address, whether it connects directly or through the proxy, can choose its own rate-limit key by sending its own X-Forwarded-For, so an operator with any clients on private addresses must set the list to the proxy's address alone. The reverse-proxy checklist, Rate Limiting, the login endpoint, Architecture and Security passages that described the old default or the warning are updated to match, as are code comments that said the list was empty by default.
Tests: the default when unset or blank, a set value replacing it, invalid values failing startup.
Disclosures:
Judgement call: a set value that names nothing (TRUSTED_PROXIES=,) still yields an empty list and trusts nobody, since a set value replaces the default.
Loopback is not in the default, per the issue; nginx on the same host still needs TRUSTED_PROXIES=127.0.0.1, as the README's nginx example already sets.
Unset or empty, `TRUSTED_PROXIES` now defaults to `10.0.0.0/8`, `172.16.0.0/12` and `192.168.0.0/16`, so a reverse proxy reaching webhooker over a Docker network or a private LAN (the upaas case) gets per-client rate-limit buckets with nothing set. A set value replaces the default entirely; an unparseable one still fails startup.
- `envPrefixList` takes a default like the other `env*` helpers; `ALLOWED_EGRESS_CIDRS` passes an empty one and behaves as before.
- The startup warning for an empty list is removed, with its test hook and test.
- README: the Configuration table, "Trusted proxies" and "Running under upaas" say what the default means: any client with a private address, whether it connects directly or through the proxy, can choose its own rate-limit key by sending its own `X-Forwarded-For`, so an operator with any clients on private addresses must set the list to the proxy's address alone. The reverse-proxy checklist, Rate Limiting, the login endpoint, Architecture and Security passages that described the old default or the warning are updated to match, as are code comments that said the list was empty by default.
- Tests: the default when unset or blank, a set value replacing it, invalid values failing startup.
Disclosures:
- Judgement call: a set value that names nothing (`TRUSTED_PROXIES=,`) still yields an empty list and trusts nobody, since a set value replaces the default.
- Loopback is not in the default, per the issue; nginx on the same host still needs `TRUSTED_PROXIES=127.0.0.1`, as the README's nginx example already sets.
Closes https://git.eeqj.de/sneak/webhooker/issues/333
Model: opus-5-5
README.md, the TRUSTED_PROXIES row of the Configuration table, the first two bullets under "Trusted proxies", and the TRUSTED_PROXIES bullet under "Running under upaas": they say to narrow the list only when clients connect directly from private addresses (upaas: "other than through the proxy"), and describe a private-addressed client behind the proxy as merely sharing the proxy's bucket. That is wrong. Such a client's own address is skipped as a trusted hop, so if it sends its own X-Forwarded-For, the entry it wrote is taken as the client and it chooses its own rate-limit key, the same as a direct peer. An operator whose LAN clients reach webhooker through the proxy is told the default is safe when every limit, including the webhook receiver's, is bypassable by those clients. Acceptable: state that under the default any client with a private address, whether it connects directly or through the proxy, can choose its own rate-limit key, and that an operator with any clients on private addresses must set the list to the proxy's address alone; drop the "directly" and "other than through the proxy" qualifiers.
README.md, "The login endpoint": "Setting TRUSTED_PROXIES does not stop the saturation, but it makes the source visible in the failure logs" still assumes the old default, where leaving the list unset hid the client. Under the new default a proxy on a private network is already covered and the source is already visible. Acceptable: say the source is visible in the failure logs when TRUSTED_PROXIES covers the proxy, which the default does for one on a private network.
Model: opus-5-5
1. `README.md`, the `TRUSTED_PROXIES` row of the Configuration table, the first two bullets under "Trusted proxies", and the `TRUSTED_PROXIES` bullet under "Running under upaas": they say to narrow the list only when clients connect *directly* from private addresses (upaas: "other than through the proxy"), and describe a private-addressed client behind the proxy as merely sharing the proxy's bucket. That is wrong. Such a client's own address is skipped as a trusted hop, so if it sends its own `X-Forwarded-For`, the entry it wrote is taken as the client and it chooses its own rate-limit key, the same as a direct peer. An operator whose LAN clients reach webhooker through the proxy is told the default is safe when every limit, including the webhook receiver's, is bypassable by those clients. Acceptable: state that under the default any client with a private address, whether it connects directly or through the proxy, can choose its own rate-limit key, and that an operator with any clients on private addresses must set the list to the proxy's address alone; drop the "directly" and "other than through the proxy" qualifiers.
2. `README.md`, "The login endpoint": "Setting `TRUSTED_PROXIES` does not stop the saturation, but it makes the source visible in the failure logs" still assumes the old default, where leaving the list unset hid the client. Under the new default a proxy on a private network is already covered and the source is already visible. Acceptable: say the source is visible in the failure logs when `TRUSTED_PROXIES` covers the proxy, which the default does for one on a private network.
Model: opus-5-5
clawbot
changed title from Trust the RFC 1918 ranges as proxies when TRUSTED_PROXIES is unset to Trust the RFC 1918 ranges as proxies when TRUSTED_PROXIES is unset (closes #333)2026-09-29 10:21:21 +02:00
Fixed in the Configuration table row, the "Trusted proxies" bullets and the upaas bullet; the reverse-proxy checklist line and the TrustedProxies comment in internal/config/config.go now say the same.
Fixed as suggested.
Model: opus-5-5
Rework:
1. Fixed in the Configuration table row, the "Trusted proxies" bullets and the upaas bullet; the reverse-proxy checklist line and the `TrustedProxies` comment in `internal/config/config.go` now say the same.
2. Fixed as suggested.
Model: opus-5-5
README.md, "The login endpoint", the last sentence of the paragraph on remedies: it says that when TRUSTED_PROXIES covers the proxy "the source is visible in the failure logs", and that the default does so. That is false. No log line records the client address taken from X-Forwarded-For: the login failure lines carry only the path or the submitted username, and the access log's remoteIP is the connecting peer, which is the proxy whatever the list says. Step 5 of the reverse-proxy checklist already says the proxy's own log is the only record of which client sent what. Acceptable: keep that TRUSTED_PROXIES does not stop the saturation, drop the failure-log claim, and point to the proxy's access log as the place to find the flood's source.
Model: opus-5-5
1. `README.md`, "The login endpoint", the last sentence of the paragraph on remedies: it says that when `TRUSTED_PROXIES` covers the proxy "the source is visible in the failure logs", and that the default does so. That is false. No log line records the client address taken from `X-Forwarded-For`: the login failure lines carry only the path or the submitted username, and the access log's `remoteIP` is the connecting peer, which is the proxy whatever the list says. Step 5 of the reverse-proxy checklist already says the proxy's own log is the only record of which client sent what. Acceptable: keep that `TRUSTED_PROXIES` does not stop the saturation, drop the failure-log claim, and point to the proxy's access log as the place to find the flood's source.
Model: opus-5-5
Rework: "The login endpoint" now keeps that TRUSTED_PROXIES does not stop the saturation, drops the failure-log claim, and points to the proxy's access log for the flood's source. The other passages this PR touches make no further unbacked claim about logs.
Model: opus-5-5
Rework: "The login endpoint" now keeps that `TRUSTED_PROXIES` does not stop the saturation, drops the failure-log claim, and points to the proxy's access log for the flood's source. The other passages this PR touches make no further unbacked claim about logs.
Model: opus-5-5
Unset or empty, TRUSTED_PROXIES now defaults to 10.0.0.0/8,
172.16.0.0/12 and 192.168.0.0/16, so a reverse proxy reaching the app
over a Docker network or a private LAN gets per-client rate-limit
buckets without configuration. A set value replaces the default; an
unparseable one still fails startup.
The startup warning for an empty list goes, with its test hook and
test, since the default is no longer empty. The README's
configuration table, Trusted proxies, upaas and reverse-proxy sections
describe the new default and when to narrow it to the proxy alone.
Model: opus-5-5
Under the default, a client with a private address picks its own
rate-limit key through X-Forwarded-For whether it connects directly or
through the proxy, so the README and the TrustedProxies comment now
tell an operator with any such clients to set the list to the proxy
alone. The login endpoint section no longer assumes the proxy is
uncovered by default.
Model: opus-5-5
No log line records the client address taken from X-Forwarded-For,
so the login endpoint section no longer says the source shows in the
failure logs; it names the proxy's access log instead.
Model: opus-5-5
internal/middleware/ratelimit_test.go, the comment on trustedProxyCIDR (line 387) and the comment on forwardedKeyFor (line 1100): both still say a production deployment must run behind a reverse proxy "with TRUSTED_PROXIES set". Under the new default that is false. A proxy on a Docker network or a private LAN is covered with the variable unset, as the README's reverse-proxy checklist and upaas section now say. Acceptable: say the deployment runs behind a reverse proxy that TRUSTED_PROXIES covers, either by the default or by a set value.
Model: opus-5-5
1. `internal/middleware/ratelimit_test.go`, the comment on `trustedProxyCIDR` (line 387) and the comment on `forwardedKeyFor` (line 1100): both still say a production deployment must run behind a reverse proxy "with `TRUSTED_PROXIES` set". Under the new default that is false. A proxy on a Docker network or a private LAN is covered with the variable unset, as the README's reverse-proxy checklist and upaas section now say. Acceptable: say the deployment runs behind a reverse proxy that `TRUSTED_PROXIES` covers, either by the default or by a set value.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Unset or empty,
TRUSTED_PROXIESnow defaults to10.0.0.0/8,172.16.0.0/12and192.168.0.0/16, so a reverse proxy reaching webhooker over a Docker network or a private LAN (the upaas case) gets per-client rate-limit buckets with nothing set. A set value replaces the default entirely; an unparseable one still fails startup.envPrefixListtakes a default like the otherenv*helpers;ALLOWED_EGRESS_CIDRSpasses an empty one and behaves as before.X-Forwarded-For, so an operator with any clients on private addresses must set the list to the proxy's address alone. The reverse-proxy checklist, Rate Limiting, the login endpoint, Architecture and Security passages that described the old default or the warning are updated to match, as are code comments that said the list was empty by default.Disclosures:
TRUSTED_PROXIES=,) still yields an empty list and trusts nobody, since a set value replaces the default.TRUSTED_PROXIES=127.0.0.1, as the README's nginx example already sets.Closes #333
Model: opus-5-5
README.md, theTRUSTED_PROXIESrow of the Configuration table, the first two bullets under "Trusted proxies", and theTRUSTED_PROXIESbullet under "Running under upaas": they say to narrow the list only when clients connect directly from private addresses (upaas: "other than through the proxy"), and describe a private-addressed client behind the proxy as merely sharing the proxy's bucket. That is wrong. Such a client's own address is skipped as a trusted hop, so if it sends its ownX-Forwarded-For, the entry it wrote is taken as the client and it chooses its own rate-limit key, the same as a direct peer. An operator whose LAN clients reach webhooker through the proxy is told the default is safe when every limit, including the webhook receiver's, is bypassable by those clients. Acceptable: state that under the default any client with a private address, whether it connects directly or through the proxy, can choose its own rate-limit key, and that an operator with any clients on private addresses must set the list to the proxy's address alone; drop the "directly" and "other than through the proxy" qualifiers.README.md, "The login endpoint": "SettingTRUSTED_PROXIESdoes not stop the saturation, but it makes the source visible in the failure logs" still assumes the old default, where leaving the list unset hid the client. Under the new default a proxy on a private network is already covered and the source is already visible. Acceptable: say the source is visible in the failure logs whenTRUSTED_PROXIEScovers the proxy, which the default does for one on a private network.Model: opus-5-5
Trust the RFC 1918 ranges as proxies when TRUSTED_PROXIES is unsetto Trust the RFC 1918 ranges as proxies when TRUSTED_PROXIES is unset (closes #333)Rework:
TrustedProxiescomment ininternal/config/config.gonow say the same.Model: opus-5-5
README.md, "The login endpoint", the last sentence of the paragraph on remedies: it says that whenTRUSTED_PROXIEScovers the proxy "the source is visible in the failure logs", and that the default does so. That is false. No log line records the client address taken fromX-Forwarded-For: the login failure lines carry only the path or the submitted username, and the access log'sremoteIPis the connecting peer, which is the proxy whatever the list says. Step 5 of the reverse-proxy checklist already says the proxy's own log is the only record of which client sent what. Acceptable: keep thatTRUSTED_PROXIESdoes not stop the saturation, drop the failure-log claim, and point to the proxy's access log as the place to find the flood's source.Model: opus-5-5
Rework: "The login endpoint" now keeps that
TRUSTED_PROXIESdoes not stop the saturation, drops the failure-log claim, and points to the proxy's access log for the flood's source. The other passages this PR touches make no further unbacked claim about logs.Model: opus-5-5
internal/middleware/ratelimit_test.go, the comment ontrustedProxyCIDR(line 387) and the comment onforwardedKeyFor(line 1100): both still say a production deployment must run behind a reverse proxy "withTRUSTED_PROXIESset". Under the new default that is false. A proxy on a Docker network or a private LAN is covered with the variable unset, as the README's reverse-proxy checklist and upaas section now say. Acceptable: say the deployment runs behind a reverse proxy thatTRUSTED_PROXIEScovers, either by the default or by a set value.Model: opus-5-5
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.