the php framework slim architecture on the presence of the XXE vulnerability, XXE typically present in the form of-vulnerability warning-the black bar safety net

ID MYHACK58:62201672904
Type myhack58
Reporter 佚名
Modified 2016-03-24T00:00:00


Modern cms framework laraval/symfony/slim, leading to today's php vulnerability appears point, principle, using method, has undergone some changes, this series can hope to summarize their excavation of such a cms vulnerability.

slim is one of the design ideas ahead of the well-known of php light framework, combining psr7 to design, since the user has more than 100w of:

In reading its source code, I found its presence A only in the framework of the CMS will appear vulnerabilities.

Official website:

Vulnerability details

This vulnerability exists in the latest version 3.0. First with a conposer of installation

composer require slim/slim “^3.0@RC”

See its documentation: GET POST data, is the use of getParsedBody method, and this method of POST processing that is in accordance with the content-type to distinguish between and resolution:

Very typical problem, and sometimes the framework will help developers to some he may not need"busy", such as slimphp here, the regular POST content-type to application/x - www-form-urlencoded, but as soon as I change it to application/json, I can pass in a json formatted POST data, modify application/xml, I can pass in XML data format. This feature will lead to two problems: WAF bypass There may be the XXE vulnerability WAF bypassing this is certainly needless to say, the conventional WAF generally only detect application/x-www-form-urlencoded data, once modified the data type you will pass to kill the maximum WAF of. XXE is the present vulnerability of the key. We see that parsing the body of the code: public function __construct($method, UriInterface $uri, HeadersInterface $headers, array $cookies, array $serverParams, StreamInterface $body, array $uploadedFiles = []) { $this->originalMethod = $this->filterMethod($method); $this->uri = $uri; $this->headers = $headers; $this->cookies = $cookies; $this->serverParams = $serverParams; $this->attributes = new Collection(); $this->body = $body; $this->uploadedFiles = $uploadedFiles; if (!$ this->headers->has('Host') || $this->uri->getHost() !== ") { $this->headers->set('Host', $this->uri->getHost()); } $this->registerMediaTypeParser('application/json', function ($input) { return json_decode($input, true); }); $this->registerMediaTypeParser('application/xml', function ($input) { return simplexml_load_string($input); }); $this->registerMediaTypeParser('text/xml', function ($input) { return simplexml_load_string($input); }); $this->registerMediaTypeParser('application/x-www-form-urlencoded', function ($input) { parse_str($input, $data); return $data; }); } Actually parse the code as a callback function written in the Request class constructor method. Seen here is directly calling the simplexml_load_string to parse$input, resulting in an XML entity injection vulnerability. So, with the slim framework 3.0 development of the CMS, just get the POST data will be affected by this XXE vulnerability. Vulnerability proof Write a simple demo page, only one gets the POST information and the output of the function: require 'vendor/autoload.php'; $app = new \Slim\App(); $app->post("/post", function($request, $response) { $parsedBody = $request->getParsedBody(); print_r($parsedBody); }); $app->run(); Built in three white cap:正常请求 to:

Trigger the XXE vulnerability and reads the/etc/passwd to:

Bug fixes

In slimphp2, the official is on this block for a certain process:

/ Parse XML This method creates a SimpleXMLElement based upon the XML input. If the SimpleXML extension is not available, the raw input will be returned unchanged. @param string $input @return \SimpleXMLElement|string / protected function parseXml($input) { if (class_exists('SimpleXMLElement')) { try { $backup = libxml_disable_entity_loader(true); $result = new \SimpleXMLElement($input); libxml_disable_entity_loader($backup); return $result; } catch (\Exception $e) { // Do nothing } } return $input; }

[1] [2] next