From 3744f1eb8a85e5d55e9de8d616845c800fe39273 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Sun, 7 Jul 2024 10:36:50 +0200 Subject: Switch to useing XMLReader to parse XML payloads. XMLParser would expand entities by default, which could make us susceptible both to XXE attacks, and the billion laughs attack. By default XMLReader does _not_ expand entities, so it's a safer choice. This also changes the XmlRpcMethod::parse() function to throw a runtime exception if the XML payload could not be parsed, and to return null if the payload does not contain a valid element. In cases where we're unable to parse the payload as a valid XML-RPC request, we fall back to saving the full request info as before. --- src/process-request.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/process-request.php') diff --git a/src/process-request.php b/src/process-request.php index d0af0b5..69e1e58 100644 --- a/src/process-request.php +++ b/src/process-request.php @@ -29,13 +29,17 @@ $data = [ ]; if (preg_match('/xmlrpc\.php/i', $data['REQUEST_URI']) && $data['REQUEST_METHOD'] === 'POST') { - $method = XmlRpcMethod::parse($data['BODY']); - if ($method->name === 'wp.getUsersBlogs') { - save_credentials($data['REQUEST_TIME'], $data['REMOTE_ADDR'], $method->params[0], $method->params[1]); - error_log("Trapped XML-RPC request: saved credentials"); - - header("HTTP/1.1 404 Not Found"); - die(); + try { + $method = XmlRpcMethod::parse($data['BODY']); + if ($method && $method->name === 'wp.getUsersBlogs') { + save_credentials($data['REQUEST_TIME'], $data['REMOTE_ADDR'], $method->params[0], $method->params[1]); + error_log("Trapped XML-RPC request: saved credentials"); + + header("HTTP/1.1 404 Not Found"); + die(); + } + } catch (RuntimeException $e) { + error_log("Webtrap: {$e->getMessage()} ({$e->getCode()}), saving request instead."); } } -- cgit v1.2.3