mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Xpath injection #10162
This commit is contained in:
parent
cc7ed9586e
commit
c16216bc42
@ -444,6 +444,7 @@
|
||||
<xs:element name="TaintedTextWithQuotes" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="TaintedUnserialize" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="TaintedUserSecret" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="TaintedXpath" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="TooFewArguments" type="ArgumentIssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="TooManyArguments" type="ArgumentIssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="TooManyTemplateParams" type="FunctionIssueHandlerType" minOccurs="0" />
|
||||
|
@ -297,6 +297,7 @@ Level 5 and above allows a more non-verifiable code, and higher levels are even
|
||||
- [TaintedSystemSecret](issues/TaintedSystemSecret.md)
|
||||
- [TaintedUnserialize](issues/TaintedUnserialize.md)
|
||||
- [TaintedUserSecret](issues/TaintedUserSecret.md)
|
||||
- [TaintedXpath](issues/TaintedXpath.md)
|
||||
- [UncaughtThrowInGlobalScope](issues/UncaughtThrowInGlobalScope.md)
|
||||
- [UnevaluatedCode](issues/UnevaluatedCode.md)
|
||||
- [UnnecessaryVarAnnotation](issues/UnnecessaryVarAnnotation.md)
|
||||
|
@ -246,6 +246,7 @@
|
||||
- [TaintedTextWithQuotes](issues/TaintedTextWithQuotes.md)
|
||||
- [TaintedUnserialize](issues/TaintedUnserialize.md)
|
||||
- [TaintedUserSecret](issues/TaintedUserSecret.md)
|
||||
- [TaintedXpath](issues/TaintedXpath.md)
|
||||
- [TooFewArguments](issues/TooFewArguments.md)
|
||||
- [TooManyArguments](issues/TooManyArguments.md)
|
||||
- [TooManyTemplateParams](issues/TooManyTemplateParams.md)
|
||||
|
12
docs/running_psalm/issues/TaintedXpath.md
Normal file
12
docs/running_psalm/issues/TaintedXpath.md
Normal file
@ -0,0 +1,12 @@
|
||||
# TaintedSql
|
||||
|
||||
Emitted when user-controlled input can be passed into to a xpath query.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
function queryExpression(SimpleXMLElement $xml) : array|false|null {
|
||||
$expression = $_GET["expression"];
|
||||
return $xml->xpath($expression);
|
||||
}
|
||||
```
|
@ -24,6 +24,7 @@ use Psalm\Issue\TaintedSystemSecret;
|
||||
use Psalm\Issue\TaintedTextWithQuotes;
|
||||
use Psalm\Issue\TaintedUnserialize;
|
||||
use Psalm\Issue\TaintedUserSecret;
|
||||
use Psalm\Issue\TaintedXpath;
|
||||
use Psalm\IssueBuffer;
|
||||
use Psalm\Type\TaintKind;
|
||||
|
||||
@ -449,6 +450,15 @@ class TaintFlowGraph extends DataFlowGraph
|
||||
);
|
||||
break;
|
||||
|
||||
case TaintKind::INPUT_XPATH:
|
||||
$issue = new TaintedXpath(
|
||||
'Detected tainted xpath query',
|
||||
$issue_location,
|
||||
$issue_trace,
|
||||
$path,
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
$issue = new TaintedCustom(
|
||||
'Detected tainted ' . $matching_taint,
|
||||
|
8
src/Psalm/Issue/TaintedXpath.php
Normal file
8
src/Psalm/Issue/TaintedXpath.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Psalm\Issue;
|
||||
|
||||
final class TaintedXpath extends TaintedInput
|
||||
{
|
||||
public const SHORTCODE = 322;
|
||||
}
|
@ -20,6 +20,7 @@ final class TaintKind
|
||||
public const INPUT_FILE = 'file';
|
||||
public const INPUT_COOKIE = 'cookie';
|
||||
public const INPUT_HEADER = 'header';
|
||||
public const INPUT_XPATH = 'xpath';
|
||||
public const USER_SECRET = 'user_secret';
|
||||
public const SYSTEM_SECRET = 'system_secret';
|
||||
}
|
||||
|
@ -21,5 +21,6 @@ final class TaintKindGroup
|
||||
TaintKind::INPUT_FILE,
|
||||
TaintKind::INPUT_HEADER,
|
||||
TaintKind::INPUT_COOKIE,
|
||||
TaintKind::INPUT_XPATH,
|
||||
];
|
||||
}
|
||||
|
@ -972,10 +972,15 @@ class DOMXPath
|
||||
|
||||
public function __construct(DOMDocument $document, bool $registerNodeNS = true) {}
|
||||
|
||||
/**
|
||||
* @return DOMNodeList<DOMNode>|false
|
||||
* @psalm-taint-sink xpath $expression
|
||||
*/
|
||||
public function evaluate(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true): mixed {}
|
||||
|
||||
/**
|
||||
* @return DOMNodeList<DOMNode>|false
|
||||
* @psalm-taint-sink xpath $expression
|
||||
*/
|
||||
public function query(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true): mixed {}
|
||||
|
||||
|
@ -29,7 +29,10 @@ function simplexml_import_dom(SimpleXMLElement|DOMNode $node, ?string $class_nam
|
||||
*/
|
||||
class SimpleXMLElement implements Traversable, Countable
|
||||
{
|
||||
/** @return array<array-key, SimpleXMLElement>|null|false */
|
||||
/**
|
||||
* @return array<array-key, SimpleXMLElement>|null|false
|
||||
* @psalm-taint-sink xpath $expression
|
||||
*/
|
||||
public function xpath(string $expression) {}
|
||||
|
||||
public function registerXPathNamespace(string $prefix, string $namespace): bool {}
|
||||
|
@ -749,6 +749,19 @@ class TaintTest extends TestCase
|
||||
$d = mysqli_real_escape_string($_GET["d"]);
|
||||
|
||||
$mysqli->query("$a$b$c$d");',
|
||||
],
|
||||
'querySimpleXMLElement' => [
|
||||
'code' => '<?php
|
||||
/**
|
||||
* @psalm-taint-escape xpath
|
||||
*/
|
||||
function my_escaping_function_for_xpath(string input) : string {};
|
||||
|
||||
function queryExpression(SimpleXMLElement $xml) : array|false|null {
|
||||
$expression = $_GET["expression"];
|
||||
$expression = my_escaping_function_for_xpath($expression);
|
||||
return $xml->xpath($expression);
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
@ -2503,6 +2516,30 @@ class TaintTest extends TestCase
|
||||
$function->invoke();',
|
||||
'error_message' => 'TaintedCallable',
|
||||
],
|
||||
'querySimpleXMLElement' => [
|
||||
'code' => '<?php
|
||||
function queryExpression(SimpleXMLElement $xml) : array|false|null {
|
||||
$expression = $_GET["expression"];
|
||||
return $xml->xpath($expression);
|
||||
}',
|
||||
'error_message' => 'TaintedXpath',
|
||||
],
|
||||
'queryDOMXPath' => [
|
||||
'code' => '<?php
|
||||
function queryExpression(DOMXPath $xpath) : mixed {
|
||||
$expression = $_GET["expression"];
|
||||
return $xpath->query($expression);
|
||||
}',
|
||||
'error_message' => 'TaintedXpath',
|
||||
],
|
||||
'evaluateDOMXPath' => [
|
||||
'code' => '<?php
|
||||
function evaluateExpression(DOMXPath $xpath) : mixed {
|
||||
$expression = $_GET["expression"];
|
||||
return $xpath->evaluate($expression);
|
||||
}',
|
||||
'error_message' => 'TaintedXpath',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user