[prev in list] [next in list] [prev in thread] [next in thread] 

List:       bugtraq
Subject:    Re: Simple way to bypass squid ACLs [preleminary patch]
From:       Henrik Nordstrom <hno () HEM ! PASSAGEN ! SE>
Date:       1998-02-21 1:28:45
[Download RAW message or body]

Vitaly V. Fedrushkov wrote:

> Software:       Squid Internet Object Cache
> Version:        1.1.20 (at least)
> Summary:        any URL-based ACLs can be bypassed using
>                 simple rewriting
> Impact:         renders any access control based on url_regex
>                 and/or urlpath_regex unusable

Confirmed for all current Squid releases (1.1.20 and 1.2beta15).

[some examples and details deleted]

> Workaround
> ~~~~~~~~~~
[rexep workaround deleted]
> 2. Use some request-rewriting software at proxy port to canonify
> request and forward it to squid.  This breaks port- and IDENT-based
> rules.

This breaks HTTP 1.1. In HTTP 1.1 a proxy is explicitly forbidden to
transform URLs. If a client has escaped a URL in a certain way it is
required that it arrives on the same format to the server, since a
escaped url may result in a different object.

What should be done is to temporarily unescape the URL for ACL
processing only. I have attached preleminary patches for Squid 1.1.2 and
1.2beta15 (preleminary == only basic testing completed, not official).

The patches is available from http://hem.passagen.se/hno/squid/ as well.

---
Henrik Nordström
Sparetime Squid Hacker

["squid-1.1.20.escaped_url_acl.patch" (text/plain)]

Index: squid-1.1.20/src/acl.c
--- squid-1.1.20/src/acl.c      Mon Nov  3 20:27:08 1997
+++ squid-1.1.20.henrik/src/acl.c       Sat Feb 21 00:42:01 1998
@@ -1105,10 +1105,10 @@
        return aclMatchTime(acl->data, squid_curtime);
        /* NOTREACHED */
     case ACL_URLPATH_REGEX:
-       return aclMatchRegex(acl->data, r->urlpath);
+       return aclMatchRegex(acl->data, checklist->urlpath);
        /* NOTREACHED */
     case ACL_URL_REGEX:
-       return aclMatchRegex(acl->data, urlCanonical(r, NULL));
+       return aclMatchRegex(acl->data, checklist->url);
        /* NOTREACHED */
     case ACL_URL_PORT:
        return aclMatchInteger(acl->data, r->port);
Index: squid-1.1.20/src/acl.h
--- squid-1.1.20/src/acl.h      Thu Feb 20 22:03:10 1997
+++ squid-1.1.20.henrik/src/acl.h       Sat Feb 21 00:43:41 1998
@@ -124,6 +124,8 @@
     struct in_addr dst_addr;
     char src_fqdn[SQUIDHOSTNAMELEN];
     request_t *request;
+    char url[MAX_URL];
+    char *urlpath;
     char ident[ICP_IDENT_SZ];
     char browser[BROWSERNAMELEN];
     acl_lookup_state state[ACL_ENUM_MAX];
Index: squid-1.1.20/src/client_side.c
--- squid-1.1.20/src/client_side.c      Wed Nov 19 17:44:51 1997
+++ squid-1.1.20.henrik/src/client_side.c       Sat Feb 21 01:03:07 1998
@@ -31,6 +31,8 @@

 #include "squid.h"

+extern void rfc1738_unescape _PARAMS((char *));
+
 static void clientRedirectDone _PARAMS((void *data, char *result));
 static void icpHandleIMSReply _PARAMS((int fd, StoreEntry * entry, void *data));
 static void clientLookupDstIPDone _PARAMS((int fd, const ipcache_addrs *, void *data));
@@ -155,6 +157,19 @@
        icpState->aclChecklist = xcalloc(1, sizeof(aclCheck_t));
        icpState->aclChecklist->src_addr = icpState->peer.sin_addr;
        icpState->aclChecklist->request = requestLink(icpState->request);
