summaryrefslogtreecommitdiff
path: root/include/token_authorization_middleware.hpp
diff options
context:
space:
mode:
authorEd Tanous <ed.tanous@intel.com>2018-04-27 02:08:56 +0300
committerEd Tanous <ed.tanous@intel.com>2018-06-29 21:18:39 +0300
commit9bd21fc16817ab1a47e9cd4ac6baf8f5b1d4ba63 (patch)
tree6fd10d1f64bb80abced63fe1345a87b088766d43 /include/token_authorization_middleware.hpp
parente0d918bc397350aa21af3dab9faa6e21748f6373 (diff)
downloadbmcweb-9bd21fc16817ab1a47e9cd4ac6baf8f5b1d4ba63.tar.xz
Fix issue with basic auth and the bmcweb
This fixes a bug where the webserver requests a resource that doesn't exist, which triggers a www-authenticate, and causes the browser to show the wrong thing. Change-Id: I65643a50eb269b0a7c76dcb0c65c4e7db2165c88 Signed-off-by: Ed Tanous <ed.tanous@intel.com>
Diffstat (limited to 'include/token_authorization_middleware.hpp')
-rw-r--r--include/token_authorization_middleware.hpp34
1 files changed, 28 insertions, 6 deletions
diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp
index 49649dd978..0c0c474a19 100644
--- a/include/token_authorization_middleware.hpp
+++ b/include/token_authorization_middleware.hpp
@@ -44,8 +44,19 @@ class Middleware {
if (ctx.session == nullptr) {
CROW_LOG_WARNING << "[AuthMiddleware] authorization failed";
- res.result(boost::beast::http::status::unauthorized);
- res.add_header("WWW-Authenticate", "Basic");
+ // If it's a browser connecting, don't send the HTTP authenticate header,
+ // to avoid possible CSRF attacks with basic auth
+ if (http_helpers::request_prefers_html(req)) {
+ res.result(boost::beast::http::status::temporary_redirect);
+ res.add_header("Location", "/#/login");
+ } else {
+ res.result(boost::beast::http::status::unauthorized);
+ // only send the WWW-authenticate header if this isn't a xhr from the
+ // browser. most scripts,
+ if (req.get_header_value("User-Agent").empty()) {
+ res.add_header("WWW-Authenticate", "Basic");
+ }
+ }
res.end();
return;
@@ -187,7 +198,7 @@ class Middleware {
if ("POST"_method == req.method()) {
if ((req.url == "/redfish/v1/SessionService/Sessions") ||
(req.url == "/redfish/v1/SessionService/Sessions/") ||
- (req.url == "/login") || (req.url == "/logout")) {
+ (req.url == "/login")) {
return true;
}
}
@@ -302,9 +313,20 @@ void request_routes(Crow<Middlewares...>& app) {
{"data", "User '" + std::string(username) + "' logged in"},
{"message", "200 OK"},
{"status", "ok"}};
- res.add_header("Set-Cookie", "XSRF-TOKEN=" + session->csrf_token);
- res.add_header("Set-Cookie", "SESSION=" + session->session_token +
- "; Secure; HttpOnly");
+
+ // Hack alert. Boost beast by default doesn't let you declare
+ // multiple headers of the same name, and in most cases this is
+ // fine. Unfortunately here we need to set the Session cookie,
+ // which requires the httpOnly attribute, as well as the XSRF
+ // cookie, which requires it to not have an httpOnly attribute.
+ // To get the behavior we want, we simply inject the second
+ // "set-cookie" string into the value header, and get the result
+ // we want, even though we are technicaly declaring two headers
+ // here.
+ res.add_header("Set-Cookie",
+ "XSRF-TOKEN=" + session->csrf_token +
+ "; Secure\r\nSet-Cookie: SESSION=" +
+ session->session_token + "; Secure; HttpOnly");
} else {
// if content type is json, assume json token
res.json_value = {{"token", session->session_token}};