Live data from Hacker News

Be Careful with Python's New-Style String Format

lucumr.pocoo.org

111–120 of 155 posts

Re: Be Careful with Python's New-Style String Format

#111

This is the same principle for not passing user input to the first argument of `printf(3)` in C. Coming from C, I would never allow the user control of the format string if I were writing code.

The reasoning why printf strings in C are unsafe is not applicable in python though. You cannot access memory directly, and %n doesn't exist (nor other other fun POSIX requirements that write to random places on the stack). In fact, Python's C-style formatting strings are immune to this problem (even the extended form that allows you to name arguments).

Re: Be Careful with Python's New-Style String Format

#112

Earlier quoted context omitted.

The author discovered this exploit in the template engine he wrote (Jinja2).

Why would a template engine allow for free access to the native platforms string capabilities in the first place?

Native vs. non-native is irrelevant. A non-native formatting system could have the features of the python formatter that are dangerous. Or, if Python's native formatter lacked these dangerous features, there'd be no reason not to use it.

Re: Be Careful with Python's New-Style String Format

#113
post #5

I do love writing python, but it's pretty shocking when I find out you can write something like `event.__init__.__globals__[CONFIG][SECRET_KEY]`. That language just does not care about privacy or information hiding at all, I guess.

Format strings aren't a template language (Python even has Template Strings for that purpose), and being able to do this is quite useful in eg. debug logs it's a shorter and easier to write "{foo.x} ({foo.__class__.__name__})".format(foo=something).

Conversely they don't prohibit expensive properties either (eg. ORM-based lookups), or generating misleading output or whatever.

Re: Be Careful with Python's New-Style String Format

#114
post #3

... Uncontrolled format string bugs? In 2016? Really? Someone would fall for that? ..

Old style format strings are perfectly safe for arbitrary user input and commonly used as such.

User-provided format strings seem rather rare to me ; at least in scenarios where the user doesn't have full access anyway (eg. controlling output formatting of some command).

Re: Be Careful with Python's New-Style String Format

#115
post #4

Err, why would you allow for the user to enter arbitrary format strings in the first place? Might as well write "be careful about eval of arbitrary user provided strings".

Templates. Very useful in many places. Although if you are using templates in Python, you are likely using jinja2. And they just "fixed" the bug. So you are good to go if your upgrade.

Although this only applies to format-string evaluation in Jinja2, which would look something like

    {{ "Hello {user.name}".format(user) }}
which is really kinda obscure, especially since Jinja already has an explicit |format using the very safe / limited (but generally sufficient) alternative %(key)s syntax (also suitable for i18n, to some extend).

Re: Be Careful with Python's New-Style String Format

#116
post #18

Earlier quoted context omitted.

Shouldn't that be based not on the built-in string capabilities, but on a template engine, that must also take care for much more narrow cases of abuse (e.g. SQL injection, or access to only of a restricted number of helper functions within the template)?

The author discovered this exploit in the template engine he wrote (Jinja2).

While the vuln is there, it's a rather obscure way of using the engine in the first place, so in "good" templates it shouldn't be exploitable. See the example in the release: https://www.palletsprojects.com/blog/jinja-281-released/

Re: Be Careful with Python's New-Style String Format

#117
post #18

Earlier quoted context omitted.

"Customize the look of your blog by editing these templates."

Shouldn't that be based not on the built-in string capabilities, but on a template engine, that must also take care for much more narrow cases of abuse (e.g. SQL injection, or access to only of a restricted number of helper functions within the template)?

What does the template engine have to do with SQL? Not really following you there.

Re: Be Careful with Python's New-Style String Format

#118
post #79

Sane Lisp approach: provide easily analyzable target syntax. This is the TXR Lisp interactive listener of TXR 163. Use the :quit command or type Ctrl-D on empty line to exit. 1> (defvar foo 42) foo 2> `@(list foo) ... @foo` "42 ... 42" What is that backticked literal? Let's quote it: 3> '`@(list foo) ... @foo` `@(list foo) ... @foo` Hmm, prints back in same form. Probably syntactic sugar for a list; what is in the ca…

If you're LISP has first class environments, then this becomes much easier, and safer. (eval (read (get-some-user-string)) (let [ (post-title post-title) (post-date post-date) (post-author post-author) (fmt string-append) ] (null-environment))) eval is only executed in the context of some environment, and the only things it has access to are some strings, and a string concatenation procedure. It doesn't have access t…

My Lisp has search through a first-class environnment which falls back on a dynamic/global environment. A way could be provided to suppress the fallback, like a special environment node indicating "do not search for bindings past me, stop here".

If we have a completely empty environment, then we cannot eval the (sys:quasi ...) form itself; the sys:quasi symbol itself has no binding.

A nice idea might be to have a filter object in the environment stack which says "only if you're looking for one of these specific symbols, can you proceed to the global environment". Then we can easily arrange for select global bindings to be visible.

Re: Be Careful with Python's New-Style String Format

#119
post #4

Err, why would you allow for the user to enter arbitrary format strings in the first place? Might as well write "be careful about eval of arbitrary user provided strings".

Yeah, that was my first thought, too, and it's not very fair to blame Python's new style string format.

Treating user input as a format string has always been a bad idea in every language and library that use them.

Re: Be Careful with Python's New-Style String Format

#120
post #111

This is the same principle for not passing user input to the first argument of `printf(3)` in C. Coming from C, I would never allow the user control of the format string if I were writing code.

The reasoning why printf strings in C are unsafe is not applicable in python though. You cannot access memory directly, and %n doesn't exist (nor other other fun POSIX requirements that write to random places on the stack). In fact, Python's C-style formatting strings are immune to this problem (even the extended form that allows you to name arguments).

That's pointless nitpicking. The point is that user specified format strings allow the user to access things they shouldn't be able to access. It's the same in every language that has format strings.
Post reply on HN