-
-
Notifications
You must be signed in to change notification settings - Fork 947
Add support for literal-string type, to address Injection Vulnerabilities #5507
Description
Feature request
Psalm 4.8 has introduced a new literal-string type, which is used to "distinguish strings from a trusted developer, from strings that may be attacker controlled".
This helps identify the main source of Injection Vulnerabilities, where developers incorrectly include user-input in sensitive strings (SQL, HTML, CLI, etc).
/** @param literal-string $sql */
function execute_sql(string $sql, array $params = []): void { }
$id = (string) ($_GET['id'] ?? '');
// passes type checks
execute_sql(
'SELECT * FROM `foo` WHERE `id` = :id',
[':id' => $id]
);
// fails
execute_sql(
'SELECT * FROM `foo` WHERE `id` = "' .$id . '"'
);It is based on the is_literal() RFC that didn't make it in for PHP 8.1, but will be re-considered for 8.2.
As an aside, this is not the same as Taint Checking, which incorrectly assumes the output of an escaping function is “safe” for a particular context (creating a false sense of security); for example:
$sql = 'SELECT * FROM users WHERE id = ' . $db->real_escape_string($id); // INSECURE, $id = "id"
$html = "<img src=" . htmlentities($url) . " alt='' />"; // INSECURE, $url = "/ onerror=alert(1)"
$html = "<a href='" . htmlentities($url) . "'>..."; // INSECURE, $url = "javascript:alert(1)"; and single quotes before PHP 8.1 were not escaped by default.Did PHPStan help you today? Did it make you happy in any way?
PHPStan helps me focus on problem solving, knowing that it will pick up most typos/mistakes (the reason for this feature request is to catch the last set of mistakes that I still worry about, especially when working with a larger team of developers).