diff options
author | Ed Tanous <ed.tanous@intel.com> | 2018-04-27 02:08:56 +0300 |
---|---|---|
committer | Ed Tanous <ed.tanous@intel.com> | 2018-06-29 21:18:39 +0300 |
commit | 9bd21fc16817ab1a47e9cd4ac6baf8f5b1d4ba63 (patch) | |
tree | 6fd10d1f64bb80abced63fe1345a87b088766d43 /include/token_authorization_middleware.hpp | |
parent | e0d918bc397350aa21af3dab9faa6e21748f6373 (diff) | |
download | bmcweb-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.hpp | 34 |
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}}; |