mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +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:
parent
0f548c83ea
commit
e3d59bf5d4
@ -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 {}
|
||||
}
|
||||
|
@ -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',
|
||||
],
|
||||
*/
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user