Skip to content

Commit e7e9073

Browse files
yadijrousskov
andauthored
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 bbc23aa commit e7e9073

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
@@ -195,6 +195,9 @@ This section gives an account of those changes in three categories:
195195
<tag>logformat</tag>
196196
<p>Removed <em>%ui</em> format code with Ident protocol support.
197197

198+
<tag>email_err_data</tag>
199+
<p>Since Squid-7.2, the default for this directive is <em>off</em>.
200+
198201
<tag>external_acl_type</tag>
199202
<p>Removed <em>%IDENT</em> format code with Ident protocol support.
200203

src/HttpRequest.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,14 +340,14 @@ HttpRequest::swapOut(StoreEntry * e)
340340

341341
/* packs request-line and headers, appends <crlf> terminator */
342342
void
343-
HttpRequest::pack(Packable * p) const
343+
HttpRequest::pack(Packable * const p, const bool maskSensitiveInfo) const
344344
{
345345
assert(p);
346346
/* pack request-line */
347347
packFirstLineInto(p, false /* origin-form */);
348348
/* headers */
349-
header.packInto(p);
350-
/* trailer */
349+
header.packInto(p, maskSensitiveInfo);
350+
/* indicate the end of the header section */
351351
p->append("\r\n", 2);
352352
}
353353

src/HttpRequest.h

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

205205
void swapOut(StoreEntry * e);
206206

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

209209
static void httpRequestPack(void *obj, Packable *p);
210210

src/cf.data.pre

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8903,12 +8903,18 @@ NAME: email_err_data
89038903
COMMENT: on|off
89048904
TYPE: onoff
89058905
LOC: Config.onoff.emailErrData
8906-
DEFAULT: on
8906+
DEFAULT: off
89078907
DOC_START
89088908
If enabled, information about the occurred error will be
89098909
included in the mailto links of the ERR pages (if %W is set)
89108910
so that the email body contains the data.
89118911
Syntax is <A HREF="mailto:%w%W">%w</A>
8912+
8913+
SECURITY WARNING:
8914+
Request headers and other included facts may contain
8915+
sensitive information about transaction history, the
8916+
Squid instance, and its environment which would be
8917+
unavailable to error recipients otherwise.
89128918
DOC_END
89138919

89148920
NAME: deny_info

src/client_side_reply.cc

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

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

10151015
#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.originForm()),
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)