Denial on IP Rules should not indicate 401 or that the resource exists #815

Closed
opened 2026-04-05 17:47:49 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @curious-debug on 10/4/2025

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.

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:

  1. send client to Auth page;
  2. select from list of HTTP status codes to send to client (e.g.: 401 Unauthorized, 403 Forbidden, 404 Not Found, 405 Method Not Allowed, 503 Service Unavailable, custom status code, etc.); or
  3. drop connection (send no response to client).

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

  • OS Type & Version: Ubuntu 24.04
  • Pangolin Version: Community Edition (I'm not using Pangolin cloud, but it's probably the same there also)

To Reproduce

  • Create Resource
  • Create/Enable Resource Rule to "Always Deny"
  • Visit the Resource, satisfying the "Always Deny" condition
  • "401 Unauthorized" is returned

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).

*Originally created by @curious-debug on 10/4/2025* ### 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](https://github.com/fosrl/pangolin/issues/1614#issuecomment-3387880656), 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**: 1. send client to Auth page; 2. select from list of HTTP status codes to send to client (e.g.: 401 Unauthorized, 403 Forbidden, 404 Not Found, 405 Method Not Allowed, 503 Service Unavailable, custom status code, etc.); or 3. drop connection (send no response to client). 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](https://github.com/orgs/fosrl/discussions/1554) 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 - OS Type & Version: Ubuntu 24.04 - Pangolin Version: Community Edition (I'm not using Pangolin cloud, but it's probably the same there also) ### To Reproduce - Create Resource - Create/Enable Resource Rule to "Always Deny" - Visit the Resource, satisfying the "Always Deny" condition - "401 Unauthorized" is returned ### Expected Behavior The request should not return anything. Per [IETF docs](https://datatracker.ietf.org/doc/html/rfc9110#section-15.5.2): "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).
MrUnknownDE added the Security label 2026-04-05 17:47:49 +02:00
Sign in to join this conversation.
No Label Security
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/pangolin#815