Now that tools are being implemented to access the cache manager via
http:// scheme we need to accomodate the browser XSS protection
mechanisms which limit XHR based scripts abilities.
This adds CORS headers to manager responses. Permitting XHR to view the
Server header (to detect squid version for known capabilities) and to
flag that the XHR request may need access to credentials for
authenticating with the manager.
This also closes the feature bug 3407 requesting we support the
non-standard "Origin:" header, which is used by the CORS mechanisms.
Future work:
Support the OPTIONS request used by CORS to detect requirements
before POSTing. We do not yet use POST in the main code so that is left
until needed.
Amos
=== modified file 'src/HttpHeader.cc'
--- src/HttpHeader.cc 2011-12-12 16:46:49 +0000
+++ src/HttpHeader.cc 2011-12-23 09:15:25 +0000
@@ -116,6 +116,7 @@
{"Max-Forwards", HDR_MAX_FORWARDS, ftInt64},
{"Mime-Version", HDR_MIME_VERSION, ftStr}, /* for now */
{"Negotiate", HDR_NEGOTIATE, ftStr},
+ {"Origin", HDR_ORIGIN, ftStr},
{"Pragma", HDR_PRAGMA, ftStr},
{"Proxy-Authenticate", HDR_PROXY_AUTHENTICATE, ftStr},
{"Proxy-Authentication-Info", HDR_PROXY_AUTHENTICATION_INFO, ftStr},
@@ -231,6 +232,7 @@
HDR_ACCEPT_RANGES, HDR_AGE,
HDR_LOCATION, HDR_MAX_FORWARDS,
HDR_MIME_VERSION, HDR_PUBLIC, HDR_RETRY_AFTER, HDR_SERVER, HDR_SET_COOKIE,
HDR_SET_COOKIE2,
+ HDR_ORIGIN,
HDR_VARY,
HDR_WARNING, HDR_PROXY_CONNECTION, HDR_X_CACHE,
HDR_X_CACHE_LOOKUP,
@@ -249,7 +251,9 @@
static http_hdr_type RequestHeadersArr[] = {
HDR_AUTHORIZATION, HDR_FROM, HDR_HOST,
HDR_IF_MATCH, HDR_IF_MODIFIED_SINCE, HDR_IF_NONE_MATCH,
- HDR_IF_RANGE, HDR_MAX_FORWARDS, HDR_PROXY_CONNECTION,
+ HDR_IF_RANGE, HDR_MAX_FORWARDS,
+ HDR_ORIGIN,
+ HDR_PROXY_CONNECTION,
HDR_PROXY_AUTHORIZATION, HDR_RANGE, HDR_REFERER, HDR_REQUEST_RANGE,
HDR_USER_AGENT, HDR_X_FORWARDED_FOR, HDR_SURROGATE_CAPABILITY
};
=== modified file 'src/HttpHeader.h'
--- src/HttpHeader.h 2011-12-02 11:20:58 +0000
+++ src/HttpHeader.h 2011-12-23 09:17:32 +0000
@@ -101,6 +101,7 @@
HDR_MIME_VERSION, /**< RFC 2626 */
HDR_NEGOTIATE, /**< experimental RFC 2295. Why only
this one from 2295? */
/*HDR_OVERWRITE,*/ /* RFC 2518 */
+ HDR_ORIGIN, /* CORS Draft specification (see
http://www.w3.org/TR/cors/) */
HDR_PRAGMA, /**< deprecated RFC 2068,2616 header
we may need to erase */
HDR_PROXY_AUTHENTICATE, /**< RFC 2608, 2616, 2617 */
HDR_PROXY_AUTHENTICATION_INFO, /**< RFC 2617 */
=== modified file 'src/cache_manager.cc'
--- src/cache_manager.cc 2011-11-27 12:37:35 +0000
+++ src/cache_manager.cc 2011-12-23 10:14:00 +0000
@@ -371,6 +371,14 @@
*/
rep->header.putAuth("Basic", actionName);
#endif
+ // Allow cachemgr and other XHR scripts access to our version string
+ if (request->header.has(HDR_ORIGIN)) {
+
rep->header.putExt("Access-Control-Allow-Origin",request->header.getStr(HDR_ORIGIN));
+#if HAVE_AUTH_MODULE_BASIC
+ rep->header.putExt("Access-Control-Allow-Credentials","true");
+#endif
+ rep->header.putExt("Access-Control-Expose-Headers","Server");
+ }
/* store the reply */
entry->replaceHttpReply(rep);
@@ -382,6 +390,10 @@
return;
}
+ if (request->header.has(HDR_ORIGIN)) {
+ cmd->params.httpOrigin = request->header.getStr(HDR_ORIGIN);
+ }
+
debugs(16, 2, "CacheManager: " <<
userName << "@" <<
client << " requesting '" <<
=== modified file 'src/mgr/Action.cc'
--- src/mgr/Action.cc 2011-10-03 20:27:34 +0000
+++ src/mgr/Action.cc 2011-12-23 10:09:47 +0000
@@ -102,6 +102,15 @@
if (writeHttpHeader) {
HttpReply *rep = new HttpReply;
rep->setHeaders(HTTP_OK, NULL, "text/plain", -1, squid_curtime,
squid_curtime);
+ // Allow cachemgr and other XHR scripts access to our version string
+ const ActionParams ¶ms = command().params;
+ if (params.httpOrigin.size() > 0) {
+ rep->header.putExt("Access-Control-Allow-Origin",
params.httpOrigin.termedBuf());
+#if HAVE_AUTH_MODULE_BASIC
+ rep->header.putExt("Access-Control-Allow-Credentials","true");
+#endif
+ rep->header.putExt("Access-Control-Expose-Headers","Server");
+ }
entry->replaceHttpReply(rep);
}
=== modified file 'src/mgr/ActionParams.cc'
--- src/mgr/ActionParams.cc 2011-01-24 17:24:59 +0000
+++ src/mgr/ActionParams.cc 2011-12-23 09:50:46 +0000
@@ -23,6 +23,7 @@
httpMethod = static_cast<_method_t>(m);
msg.getPod(httpFlags);
+ msg.getString(httpOrigin);
msg.getString(actionName);
msg.getString(userName);
@@ -36,6 +37,7 @@
msg.putString(httpUri);
msg.putInt(httpMethod);
msg.putPod(httpFlags);
+ msg.putString(httpOrigin);
msg.putString(actionName);
msg.putString(userName);
=== modified file 'src/mgr/ActionParams.h'
--- src/mgr/ActionParams.h 2011-01-24 17:24:59 +0000
+++ src/mgr/ActionParams.h 2011-12-23 09:50:01 +0000
@@ -29,6 +29,7 @@
String httpUri; ///< HTTP request URI
_method_t httpMethod; ///< HTTP request method
request_flags httpFlags; ///< HTTP request flags
+ String httpOrigin; ///< HTTP Origin: header (if any)
/* action parameters extracted from the client HTTP request */
String actionName; ///< action name (and credentials realm)