From 053b32287a15092e049fe38b8cfecd47efe37034 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Wed, 22 Jun 2011 18:36:41 +1200 Subject: [PATCH] Bug 3243: CVE-2009-0801 Bypass of browser same-origin access control ... in intercepted communications. --- doc/release-notes/release-3.2.sgml | 4 ++++ src/acl/DestinationIp.cc | 14 ++++++++++++++ src/cf.data.pre | 30 ++++++++++++++++++++++++++++++ src/forward.cc | 19 ++++++++++++++++++- src/hier_code.h | 1 + src/structs.h | 1 + 6 files changed, 68 insertions(+), 1 deletion(-) diff --git a/doc/release-notes/release-3.2.sgml b/doc/release-notes/release-3.2.sgml index 0d67a12728..bd93292d24 100644 --- a/doc/release-notes/release-3.2.sgml +++ b/doc/release-notes/release-3.2.sgml @@ -366,6 +366,10 @@ This section gives a thorough account of those changes in three categories:

New setting for client bandwith limits to determines the client-side delay pool for the request. + client_dst_passthru +

New setting to disable Host: header security on interception proxies. + Impacts cache integrity/reliability and client browser security. + cpu_affinity_map

New setting for SMP support to map Squid processes onto specific CPU cores. diff --git a/src/acl/DestinationIp.cc b/src/acl/DestinationIp.cc index 39d3bf9fc6..93e8930927 100644 --- a/src/acl/DestinationIp.cc +++ b/src/acl/DestinationIp.cc @@ -36,7 +36,10 @@ #include "squid.h" #include "acl/DestinationIp.h" #include "acl/FilledChecklist.h" +#include "comm/Connection.h" #include "HttpRequest.h" +// for Config.* +#include "structs.h" char const * ACLDestinationIP::typeString() const @@ -48,6 +51,17 @@ int ACLDestinationIP::match(ACLChecklist *cl) { ACLFilledChecklist *checklist = Filled(cl); + + // Bug 3243: CVE 2009-0801 + // Bypass of browser same-origin access control in intercepted communication + // To resolve this we will force DIRECT and only to the original client destination. + // In which case, we also need this ACL to accurately match the destination + if (Config.onoff.client_dst_passthru && checklist->request && + (checklist->request->flags.intercepted || checklist->request->flags.spoof_client_ip)) { + assert(checklist->conn() && checklist->conn()->clientConnection != NULL); + return ACLIP::match(checklist->conn()->clientConnection->local); + } + const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->GetHost(), IP_LOOKUP_IF_MISS); if (ia) { diff --git a/src/cf.data.pre b/src/cf.data.pre index cb4f0acb3c..3af986b0ae 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1803,6 +1803,36 @@ DOC_START DOC_END +NAME: client_dst_passthru +TYPE: onoff +DEFAULT: on +LOC: Config.onoff.client_dst_passthru +DOC_START + With NAT or TPROXY intercepted traffic Squid may pass the request + directly to the original client destination IP or seek a faster + source. + + This option (on by default) prevents cache_peer and alternative DNS + entries being used on intercepted traffic. Both of which lead to + the security vulnerability outlined below. + + SECURITY WARNING: + + This directive should only be disabled if cache_peer are required. + + As described in CVE-2009-0801 when the Host: header alone is used + to determine the destination of a request it becomes trivial for + malicious scripts on remote websites to bypass browser same-origin + security policy and sandboxing protections. + + The cause of this is that such applets are allowed to perform their + own HTTP stack, in which case the same-origin policy of the browser + sandbox only verifies that the applet tries to contact the same IP + as from where it was loaded at the IP level. The Host: header may + be different from the connected IP and approved origin. + +DOC_END + COMMENT_START SSL OPTIONS ----------------------------------------------------------------------------- diff --git a/src/forward.cc b/src/forward.cc index d043092813..74264a28a9 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -116,7 +116,24 @@ void FwdState::start(Pointer aSelf) // Otherwise we are going to leak our object. entry->registerAbort(FwdState::abort, this); - peerSelect(&serverDestinations, request, entry, fwdPeerSelectionCompleteWrapper, this); + + // Bug 3243: CVE 2009-0801 + // Bypass of browser same-origin access control in intercepted communication + // To resolve this we must force DIRECT and only to the original client destination. + if (Config.onoff.client_dst_passthru && request && + (request->flags.intercepted || request->flags.spoof_client_ip)) { + Comm::ConnectionPointer p = new Comm::Connection(); + p->remote = clientConn->local; + p->peerType = ORIGINAL_DST; + getOutgoingAddress(request, p); + serverDestinations.push_back(p); + + // destination "found". continue with the forwarding. + startConnectionOrFail(); + } else { + // do full route options selection + peerSelect(&serverDestinations, request, entry, fwdPeerSelectionCompleteWrapper, this); + } } void diff --git a/src/hier_code.h b/src/hier_code.h index 23225c3760..678cb593fa 100644 --- a/src/hier_code.h +++ b/src/hier_code.h @@ -25,6 +25,7 @@ typedef enum { USERHASH_PARENT, SOURCEHASH_PARENT, PINNED, + ORIGINAL_DST, HIER_MAX } hier_code; diff --git a/src/structs.h b/src/structs.h index 1677ec5dd6..38b978780f 100644 --- a/src/structs.h +++ b/src/structs.h @@ -436,6 +436,7 @@ struct SquidConfig { int WIN32_IpAddrChangeMonitor; int memory_cache_first; int memory_cache_disk; + int client_dst_passthru; } onoff; int forward_max_tries; -- 2.47.2