1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Merge pull request #10183 from cgocast/master

Detect DoS by sleep vimeo#10178
This commit is contained in:
orklah 2023-09-29 13:27:43 +02:00 committed by GitHub
commit 1b12255fb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 91 additions and 2 deletions

View File

@ -11,7 +11,7 @@
- [BC] The `TDependentListKey` type was removed and replaced with an optional property of the `TIntRange` type.
- [BC] Value of constant `Psalm\Type\TaintKindGroup::ALL_INPUT` changed to reflect a new `TaintKind::INPUT_XPATH` have been added. Accordingly, default values for `$taint` parameters of `Psalm\Codebase::addTaintSource()` and `Psalm\Codebase::addTaintSink()` have been changed as well.
- [BC] Value of constant `Psalm\Type\TaintKindGroup::ALL_INPUT` changed to reflect new `TaintKind::INPUT_SLEEP` and `TaintKind::INPUT_XPATH` have been added. Accordingly, default values for `$taint` parameters of `Psalm\Codebase::addTaintSource()` and `Psalm\Codebase::addTaintSink()` have been changed as well.
- [BC] Property `Config::$shepherd_host` was replaced with `Config::$shepherd_endpoint`

View File

@ -439,6 +439,7 @@
<xs:element name="TaintedInput" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedLdap" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedShell" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedSleep" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedSql" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedSSRF" type="IssueHandlerType" minOccurs="0" />
<xs:element name="TaintedSystemSecret" type="IssueHandlerType" minOccurs="0" />

View File

@ -293,6 +293,7 @@ Level 5 and above allows a more non-verifiable code, and higher levels are even
- [TaintedInput](issues/TaintedInput.md)
- [TaintedLdap](issues/TaintedLdap.md)
- [TaintedShell](issues/TaintedShell.md)
- [TaintedSleep](issues/TaintedSleep.md)
- [TaintedSql](issues/TaintedSql.md)
- [TaintedSSRF](issues/TaintedSSRF.md)
- [TaintedSystemSecret](issues/TaintedSystemSecret.md)

View File

@ -241,6 +241,7 @@
- [TaintedInput](issues/TaintedInput.md)
- [TaintedLdap](issues/TaintedLdap.md)
- [TaintedShell](issues/TaintedShell.md)
- [TaintedSleep](issues/TaintedSleep.md)
- [TaintedSql](issues/TaintedSql.md)
- [TaintedSSRF](issues/TaintedSSRF.md)
- [TaintedSystemSecret](issues/TaintedSystemSecret.md)

View File

@ -0,0 +1,9 @@
# TaintedSleep
Emitted when user-controlled input can be passed into a `sleep` call or similar.
```php
<?php
sleep($_GET["seconds"]);
```

View File

@ -19,6 +19,7 @@ use Psalm\Issue\TaintedInclude;
use Psalm\Issue\TaintedLdap;
use Psalm\Issue\TaintedSSRF;
use Psalm\Issue\TaintedShell;
use Psalm\Issue\TaintedSleep;
use Psalm\Issue\TaintedSql;
use Psalm\Issue\TaintedSystemSecret;
use Psalm\Issue\TaintedTextWithQuotes;
@ -459,6 +460,15 @@ class TaintFlowGraph extends DataFlowGraph
);
break;
case TaintKind::INPUT_SLEEP:
$issue = new TaintedSleep(
'Detected tainted sleep',
$issue_location,
$issue_trace,
$path,
);
break;
default:
$issue = new TaintedCustom(
'Detected tainted ' . $matching_taint,

View File

@ -0,0 +1,8 @@
<?php
namespace Psalm\Issue;
final class TaintedSleep extends TaintedInput
{
public const SHORTCODE = 324;
}

View File

@ -21,6 +21,7 @@ final class TaintKind
public const INPUT_COOKIE = 'cookie';
public const INPUT_HEADER = 'header';
public const INPUT_XPATH = 'xpath';
public const INPUT_SLEEP = 'sleep';
public const USER_SECRET = 'user_secret';
public const SYSTEM_SECRET = 'system_secret';
}

View File

@ -22,5 +22,6 @@ final class TaintKindGroup
TaintKind::INPUT_HEADER,
TaintKind::INPUT_COOKIE,
TaintKind::INPUT_XPATH,
TaintKind::INPUT_SLEEP,
];
}

View File

@ -1797,3 +1797,25 @@ if (defined('GLOB_BRACE')) {
* @psalm-taint-sink shell $command
*/
function exec(string $command, &$output = null, int &$result_code = null): string|false {}
/**
* @psalm-taint-specialize
* @psalm-taint-sink sleep $seconds
*/
function sleep(int $seconds): int {}
/**
* @psalm-taint-sink sleep $microseconds
*/
function usleep(int $microseconds): void {}
/**
* @psalm-taint-sink sleep $seconds
* @psalm-taint-sink sleep $nanoseconds
*/
function time_nanosleep(int $seconds, int $nanoseconds): array|bool {}
/**
* @psalm-taint-sink sleep $timestamp
*/
function time_sleep_until(float $timestamp): bool {}

View File

@ -755,7 +755,7 @@ class TaintTest extends TestCase
/**
* @psalm-taint-escape xpath
*/
function my_escaping_function_for_xpath(string input) : string {};
function my_escaping_function_for_xpath(string $input) : string {};
function queryExpression(SimpleXMLElement $xml) : array|false|null {
$expression = $_GET["expression"];
@ -763,6 +763,16 @@ class TaintTest extends TestCase
return $xml->xpath($expression);
}',
],
'escapeSeconds' => [
'code' => '<?php
/**
* @psalm-taint-escape sleep
*/
function my_escaping_function_for_seconds(mixed $input) : int {};
$seconds = my_escaping_function_for_seconds($_GET["seconds"]);
sleep($seconds);',
],
];
}
@ -2540,6 +2550,31 @@ class TaintTest extends TestCase
}',
'error_message' => 'TaintedXpath',
],
'taintedSleep' => [
'code' => '<?php
sleep($_GET["seconds"]);',
'error_message' => 'TaintedSleep',
],
'taintedUsleep' => [
'code' => '<?php
usleep($_GET["microseconds"]);',
'error_message' => 'TaintedSleep',
],
'taintedTimeNanosleepSeconds' => [
'code' => '<?php
time_nanosleep($_GET["seconds"], 42);',
'error_message' => 'TaintedSleep',
],
'taintedTimeNanosleepNanoseconds' => [
'code' => '<?php
time_nanosleep(42, $_GET["nanoseconds"]);',
'error_message' => 'TaintedSleep',
],
'taintedTimeSleepUntil' => [
'code' => '<?php
time_sleep_until($_GET["timestamp"]);',
'error_message' => 'TaintedSleep',
],
];
}