Input parameter validation for Event Subscription
User input must be validated to avoid the out-of-memory issue. This
commit adds the size check on input parameters such as Context,
Destination and Header field while create or update the
EventDestination.
Added a generic error message "PropertySizeExceeded" in message registry
which is used as response when size limit is exceeded.
Tested
- Validated using POST on Event Subscription.
- When Context, Destination and Headers were too long,
received a error message denoting the same.
Change-Id: Ibab847ce0c99f445a76e6d3aee8074428bb7d30f
Signed-off-by: AppaRao Puli <apparao.puli@intel.com>
Signed-off-by: Ayushi Smriti <smriti.ayushi@intel.com>
Signed-off-by: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
Signed-off-by: Ed Tanous <edtanous@google.com>
diff --git a/redfish-core/include/error_messages.hpp b/redfish-core/include/error_messages.hpp
index e45ea45..f55a6bb 100644
--- a/redfish-core/include/error_messages.hpp
+++ b/redfish-core/include/error_messages.hpp
@@ -1070,6 +1070,25 @@
void operationNotAllowed(crow::Response& res);
+/**
+ * @brief Formats ArraySizeTooLong message into JSON
+ * Message body: "Indicates that a string value passed to the given resource
+ * exceeded its length limit."
+ * @returns Message ArraySizeTooLong formatted to JSON */
+nlohmann::json arraySizeTooLong(std::string_view property, uint64_t length);
+
+void arraySizeTooLong(crow::Response& res, std::string_view property,
+ uint64_t length);
+/**
+ * @brief Formats StringValueTooLong message into JSON
+ * Message body: "Indicates that a string value passed to the given resource
+ * exceeded its length limit."
+ * @returns Message StringValueTooLong formatted to JSON */
+nlohmann::json stringValueTooLong(std::string_view property, uint64_t length);
+
+void stringValueTooLong(crow::Response& res, std::string_view property,
+ uint64_t length);
+
} // namespace messages
} // namespace redfish
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index 5f57ff7..5a66c97 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -252,6 +252,15 @@
return;
}
+ // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
+ static constexpr const uint16_t maxDestinationSize = 2000;
+ if (destUrl.size() > maxDestinationSize)
+ {
+ messages::stringValueTooLong(asyncResp->res, "Destination",
+ maxDestinationSize);
+ return;
+ }
+
if (regPrefixes && msgIds)
{
if (!regPrefixes->empty() && !msgIds->empty())
@@ -329,13 +338,35 @@
if (context)
{
+ // This value is selected aribitrarily.
+ constexpr const size_t maxContextSize = 256;
+ if (context->size() > maxContextSize)
+ {
+ messages::stringValueTooLong(asyncResp->res, "Context",
+ maxContextSize);
+ return;
+ }
subValue->customText = *context;
}
if (headers)
{
+ size_t cumulativeLen = 0;
+
for (const nlohmann::json& headerChunk : *headers)
{
+ std::string hdr{headerChunk.dump(
+ -1, ' ', true, nlohmann::json::error_handler_t::replace)};
+ cumulativeLen += hdr.length();
+
+ // This value is selected to mirror http_connection.hpp
+ constexpr const uint16_t maxHeaderSizeED = 8096;
+ if (cumulativeLen > maxHeaderSizeED)
+ {
+ messages::arraySizeTooLong(asyncResp->res, "HttpHeaders",
+ maxHeaderSizeED);
+ return;
+ }
for (const auto& item : headerChunk.items())
{
const std::string* value =
diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp
index e3fb74b..33f5d70 100644
--- a/redfish-core/src/error_messages.cpp
+++ b/redfish-core/src/error_messages.cpp
@@ -1769,6 +1769,48 @@
addMessageToErrorJson(res.jsonValue, operationNotAllowed());
}
+/**
+ * @internal
+ * @brief Formats ArraySizeTooLong message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json arraySizeTooLong(std::string_view property, uint64_t length)
+{
+ std::string valStr = std::to_string(length);
+ return getLog(redfish::registries::base::Index::arraySizeTooLong,
+ std::to_array<std::string_view>({property, valStr}));
+}
+
+void arraySizeTooLong(crow::Response& res, std::string_view property,
+ uint64_t length)
+{
+ res.result(boost::beast::http::status::method_not_allowed);
+ addMessageToErrorJson(res.jsonValue, arraySizeTooLong(property, length));
+}
+
+/**
+ * @internal
+ * @brief Formats StringValueTooLong message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json stringValueTooLong(std::string_view property, uint64_t length)
+{
+ std::string valStr = std::to_string(length);
+ return getLog(redfish::registries::base::Index::stringValueTooLong,
+ std::to_array<std::string_view>({property, valStr}));
+}
+
+void stringValueTooLong(crow::Response& res, std::string_view property,
+ uint64_t length)
+{
+ res.result(boost::beast::http::status::method_not_allowed);
+ addMessageToErrorJson(res.jsonValue, stringValueTooLong(property, length));
+}
+
void invalidUpload(crow::Response& res, std::string_view arg1,
std::string_view arg2)
{