On Fri, May 07, 2021 at 01:40:19PM -0600, Nick Humrich wrote:
> PEP 501 already mentions how templates (i-strings?) can solve injection.
I don't think it does. The PEP only mentions the substring "inject" five
times:
- once in the table of contents;
- twice to describe how f-strings may be vulnerable to code
injection attacks;
- once as a section header "Handling code injection attacks"
- and once in that section to describe how third-party libraries can
provide "case specific renderers that take care of quoting
interpolated values appropriately for the relevant security context".
It seems to me that PEP 501 itself doesn't provide any further
protection from code injection attacks than do existing solutions.
The PEP gives this simple example:
os.system(f"echo {message_from_user}")
If `message_from_user` has the value:
message_from_user = 'pwned; rm /'
then you're going to have a bad time. Your i-strings are no safer:
os.system(i"echo {message_from_user}")
gives no protection from untrusted input than the f-string version does.
Merely delaying execution alone doesn't help.
A naive implementation of `os.system` will just run `format()` on the
interpolation template. Without an appropriate renderer, there's no
security gain, and PEP 501 explicitly states that it is up to
third-parties to provide renderers (at least initially).
A serious danger is that people will naively, and wrongly, think that
they should format the i-string themselves:
os.system(format(i"echo {message_from_user}"))
and thus defeat any renderers which os.system may provide. And that in
turn will surely lead people to optimise the code to:
os.system(f"echo {message_from_user}")
I believe that if you are interested in preventing code injection
attacks, it would be much better to introduce tainted and untainted
strings: all non-literal strings are assumed tainted until explicitly
escaped and flagged as untainted, after which they are considered safe
to use.
Either that or use the approach favoured by the stdlib: pass a string
template and a tuple of values which are then quoted before being
interpolated into the template.
The bottom line here is that I think you are exaggerating the benefits
of PEP 501 i-strings to "completely remove injection attacks".
Even if i-strings did everything you want, to *completely* remove
injection attacks would require *all* such functions:
* eval, exec
* os.system
* sql
etc break backwards compatibility by no longer supporting string inputs
at all, only interpolation template objects. So long as we *can* pass a
plain old string to such functions, somebody *will* pass strings, and
some of those will be tainted.
--
Steve
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/DM3SUFWCHVZ7RU2C43TXHS6CQDBVEFRO/
Code of Conduct: http://python.org/psf/codeofconduct/