mirror of
https://github.com/fosrl/pangolin.git
synced 2026-05-21 09:21:15 -05:00
[GH-ISSUE #1614] Denial on IP Rules should not indicate 401 or that the resource exists #8726
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @curious-debug on GitHub (Oct 4, 2025).
Original GitHub issue: https://github.com/fosrl/pangolin/issues/1614
Describe the Bug
When visiting a resource having Resource Rules that the IP of the end user does not pass (i.e., IP is denied), the response is currently "401 unauthorized". Not only is this incorrect per IETF HTTP Semantics, but this presents a security concern, as the end user now has knowledge that the URL exists. A better security posture should not return any response.
UPDATED RECOMMENDED ACTION
Per insightful discussion with @hhftechnology below, and this comment, the best path forward is this:
When not satisfying any IP Rules, admin should be able to select one of these for what happens next:
My original post primarily suggested sending no response, so as to not inform the failed IP visitor that the resource exists. @hhftechnology suggested keeping the 401 for its use case. Thus, the best option is to allow the admin flexibility to choose the course of action when visiting a resource fails all IP Rules, allowing the admin to pursue further logging/tracking and/or security, as best determined by the admin.
Below is original post.
In this discussion requesting "Always Deny if NOT IP Address Match", I discovered that I can create a "catch all" rule using 0.0.0.0/24 to deny visitors from visiting a resource if their IP address does not match. However, when visiting the resource from outside the allowed IP range, the response is "401 Unauthorized". This raised a red flag. Attackers visiting this resource now have knowledge that there indeed is a live resource behind the URL, and that resource can be now probed/attacked. A better response to visiting a resource that fails the IP check should be no response at all.
Environment
To Reproduce
Expected Behavior
The request should not return anything.
Per IETF docs: "The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource." So, returning a 401 is not really right here, because the issue isn’t missing credentials; it’s denial of access regardless of credentials.
"403 Forbidden" means “we know what you’re asking for, but you’re not allowed," and although this is the most technically correct status to reject a request due to an access control policy (like an IP restriction), that also reveals knowledge that the URL/path exists.
"404 Not Found" still indicates that a server is present at that resource URL/subdomain name.
To obtain security by obscurity, Pangolin shouldn't inform outsiders that the resource exists, so it should silently drop the connection.
Or, we should at least have the option of choosing what to do if the Resource Rules config fails (e.g. choose 403, 404, or no response/connection drop).
@oschwartz10612 commented on GitHub (Oct 5, 2025):
Thanks for bringing this up! We should definitely implement this fix across badger and pangolin.
@curious-debug commented on GitHub (Oct 5, 2025):
You're welcome @oschwartz10612 . Also looking forward to the ability to manage Authentication and IP Rules in one place, so that authentication and rules can be applied to, and edited on, multiple resources, without having to edit each resource individually. @Pallavikumarimdb indicated working on this, but hopefully, whatever is done is a wholesome approach and considers Authentication Sets as well, and not just IP Rule Sets.
@hhftechnology commented on GitHub (Oct 5, 2025):
its was changed from 400 to 401.
401 is the correct code(404/ any other would be misleading). Why it is imp. because security apps like crowdsec reads these code and blocks and ban them if they continuously hammer this path.
if they all return 401 as unauthorized i don't think there is even a need for a custom collection/parser.
external display can be altered but i dont know how that will be helpful.
"Security through obscurity" is a weak and unreliable security approach
@hhftechnology commented on GitHub (Oct 5, 2025):
not needed as per my understanding in security.
@curious-debug commented on GitHub (Oct 8, 2025):
What was changed from 400 to 401?
As pointed out above, 401 is not correct, per IETF/RFC: "The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. The server generating a 401 response MUST send a WWW-Authenticate header field (Section 11.6.1) containing at least one challenge applicable to the target resource."
IP Rule failure in Pangolin is not due to a "lack of valid authentication credentials for the target resource", nor is Pangolin, in its 401 response here (or in any IP Rule failure response), then sending a WWW-Authenticate header field containing at least one challenge applicable to the target resource.
My aforementioned "security by obscurity" is not the correct terminology per se. It is simply this — "no response on IP Rule failure" — so that outsiders will not know that the resource exists.
Also, not everyone uses CrowdSec.
@hhftechnology commented on GitHub (Oct 8, 2025):
Any reactive L7 firewall will need logs. how you plan to inform that firewall about bad actors if the error code is removed or manipulated?
Your words

@curious-debug commented on GitHub (Oct 9, 2025):
@hhftechnology
Provide the correct error code, or track the attempts and do something else. Give that option to the admin, as proposed above.
Also my words:
My aforementioned "security by obscurity" is not the correct terminology per se. It is simply this — "no response on IP Rule failure" — so that outsiders will not know that the resource exists.Sounds like you are here just to argue, rather than propose solutions. People just love hanging out with those.
@hhftechnology commented on GitHub (Oct 9, 2025):
for me 401 works, that was my solution. we don't have to create a separate parser if 401 code is there in the logs.
@curious-debug commented on GitHub (Oct 10, 2025):
@hhftechnology Got it. With that, I think giving us the option to choose what happens on an IP Rule denial would be best. For your use case, for example, 401 works. For others, they might want a 404 Not Found, or just no response altogether, so as to not inform the IP-failed requestor that there is a resource behind the URL.
The last sentence in the OP suggested that:
Or, we should at least have the option of choosing what to do if the Resource Rules config fails (e.g. choose 403, 404, or no response/connection drop).Also should include 401 for your case. So, perhaps this:When not satisfying any IP Rules, choose what happens:
This would provide the best design for customer-desired flexibility, logging, security, and/or response.
@curious-debug commented on GitHub (Oct 10, 2025):
FYI: To capture the flexibility approach from my previous comment, I updated the first post to include a section entitled "UPDATED RECOMMENDED ACTION", suggesting pursuit of the options listed above.
@hhftechnology commented on GitHub (Oct 10, 2025):
Just an FYI, https://github.com/traefik/traefik/issues/10290
404 to drop.
https://community.traefik.io/t/is-there-a-way-to-for-traefik-to-silently-drop-requests-instead-of-sending-a-404-responses/20541/2
@hhftechnology commented on GitHub (Oct 10, 2025):
so basically, in traefik its not possible so it will not be in pangolin. but you can definitely change codes with plugins, a lot of them are available. you don't need devs permission or help to do. you can do that for each resource (a different code)
@hhftechnology commented on GitHub (Oct 19, 2025):
@oschwartz10612 can you please close this issues