Skip to content

Commit 5f07988

Browse files
authored
Merge pull request #10349 from ohader/docs/psalm-flow-5.x
Add documentation for @psalm-flow
2 parents 7acc50e + e015b7f commit 5f07988

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

docs/security_analysis/annotations.md

+4
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ See [Unescaping statements](avoiding_false_negatives.md#unescaping-statements).
1919
## `@psalm-taint-specialize`
2020

2121
See [Specializing taints in functions](avoiding_false_positives.md#specializing-taints-in-functions) and [Specializing taints in classes](avoiding_false_positives.md#specializing-taints-in-classes).
22+
23+
## `@psalm-flow [proxy <function-like>] ( <arg>, [ <arg>, ] ) [ -> return ]`
24+
25+
See [Taint Flow](taint_flow.md#optimized-taint-flow)

docs/security_analysis/taint_flow.md

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Taint Flow
2+
3+
## Optimized Taint Flow
4+
5+
When dealing with frameworks, keeping track of the data flow might involve different layers
6+
and even other 3rd party components. Using the `@psalm-flow` annotation allows PsalmPHP to
7+
take a shortcut and to make a tainted data flow more explicit.
8+
9+
### Proxy hint
10+
11+
```php
12+
<?php // --taint-analysis
13+
/**
14+
* @psalm-flow proxy exec($value)
15+
*/
16+
function process(string $value): void {}
17+
18+
process($_GET['malicious'] ?? '');
19+
```
20+
21+
The example above states, that the function `process($value)` is a proxy of the native PHP
22+
function `exec($value)` - which is potentially vulnerable to code execution (`TaintedShell`).
23+
24+
**Examples**
25+
26+
+ `@psalm-flow proxy exec($value)` referencing the global/scoped function `exec`
27+
+ `@psalm-flow proxy MyClass::mySinkMethod($value)` referencing a function/method of the class `MyClass`
28+
29+
### Return value hint
30+
31+
```php
32+
<?php // --taint-analysis
33+
/**
34+
* @psalm-flow ($value, $items) -> return
35+
*/
36+
function inputOutputHandler(string $value, string ...$items): string
37+
{
38+
// lots of complicated magic
39+
}
40+
41+
echo inputOutputHandler('first', 'second', $_GET['malicious'] ?? '');
42+
```
43+
44+
The example above states, that the function parameters `$value` and `$items` are reflected
45+
again in the return value. Thus, in case any of the input parameters to the function
46+
`inputOutputHandler` is tainted, then the resulting return value is as well. In this
47+
example `TaintedHtml` would be detected due to using `echo`.
48+
49+
### Combined proxy & return value hint
50+
51+
```php
52+
<?php // --taint-analysis
53+
/**
54+
* @psalm-flow proxy exec($value)
55+
* @psalm-flow ($value, $items) -> return
56+
*/
57+
function handleInput(string $value, string ...$items): string
58+
{
59+
// lots of complicated magic
60+
}
61+
62+
echo handleInput($_GET['malicious'] ?? '');
63+
```
64+
65+
The example above combines both previous examples and shows, that the `@psalm-flow` annotation
66+
can be used multiple times. Here, it would lead to detecting both `TaintedHtml` and `TaintedShell`.

0 commit comments

Comments
 (0)