1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Support taint detection on Throwable::getTraceAsString() (#3731)

And `__toString()`, which uses getTraceAsString().

Fixes #3696

```php
function login($username, $password, $secret) {
    throw new RuntimeException('login failure');
}
try {
    login('user', $_GET['pass'], SECRET);
} catch (Exception $e) {
    // This output includes unescaped 'pass' and SECRET
    echo $e, "\n";
    echo $e->getTraceAsString();
}
```
This commit is contained in:
Tyson Andre 2020-07-01 21:27:40 -04:00 committed by GitHub
parent 0f548c83ea
commit e3d59bf5d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 0 deletions

View File

@ -55,8 +55,14 @@ interface Throwable
/**
* @psalm-mutation-free
* @psalm-taint-source input
*/
public function getTraceAsString() : string;
/**
* @psalm-taint-source input
*/
public function __toString() : string;
}
/**
@ -126,8 +132,14 @@ class Exception implements Throwable
/**
* @psalm-mutation-free
* @psalm-taint-source input
*/
public final function getTraceAsString() : string {}
/**
* @psalm-taint-source input
*/
public function __toString() : string {}
}
/**
@ -195,6 +207,12 @@ class Error implements Throwable
/**
* @psalm-mutation-free
* @psalm-taint-source input
*/
public final function getTraceAsString() : string {}
/**
* @psalm-taint-source input
*/
public function __toString() : string {}
}

View File

@ -1473,6 +1473,42 @@ class TaintTest extends TestCase
$cb = create_function(\'$a\', $_GET[\'x\']);',
'error_message' => 'TaintedInput',
],
'taintException' => [
'<?php
$e = new Exception();
echo $e;',
'error_message' => 'TaintedInput',
],
'taintError' => [
'<?php
function foo() {}
try {
foo();
} catch (TypeError $e) {
echo "Caught: {$e->getTraceAsString()}\n";
}',
'error_message' => 'TaintedInput',
],
'taintThrowable' => [
'<?php
function foo() {}
try {
foo();
} catch (Throwable $e) {
echo "Caught: $e"; // TODO: ("Caught" . $e) does not work.
}',
'error_message' => 'TaintedInput',
],
/*
// TODO: Stubs do not support this type of inference even with $this->message = $message.
// Most uses of getMessage() would be with caught exceptions, so this is not representative of real code.
'taintException' => [
'<?php
$x = new Exception($_GET["x"]);
echo $x->getMessage();',
'error_message' => 'TaintedInput',
],
*/
];
}
}