From 63da6bdfe01e26ec4209e6d006bd38336f585a1b Mon Sep 17 00:00:00 2001 From: unacao Date: Thu, 30 Nov 2017 13:29:02 -0800 Subject: [PATCH] safeguard json request via websocket (#1493) --- modules/dreamview/backend/map/map_service.cc | 9 ++- .../simulation_world_updater.cc | 60 +++++++++++++------ .../simulation_world_updater.h | 2 + 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/modules/dreamview/backend/map/map_service.cc b/modules/dreamview/backend/map/map_service.cc index 16606c1464..19ecd5c6d0 100644 --- a/modules/dreamview/backend/map/map_service.cc +++ b/modules/dreamview/backend/map/map_service.cc @@ -72,10 +72,15 @@ void ExtractStringVectorFromJson(const nlohmann::json &json_object, const std::string &key, std::vector *result) { auto iter = json_object.find(key); - if (iter != json_object.end()) { + if (iter != json_object.end() && iter->is_array()) { result->reserve(iter->size()); for (size_t i = 0; i < iter->size(); ++i) { - result->push_back((*iter)[i]); + auto value = (*iter)[i]; + if (value.is_string()) { + result->push_back(value); + } else { + AWARN << "Expected 'string' type, but was " << value.type_name(); + } } } } diff --git a/modules/dreamview/backend/simulation_world/simulation_world_updater.cc b/modules/dreamview/backend/simulation_world/simulation_world_updater.cc index ca8731d35d..a34d561c09 100644 --- a/modules/dreamview/backend/simulation_world/simulation_world_updater.cc +++ b/modules/dreamview/backend/simulation_world/simulation_world_updater.cc @@ -70,6 +70,12 @@ SimulationWorldUpdater::SimulationWorldUpdater(WebSocketHandler *websocket, return; } + if (!radius->is_number()) { + AERROR << "Expect radius with type 'number', but was " + << radius->type_name(); + return; + } + Json response = sim_world_service_.GetMapElements(*radius); response["type"] = "MapElements"; websocket_->SendData(conn, response.dump()); @@ -107,7 +113,8 @@ SimulationWorldUpdater::SimulationWorldUpdater(WebSocketHandler *websocket, } bool requestPlanning = false; - if (json.find("planning") != json.end()) { + auto planning = json.find("planning"); + if (planning != json.end() && planning->is_boolean()) { requestPlanning = json["planning"]; } @@ -170,30 +177,33 @@ SimulationWorldUpdater::SimulationWorldUpdater(WebSocketHandler *websocket, bool SimulationWorldUpdater::ConstructRoutingRequest( const Json &json, RoutingRequest *routing_request) { - // Input validations + routing_request->clear_waypoint(); + // set start point if (!ContainsKey(json, "start")) { - AERROR << "Cannot prepare a routing request: input validation failed."; + AERROR << "Failed to prepare a routing request: start point not found."; return false; } - // set start point auto start = json["start"]; - if (!ContainsKey(start, "x") || !ContainsKey(start, "y")) { - AERROR << "Failed to prepare a routing request: start point not found"; + if (!ValidateCoordinate(start)) { + AERROR << "Failed to prepare a routing request: invalid start point."; + return false; + } + if (!map_service_->ConstructLaneWayPoint(start["x"], start["y"], + routing_request->add_waypoint())) { + AERROR << "Failed to prepare a routing request:" + << " cannot locate start point on map."; return false; } - routing_request->clear_waypoint(); - map_service_->ConstructLaneWayPoint(start["x"], start["y"], - routing_request->add_waypoint()); // set way point(s) if any auto iter = json.find("waypoint"); - if (iter != json.end()) { + if (iter != json.end() && iter->is_array()) { auto *waypoint = routing_request->mutable_waypoint(); for (size_t i = 0; i < iter->size(); ++i) { auto &point = (*iter)[i]; - if (!ContainsKey(point, "x") || !ContainsKey(point, "y")) { - AERROR << "Failed to prepare a routing request: waypoint not found"; + if (!ValidateCoordinate(point)) { + AERROR << "Failed to prepare a routing request: invalid waypoint."; return false; } @@ -205,18 +215,22 @@ bool SimulationWorldUpdater::ConstructRoutingRequest( } // set end point - auto *end_point = routing_request->add_waypoint(); if (!ContainsKey(json, "end")) { - AERROR << "Failed to prepare a routing request: end point not found"; + AERROR << "Failed to prepare a routing request: end point not found."; return false; } auto end = json["end"]; - if (!ContainsKey(end, "x") || !ContainsKey(end, "y")) { - AERROR << "Failed to prepare a routing request: end point not found"; + if (!ValidateCoordinate(end)) { + AERROR << "Failed to prepare a routing request: invalid end point."; + return false; + } + if (!map_service_->ConstructLaneWayPoint(end["x"], end["y"], + routing_request->add_waypoint())) { + AERROR << "Failed to prepare a routing request:" + << " cannot locate end point on map."; return false; } - map_service_->ConstructLaneWayPoint(end["x"], end["y"], end_point); AINFO << "Constructed RoutingRequest to be sent:\n" << routing_request->DebugString(); @@ -224,6 +238,18 @@ bool SimulationWorldUpdater::ConstructRoutingRequest( return true; } +bool SimulationWorldUpdater::ValidateCoordinate(const nlohmann::json &json) { + if (!ContainsKey(json, "x") || !ContainsKey(json, "y")) { + AERROR << "Failed to find x or y coordinate."; + return false; + } + if (json.find("x")->is_number() && json.find("y")->is_number()) { + return true; + } + AERROR << "Both x and y coordinate should be a number."; + return false; +} + void SimulationWorldUpdater::Start() { // start ROS timer, one-shot = false, auto-start = true timer_ = diff --git a/modules/dreamview/backend/simulation_world/simulation_world_updater.h b/modules/dreamview/backend/simulation_world/simulation_world_updater.h index f634826fd3..b0682abefb 100644 --- a/modules/dreamview/backend/simulation_world/simulation_world_updater.h +++ b/modules/dreamview/backend/simulation_world/simulation_world_updater.h @@ -89,6 +89,8 @@ class SimulationWorldUpdater { const nlohmann::json &json, apollo::routing::RoutingRequest *routing_request); + bool ValidateCoordinate(const nlohmann::json &json); + /** * @brief Tries to load the points of interest from the file if it has * not been. -- GitLab