+       strcpy(icpState->aclChecklist->url,
+             urlCanonical(icpState->request, NULL));
+       rfc1738_unescape(icpState->aclChecklist->url);
+       icpState->aclChecklist->urlpath =
+             strchr(icpState->aclChecklist->url, '/');
+       if (icpState->aclChecklist->urlpath != NULL)
+           icpState->aclChecklist->urlpath =
+                 strchr(icpState->aclChecklist->url+1, '/');
+       if (icpState->aclChecklist->urlpath != NULL)
+           icpState->aclChecklist->urlpath =
+                 strchr(icpState->aclChecklist->url+1, '/');
+       if (icpState->aclChecklist->urlpath == NULL)
+           icpState->aclChecklist->urlpath = "";
        browser = mime_get_header(icpState->request_hdr, "User-Agent");
        if (browser != NULL) {
            xstrncpy(icpState->aclChecklist->browser, browser, BROWSERNAMELEN);
Index: squid-1.1.20/src/neighbors.c
--- squid-1.1.20/src/neighbors.c        Sat Nov  1 02:34:19 1997
+++ squid-1.1.20.henrik/src/neighbors.c Sat Feb 21 01:00:37 1998
@@ -105,6 +105,8 @@

 #include "squid.h"

+extern void rfc1738_unescape _PARAMS((char *));
+
 /* count mcast group peers every 15 minutes */
 #define MCAST_COUNT_RATE 900

@@ -246,6 +248,15 @@
     }
     checklist.src_addr = request->client_addr;
     checklist.request = request;
+    strcpy(checklist.url, urlCanonical(request, NULL));
+    rfc1738_unescape(checklist.url);
+    checklist.urlpath = strchr(checklist.url, '/');
+    if (checklist.urlpath != NULL)
+       checklist.urlpath = strchr(checklist.urlpath+1, '/');
+    if (checklist.urlpath != NULL)
+       checklist.urlpath = strchr(checklist.urlpath+1, '/');
+    if (checklist.urlpath == NULL)
+       checklist.urlpath = "";
     for (a = e->acls; a; a = a->next) {
        if (aclMatchAcl(a->acl, &checklist))
            return a->op;

["squid-1.2.beta15.escaped_url_acl.patch" (text/plain)]

Index: squid/src/acl.c
diff -u squid/src/acl.c:1.1.1.12 squid/src/acl.c:1.1.1.12.2.1
--- squid/src/acl.c:1.1.1.12    Sat Feb 14 01:00:20 1998
+++ squid/src/acl.c     Sat Feb 21 01:05:32 1998
@@ -1300,10 +1300,10 @@
        return aclMatchTime(acl->data, squid_curtime);
        /* NOTREACHED */
     case ACL_URLPATH_REGEX:
-       return aclMatchRegex(acl->data, r->urlpath);
+       return aclMatchRegex(acl->data, checklist->urlpath);
        /* NOTREACHED */
     case ACL_URL_REGEX:
-       return aclMatchRegex(acl->data, urlCanonical(r, NULL));
+       return aclMatchRegex(acl->data, checklist->url);
        /* NOTREACHED */
     case ACL_URL_PORT:
        return aclMatchInteger(acl->data, r->port);
@@ -1547,6 +1547,16 @@
     cbdataLock(A);
     checklist->request = requestLink(request);
     checklist->src_addr = src_addr;
+    /* Build a unescaped URL & path */
+    strcpy(checklist->url, urlCanonical(request, NULL));
+    rfc1738_unescape(checklist->url);
+    checklist->urlpath=strchr(checklist->url, '/');
+    if (checklist->urlpath != NULL)
+       checklist->urlpath=strchr(checklist->urlpath+1, '/');
+    if (checklist->urlpath != NULL)
+       checklist->urlpath=strchr(checklist->urlpath+1, '/');
+    if (checklist->urlpath == NULL)
+       checklist->urlpath = "";
     for (i = 0; i < ACL_ENUM_MAX; i++)
        checklist->state[i] = ACL_LOOKUP_NONE;
     if (user_agent)
Index: squid/src/structs.h
diff -u squid/src/structs.h:1.1.1.13 squid/src/structs.h:1.1.1.13.2.1
--- squid/src/structs.h:1.1.1.13        Sat Feb 14 01:00:34 1998
+++ squid/src/structs.h Sat Feb 21 01:05:34 1998
@@ -111,6 +111,8 @@
     struct in_addr src_addr;
     struct in_addr dst_addr;
     request_t *request;
+    char url[MAX_URL];
+    char *urlpath;
     char ident[ICP_IDENT_SZ];
     char browser[BROWSERNAMELEN];
     acl_lookup_state state[ACL_ENUM_MAX];


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic