Skip to content

Add support for literal-string type, to address Injection Vulnerabilities #5507

@craigfrancis

Description

@craigfrancis

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).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions