Taint Flow
Optimized Taint Flow
When dealing with frameworks, keeping track of the data flow might involve different layers
and even other 3rd party components. Using the @psalm-flow
annotation allows PsalmPHP to
take a shortcut and to make a tainted data flow more explicit.
Proxy hint
<?php // --taint-analysis
/**
* @psalm-flow proxy exec($value)
*/
function process(string $value): void {}
process($_GET['malicious'] ?? '');
The example above states, that the function process($value)
is a proxy of the native PHP
function exec($value)
- which is potentially vulnerable to code execution (TaintedShell
).
Examples
@psalm-flow proxy exec($value)
referencing the global/scoped functionexec
@psalm-flow proxy MyClass::mySinkMethod($value)
referencing a function/method of the classMyClass
Return value hint
<?php // --taint-analysis
/**
* @psalm-flow ($value, $items) -> return
*/
function inputOutputHandler(string $value, string ...$items): string
{
// lots of complicated magic
}
echo inputOutputHandler('first', 'second', $_GET['malicious'] ?? '');
The example above states, that the function parameters $value
and $items
are reflected
again in the return value. Thus, in case any of the input parameters to the function
inputOutputHandler
is tainted, then the resulting return value is as well. In this
example TaintedHtml
would be detected due to using echo
.
Combined proxy & return value hint
<?php // --taint-analysis
/**
* @psalm-flow proxy exec($value)
* @psalm-flow ($value, $items) -> return
*/
function handleInput(string $value, string ...$items): string
{
// lots of complicated magic
}
echo handleInput($_GET['malicious'] ?? '');
The example above combines both previous examples and shows, that the @psalm-flow
annotation
can be used multiple times. Here, it would lead to detecting both TaintedHtml
and TaintedShell
.