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