1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Update documentation for taints and global configuration (#5098)

* [DOCS] Extend documentation on global variables configuration

* [DOCS] Synchronize meaning of @psalm-taint-source input with source code

* [DOCS] Add documentation for conditional @psalm-taint-escape

* [DOCS] Add documentation for @psalm-taint-unescape
This commit is contained in:
Oliver Hader 2021-01-25 17:04:00 +01:00 committed by Daniil Gentili
parent cf9d8f08b9
commit ae54b72dba
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
5 changed files with 92 additions and 10 deletions

View File

@ -384,13 +384,13 @@ Contains a list of all the directories that Psalm should inspect. You can also s
Optional. Same format as `<projectFiles>`. Directories Psalm should load but not inspect. Optional. Same format as `<projectFiles>`. Directories Psalm should load but not inspect.
#### &lt;fileExtensions&gt; #### &lt;fileExtensions&gt;
Optional. A list of extensions to search over. See [Checking non-PHP files](checking_non_php_files.md) to understand how to extend this. Optional. A list of extensions to search over. See [Checking non-PHP files](checking_non_php_files.md) to understand how to extend this.
#### &lt;plugins&gt; #### &lt;plugins&gt;
Optional. A list of `<plugin filename="path_to_plugin.php" />` entries. See the [Plugins](plugins/using_plugins.md) section for more information. Optional. A list of `<plugin filename="path_to_plugin.php" />` entries. See the [Plugins](plugins/using_plugins.md) section for more information.
#### &lt;issueHandlers&gt; #### &lt;issueHandlers&gt;
Optional. If you don't want Psalm to complain about every single issue it finds, the issueHandler tag allows you to configure that. [Dealing with code issues](dealing_with_code_issues.md) tells you more. Optional. If you don't want Psalm to complain about every single issue it finds, the issueHandler tag allows you to configure that. [Dealing with code issues](dealing_with_code_issues.md) tells you more.
#### &lt;mockClasses&gt; #### &lt;mockClasses&gt;
Optional. Do you use mock classes in your tests? If you want Psalm to ignore them when checking files, include a fully-qualified path to the class with `<class name="Your\Namespace\ClassName" />` Optional. Do you use mock classes in your tests? If you want Psalm to ignore them when checking files, include a fully-qualified path to the class with `<class name="Your\Namespace\ClassName" />`
@ -402,7 +402,7 @@ Optional. Do you have objects with properties that cannot be determined statical
Optional. If your codebase uses classes and functions that are not visible to Psalm via reflection (e.g. if there are internal packages that your codebase relies on that are not available on the machine running Psalm), you can use stub files. Used by PhpStorm (a popular IDE) and others, stubs provide a description of classes and functions without the implementations. You can find a list of stubs for common classes [here](https://github.com/JetBrains/phpstorm-stubs). List out each file with `<file name="path/to/file.php" />`. Optional. If your codebase uses classes and functions that are not visible to Psalm via reflection (e.g. if there are internal packages that your codebase relies on that are not available on the machine running Psalm), you can use stub files. Used by PhpStorm (a popular IDE) and others, stubs provide a description of classes and functions without the implementations. You can find a list of stubs for common classes [here](https://github.com/JetBrains/phpstorm-stubs). List out each file with `<file name="path/to/file.php" />`.
#### &lt;ignoreExceptions&gt; #### &lt;ignoreExceptions&gt;
Optional. A list of exceptions to not report for `checkForThrowsDocblock` or `checkForThrowsInGlobalScope`. If an exception has `onlyGlobalScope` set to `true`, only `checkForThrowsInGlobalScope` is ignored for that exception, e.g. Optional. A list of exceptions to not report for `checkForThrowsDocblock` or `checkForThrowsInGlobalScope`. If an exception has `onlyGlobalScope` set to `true`, only `checkForThrowsInGlobalScope` is ignored for that exception, e.g.
```xml ```xml
<ignoreExceptions> <ignoreExceptions>
<class name="fully\qualified\path\Exc" onlyGlobalScope="true" /> <class name="fully\qualified\path\Exc" onlyGlobalScope="true" />
@ -410,9 +410,39 @@ Optional. A list of exceptions to not report for `checkForThrowsDocblock` or `c
``` ```
#### &lt;globals&gt; #### &lt;globals&gt;
Optional. If your codebase uses global variables that are accessed with the `global` keyword, you can declare their type. e.g. Optional. If your codebase uses global variables that are accessed with the `global` keyword, you can declare their type. e.g.
```xml ```xml
<globals> <globals>
<var name="globalVariableName" type="type" /> <var name="globalVariableName" type="type" />
</globals> </globals>
``` ```
Some frameworks and libraries expose functionalities through e.g. `$GLOBALS[DB]->query($query)`.
The following configuration declares custom types for super-globals (`$GLOBALS`, `$_GET`, ...).
```xml
<globals>
<var name="$GLOBALS" type="array{DB: MyVendor\DatabaseConnection, VIEW: MyVendor\TemplateView}" />
<var name="$_GET" type="array{data: array<string, string>}" />
</globals>
```
The example above declares global variables as shown below
* `$GLOBALS`
+ `DB` of type `MyVendor\DatabaseConnection`
+ `VIEW` of type `MyVendor\TemplateView`
* `$_GET`
+ `data` e.g. like `["id" => "123", "title" => "Nice"]`
## Accessing Psalm configuration in plugins
Plugins can access or modify the global configuration in plugins using
[singleton Psalm\Config](https://github.com/vimeo/psalm/blob/master/src/Psalm/Config.php).
```php
$config = \Psalm\Config::getInstance();
if (!isset($config->globals['$GLOBALS'])) {
$config->globals['$GLOBALS'] = 'array{data: array<string, string>}';
}
```

View File

@ -1,17 +1,21 @@
# Security analysis annotations # Security analysis annotations
## `@psalm-taint-source` ## `@psalm-taint-source <taint-type>`
See [Custom taint sources](custom_taint_sources.md#taint-source-annotation). See [Custom taint sources](custom_taint_sources.md#taint-source-annotation).
## `@psalm-taint-sink` ## `@psalm-taint-sink <taint-type> <param-name>`
See [Custom taint sinks](custom_taint_sinks.md). See [Custom taint sinks](custom_taint_sinks.md).
## `@psalm-taint-escape` ## `@psalm-taint-escape <taint-type #conditional>`
See [Escaping tainted output](avoiding_false_positives.md#escaping-tainted-output). See [Escaping tainted output](avoiding_false_positives.md#escaping-tainted-output).
## `@psalm-taint-unescape <taint-type>`
See [Unescaping statements](avoiding_false_negatives.md#unescaping-statements).
## `@psalm-taint-specialize` ## `@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). 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).

View File

@ -0,0 +1,25 @@
# Avoiding false-negatives
## Unescaping statements
Post-processing previously escaped/encoded statements can cause insecure scenarios.
`@psalm-taint-unescape <taint-type>` allows to declare those components insecure explicitly.
```php
<?php
/**
* @psalm-taint-unescape html
*/
function decode(string $str): string
{
return str_replace(
['&lt;', '&gt;', '&quot;', '&apos;'],
['<', '>', '"', '"'],
$str
);
}
$safe = htmlspecialchars($_GET['text']);
echo decode($safe);
```

View File

@ -1,6 +1,6 @@
# Avoiding false-positives # Avoiding false-positives
When you run Psalms taint analysis for the first time you may see a bunch of false-positives. When you run Psalm's taint analysis for the first time you may see a bunch of false-positives.
Nobody likes false-positives! Nobody likes false-positives!
@ -26,6 +26,29 @@ function echoVar(string $str) : void {
echoVar($_GET["text"]); echoVar($_GET["text"]);
``` ```
## Conditional escaping tainted input
A slightly modified version of the previous example is using a condition to determine whether the return value
is considered secure. Only in case function argument `$escape` is true, the corresponding annotation
`@psalm-taint-escape` is applied for taint type `html` .
```php
/**
* @param string $str
* @param bool $escape
* @psalm-taint-escape ($escape is true ? 'html' : null)
*/
function processVar(string $str, bool $escape = true) : string {
if ($escape) {
$str = str_replace(['<', '>'], '', $str);
}
return $str;
}
echo processVar($_GET['text'], false); // detects tainted HTML
echo processVar($_GET['text'], true); // considered secure
```
## Specializing taints in functions ## Specializing taints in functions
For functions, methods and classes you can use the `@psalm-taint-specialize` annotation. For functions, methods and classes you can use the `@psalm-taint-specialize` annotation.

View File

@ -6,7 +6,7 @@ You can define your own taint sources with an annotation or a plugin.
You can use the annotation `@psalm-taint-source <taint-type>` to indicate a function or method that provides user input. You can use the annotation `@psalm-taint-source <taint-type>` to indicate a function or method that provides user input.
In the below example the `input` taint type is specified as a standin for the four input taints `text`, `html`, `sql` and `shell`. In the below example the `input` taint type is specified as a standin for input taints as defined in [Psalm\Type\TaintKindGroup](https://github.com/vimeo/psalm/blob/master/src/Psalm/Type/TaintKindGroup.php).
```php ```php
/** /**