Add option for validating content-type header
For systems implementing to the OWASP security guidelines[1] (of which all
should ideally) we should be checking the content-type header all times
that we parse a request as JSON.
This commit adds an option for parsing content-type, and sets a default
of "must get content-type". Ideally this would not be a breaking
change, but given the number of guides and scripts that omit the content
type, it seems worthwhile to add a trapdoor, such that people can opt
into their own model on how they would like to see this checking work.
Tested:
```
curl --insecure -H "Content-Type: application/json" -X POST -D headers.txt https://${bmc}/redfish/v1/SessionService/Sessions -d '{"UserName":"root", "Password":"0penBmc"}'
```
Succeeds.
Removing Content-Type argument causes bmc to return
Base.1.13.0.UnrecognizedRequestBody.
[1] cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
Change-Id: Iaa47dd563b40036ff2fc2cacb70d941fd8853038
Signed-off-by: Ed Tanous <edtanous@google.com>
diff --git a/http/parsing.hpp b/http/parsing.hpp
new file mode 100644
index 0000000..df63fca
--- /dev/null
+++ b/http/parsing.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "http/http_request.hpp"
+#include "logging.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <nlohmann/json.hpp>
+
+#include <string_view>
+
+enum class JsonParseResult
+{
+ BadContentType,
+ BadJsonData,
+ Success,
+};
+
+inline JsonParseResult parseRequestAsJson(const crow::Request& req,
+ nlohmann::json& jsonOut)
+{
+ std::string_view contentType =
+ req.getHeaderValue(boost::beast::http::field::content_type);
+
+ if (!boost::iequals(contentType, "application/json") &&
+ !boost::iequals(contentType, "application/json; charset=utf-8"))
+ {
+ BMCWEB_LOG_WARNING << "Failed to parse content type on request";
+#ifndef BMCWEB_INSECURE_IGNORE_CONTENT_TYPE
+ return JsonParseResult::BadContentType;
+#endif
+ }
+ jsonOut = nlohmann::json::parse(req.body, nullptr, false);
+ if (jsonOut.is_discarded())
+ {
+ BMCWEB_LOG_WARNING << "Failed to parse json in request";
+ return JsonParseResult::BadJsonData;
+ }
+
+ return JsonParseResult::Success;
+}