On 22 June 2021 10:09:50 BST, Mike Schinkel <[email protected]> wrote:
>For my inspiration take a look at Trusted Types API in Javascript:
>
>https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API
><https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API>
There is an extremely important difference here: there is no single type in
that system called "TrustedString", there are separate types for each context
("injection sink"). The W3C article calls this out explicitly:
> Note: This allows the authors to specify the intention when creating a given
> value, and the user agents to introduce checks based on the type of such
> value to preserve the authors' intent. For example, if authors intend a value
> to be used as an HTML snippet, an attempt to load a script from that value
> would fail.
This is not just an implementation detail, it's an absolutely essential part of
the concept.
So let me add my name to the chorus saying that is_trusted() is a bad name, and
the added features that led to its selection make this feature worse not better.
Most of a "trusted types" implementation can be written in pure PHP, because
all you need is an object with a private string property and some appropriate
constructors.
The one part you can't do is trust strings provided in source differently from
strings provided by the user, and the original proposal provided a
straightforward mechanism for that purpose.
There is no reason why is_literal itself needs to know about "trusted value
objects", or have a long list of special cases to construct a string that is
"not actually a literal but we can't think of any way to exploit it". That can
all be handled by the userland code:
* Create a class called TrustedSql
* Accept a parameter of type string|TrustedSql. If the parameter is a string,
reject it if is_literal returns false
* Or, if a pseudo-type is provided as well, just accept
literal_string|TrustedSql
* If the user wants to provide dynamic SQL, they need to construct a TrustedSql
object using whatever mechanism the library wants to provide. That can include
an audited sprintf pattern, imploding arrays of integers, whatever turns out to
be useful.
I think the engine should leave the complexities of defining "trusted" to APIs
specialising in a particular "injection sink", and provide the low-level
building block they need, which is the original simple is_literal function.
Regards,
--
Rowan Tommins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php