Hi,

As I'm not sure how to make any more process on this, I've added added a
Feature Request:

https://bugs.php.net/bug.php?id=79359

It shows how this change in PHP could stop SQL injection, and proposes a
way it could be used against HTML injection as well.

Craig



On Thu, 13 Feb 2020 at 12:31, Craig Francis <cr...@craigfrancis.co.uk>
wrote:

> Hi,
>
> While there was a brief discussion about an *is_literal*() method in
> August, I'm wondering where I can go next?
>
> Just as a reminder, the main objection seemed to be that Taint checking is
> the current solution. For example, those created by Laruence[1],
> MediaWiki[2], and Matthew[3]. But this can never be as good at the PHP
> engine explicitly stating a variable *only* contains literal values, where
> it can be checked at runtime, and be a key part of the development process.
>
> And while I'm using SQL injection in my examples (because it's easy to
> show how it can enforce the use of parameterised queries); it would also be
> useful to protect against command line injection, and HTML/XSS as well
> (e.g. a templating system can only accept HTML as literal strings, and
> the user supplied values be provided separately).
>
> I'm assuming this would change the zval structure (to include an
> "is_literal" flag?), and it would be more of a PHP 8.0 change, rather than
> 8.1.
>
> Craig
>
>
> ---
>
> Broken taint check, due to missing quote marks:
>
> $sql = ‘... WHERE id = ’ . mysqli_real_escape_string($db, $_GET[‘id’]);
>
> ---
>
> Support for "WHERE ... IN", ideally done via an abstraction, so you don't
> need to write this every time:
>
> $sql = '... WHERE id IN (' . substr(str_repeat('?,', count($ids)), 0, -1)
> . ')';
>
> ---
>
> [1] https://github.com/laruence/taint
> [2] https://www.mediawiki.org/wiki/Phan-taint-check-plugin
> [3] https://psalm.dev/r/ebb9522fea
>
> ---
>
>
>
>
> On Thu, 15 Aug 2019 at 19:02, Craig Francis <cr...@craigfrancis.co.uk>
> wrote:
>
>> Hi,
>>
>> How likely would it be for PHP to do Literal tracking of variables?
>>
>> This is something that's being discussed JavaScript TC39 at the moment
>> [1], and I think it would be even more useful in PHP.
>>
>> We already know we should use parameterized/prepared SQL, but there is no
>> way to prove the SQL string hasn't been tainted by external data in large
>> projects, or even in an ORM.
>>
>> This could also work for templating systems (blocking HTML injection) and
>> commands.
>>
>> Internally it would need to introduce a flag on every variable, and a
>> single function to check if a given variable has only been created by
>> Literal(s).
>>
>> Unlike the taint extension, there should be no way to override this (e.g.
>> no taint/untaint functions); and if it was part of the core language, it
>> will continue to work after every update.
>>
>> One day certain functions (e.g. mysqli_query) might use this information
>> to generate a error/warning/notice; but for now, having it available for
>> checking would be more than enough.
>>
>> Craig
>>
>>
>>
>>     public function exec($sql, $parameters = []) {
>>         if (!*is_literal*($sql)) {
>>             throw new Exception('SQL must be a literal.');
>>         }
>>         $statement = $this->pdo->prepare($sql);
>>         $statement->execute($parameters);
>>         return $statement->fetchAll();
>>     }
>>
>> ...
>>
>>     $sql = 'SELECT * FROM table WHERE id = ?';
>>
>>     $result = $db->exec($sql, [$id]);
>>
>>
>>
>> [1] https://github.com/tc39/proposal-array-is-template-object
>> https://github.com/mikewest/tc39-proposal-literals
>>
>

Reply via email to