Skip to content

Commit 0951a06

Browse files
yadijrousskov
andcommitted
Bug 3390: Proxy auth data visible to scripts (#2249)
Original changes to redact credentials from error page %R code expansion output was incomplete. It missed the parse failure case where ErrorState::request_hdrs raw buffer contained sensitive information. Also missed was the %W case where full request message headers were generated in a mailto link. This case is especially problematic as it may be delivered over insecure SMTP even if the error was secured with HTTPS. After this change: * The HttpRequest message packing code for error pages is de-duplicated and elides authentication headers for both %R and %W code outputs. * The %R code output includes the CRLF request message terminator. * The email_err_data directive causing advanced details to be added to %W mailto links is disabled by default. Also redact credentials from generated TRACE responses. --------- Co-authored-by: Alex Rousskov <[email protected]>
1 parent 86043c6 commit 0951a06

File tree

8 files changed

+26
-27
lines changed

8 files changed

+26
-27
lines changed

doc/release-notes/release-7.sgml.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ This section gives an account of those changes in three categories:
211211
<tag>logformat</tag>
212212
<p>Removed <em>%ui</em> format code with Ident protocol support.
213213

214+
<tag>email_err_data</tag>
215+
<p>Since Squid-7.2, the default for this directive is <em>off</em>.
216+
214217
<tag>external_acl_type</tag>
215218
<p>Removed <em>%IDENT</em> format code with Ident protocol support.
216219

src/HttpRequest.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,16 +341,16 @@ HttpRequest::swapOut(StoreEntry * e)
341341

342342
/* packs request-line and headers, appends <crlf> terminator */
343343
void
344-
HttpRequest::pack(Packable * p) const
344+
HttpRequest::pack(Packable * const p, const bool maskSensitiveInfo) const
345345
{
346346
assert(p);
347347
/* pack request-line */
348348
p->appendf(SQUIDSBUFPH " " SQUIDSBUFPH " HTTP/%d.%d\r\n",
349349
SQUIDSBUFPRINT(method.image()), SQUIDSBUFPRINT(url.path()),
350350
http_ver.major, http_ver.minor);
351351
/* headers */
352-
header.packInto(p);
353-
/* trailer */
352+
header.packInto(p, maskSensitiveInfo);
353+
/* indicate the end of the header section */
354354
p->append("\r\n", 2);
355355
}
356356

src/HttpRequest.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ class HttpRequest: public Http::Message
206206

207207
void swapOut(StoreEntry * e);
208208

209-
void pack(Packable * p) const;
209+
void pack(Packable * p, bool maskSensitiveInfo = false) const;
210210

211211
static void httpRequestPack(void *obj, Packable *p);
212212

src/cf.data.pre

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8912,12 +8912,18 @@ NAME: email_err_data
89128912
COMMENT: on|off
89138913
TYPE: onoff
89148914
LOC: Config.onoff.emailErrData
8915-
DEFAULT: on
8915+
DEFAULT: off
89168916
DOC_START
89178917
If enabled, information about the occurred error will be
89188918
included in the mailto links of the ERR pages (if %W is set)
89198919
so that the email body contains the data.
89208920
Syntax is <A HREF="mailto:%w%W">%w</A>
8921+
8922+
SECURITY WARNING:
8923+
Request headers and other included facts may contain
8924+
sensitive information about transaction history, the
8925+
Squid instance, and its environment which would be
8926+
unavailable to error recipients otherwise.
89218927
DOC_END
89228928

89238929
NAME: deny_info

src/client_side_reply.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ clientReplyContext::clientReplyContext(ClientHttpRequest *clientContext) :
9292
void
9393
clientReplyContext::setReplyToError(
9494
err_type err, Http::StatusCode status, char const *uri,
95-
const ConnStateData *conn, HttpRequest *failedrequest, const char *unparsedrequest,
95+
const ConnStateData *conn, HttpRequest *failedrequest, const char *,
9696
#if USE_AUTH
9797
Auth::UserRequest::Pointer auth_user_request
9898
#else
@@ -102,9 +102,6 @@ clientReplyContext::setReplyToError(
102102
{
103103
auto errstate = clientBuildError(err, status, uri, conn, failedrequest, http->al);
104104

105-
if (unparsedrequest)
106-
errstate->request_hdrs = xstrdup(unparsedrequest);
107-
108105
#if USE_AUTH
109106
errstate->auth_user_request = auth_user_request;
110107
#endif
@@ -1004,11 +1001,14 @@ clientReplyContext::traceReply()
10041001
triggerInitialStoreRead();
10051002
http->storeEntry()->releaseRequest();
10061003
http->storeEntry()->buffer();
1004+
MemBuf content;
1005+
content.init();
1006+
http->request->pack(&content, true /* hide authorization data */);
10071007
const HttpReplyPointer rep(new HttpReply);
1008-
rep->setHeaders(Http::scOkay, nullptr, "text/plain", http->request->prefixLen(), 0, squid_curtime);
1008+
rep->setHeaders(Http::scOkay, nullptr, "message/http", content.contentSize(), 0, squid_curtime);
1009+
rep->body.set(SBuf(content.buf, content.size));
10091010
http->storeEntry()->replaceHttpReply(rep);
1010-
http->request->swapOut(http->storeEntry());
1011-
http->storeEntry()->complete();
1011+
http->storeEntry()->completeSuccessfully("traceReply() stored the entire response");
10121012
}
10131013

10141014
#define SENDING_BODY 0

src/errorpage.cc

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,6 @@ ErrorState::~ErrorState()
837837

838838
safe_free(redirect_url);
839839
safe_free(url);
840-
safe_free(request_hdrs);
841840
wordlistDestroy(&ftp.server_msg);
842841
safe_free(ftp.request);
843842
safe_free(ftp.reply);
@@ -887,7 +886,7 @@ ErrorState::Dump(MemBuf * mb)
887886
body << "HTTP Request:\r\n";
888887
MemBuf r;
889888
r.init();
890-
request->pack(&r);
889+
request->pack(&r, true /* hide authorization data */);
891890
body << r.content();
892891
}
893892

@@ -1149,18 +1148,10 @@ ErrorState::compileLegacyCode(Build &build)
11491148
p = "[no request]";
11501149
break;
11511150
}
1152-
if (request) {
1153-
mb.appendf(SQUIDSBUFPH " " SQUIDSBUFPH " %s/%d.%d\n",
1154-
SQUIDSBUFPRINT(request->method.image()),
1155-
SQUIDSBUFPRINT(request->url.path()),
1156-
AnyP::ProtocolType_str[request->http_ver.protocol],
1157-
request->http_ver.major, request->http_ver.minor);
1158-
request->header.packInto(&mb, true); //hide authorization data
1159-
} else if (request_hdrs) {
1160-
p = request_hdrs;
1161-
} else {
1151+
else if (request)
1152+
request->pack(&mb, true /* hide authorization data */);
1153+
else
11621154
p = "[no request]";
1163-
}
11641155
break;
11651156

11661157
case 's':

src/errorpage.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ class ErrorState
193193
MemBuf *listing = nullptr;
194194
} ftp;
195195

196-
char *request_hdrs = nullptr;
197196
char *err_msg = nullptr; /* Preformatted error message from the cache */
198197

199198
AccessLogEntryPointer ale; ///< transaction details (or nil)

src/tests/stub_HttpRequest.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ bool HttpRequest::expectingBody(const HttpRequestMethod &, int64_t &) const STUB
4545
bool HttpRequest::bodyNibbled() const STUB_RETVAL(false)
4646
int HttpRequest::prefixLen() const STUB_RETVAL(0)
4747
void HttpRequest::swapOut(StoreEntry *) STUB
48-
void HttpRequest::pack(Packable *) const STUB
48+
void HttpRequest::pack(Packable *, bool) const STUB
4949
void HttpRequest::httpRequestPack(void *, Packable *) STUB
5050
HttpRequest * HttpRequest::FromUrl(const SBuf &, const MasterXaction::Pointer &, const HttpRequestMethod &) STUB_RETVAL(nullptr)
5151
HttpRequest * HttpRequest::FromUrlXXX(const char *, const MasterXaction::Pointer &, const HttpRequestMethod &) STUB_RETVAL(nullptr)

0 commit comments

Comments
 (0)