Skip to content

Commit

Permalink
Merge pull request #10349 from ohader/docs/psalm-flow-5.x
Browse files Browse the repository at this point in the history
Add documentation for @psalm-flow
  • Loading branch information
orklah committed Nov 6, 2023
2 parents 7acc50e + e015b7f commit 5f07988
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/security_analysis/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ See [Unescaping statements](avoiding_false_negatives.md#unescaping-statements).
## `@psalm-taint-specialize`

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).

## `@psalm-flow [proxy <function-like>] ( <arg>, [ <arg>, ] ) [ -> return ]`

See [Taint Flow](taint_flow.md#optimized-taint-flow)
66 changes: 66 additions & 0 deletions docs/security_analysis/taint_flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# 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
<?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 function `exec`
+ `@psalm-flow proxy MyClass::mySinkMethod($value)` referencing a function/method of the class `MyClass`

### Return value hint

```php
<?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
<?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`.

0 comments on commit 5f07988

Please sign in to comment.