Hacker News new | ask | show | jobs
by staticassertion 1649 days ago
I don't think this is right. .format() is not running any attacker controlled code. It might be formatting attacker controlled input, but the attacker has no control over the execution.

> o what stop them from spamming

Well I can't imagine how I would actually get that to turn into anything other than just a raw string that gets printed to the screen? Like I said, unless there's an eval somewhere it's not an issue.

edit: OK, I see the problem now. The flask article is a lot clearer.

The attacker can't control execution at all, or even really cause execution. What they can do is get your string to include information it should not - quite a footgun, but nothing close to RCE.

edit2: I maybe see a way this could be bad (if the attacker controls the format string that you call .format on), but I can't actually get it working myself.

So here's the thing. The attack as you've described does not work. Python won't just execute that string, you'll get a KeyError. What you need to do is, given a value provided to the string, call some sort of methods on that value such that you can perform your attack. This should be possible.

edit:

I'm trying to get this attack to work. So far, nah.

My assumptions are:

1. Attacker has full control over format string

2. `requests` is imported already (obviously you could just use the stdlib but I'm lazy)

3. An object or class is passed in

In theory I can construct a class from an object like this:

    Foo.__class__('requests', (requests.Request,), dict())()
    <Request [None]>

But so far that manifests as...

>>> "{0.__class__('requests', (requests.Request,), dict())()}".format(Foo) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'Foo' has no attribute '__class__('requests', (requests'

It seems that Python does not just naively execute what's inside of this thing.

Similarly,

>>> "{0.__init__((lambda: requests.get('google.com'))())}".format(Foo) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'Foo' has no attribute '__init__((lambda'

If there's a way to exploit this for actual code execution I can't find it easily.