Python 3.10.1 (main, Dec 11 2021, 17:22:55) [GCC 11.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print(f"""{print("hello")}""")
hello
None
So Python runs the expression in { } and interpolates the result into the string.
Presumably the { } has access to anything that's in scope.
(I'm not quite sure how common patterns are, but I assume the person is replying to is imagining a scenario where an attack is able to put some string payload into the { } before interpolation.)
You may find that actually making this code to use data from user-provided data will make the code look quite unnatural and I doubt it would be accidentally written.
Yeah, that's why I was quite skeptical about the exact scenario... it would probably look very out of place, but I don't have enough RW experience in Python to say for sure.
In my hypothetical scenario im not targeting the python logger but rather `''.format()` and f-strings that parse user input naively. A lot of people on /r/ mentions that they started to get '${jndi:...' in their server logs.
So malicious actors is already shotgunning the log4sh attack so what stop them from spamming `{exec("import urllib.request;urllib.request.urlopen('http://example.com').read()")}` and see what stick.
While my example is for python im sure other languages will have similar issues and we will see a rise in format string attacks.
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:
>>> "{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.
f-strings don't "parse user input". .format doesn't have access to objects not explicitly provided to the call, and can't call functions. So again, how do you intend to trigger any of this if not through a hypothetical logger that uses eval?
Thanks for invalidating my naive/fud scenario, I must apologize for fearmongering, when I played with it in a py repl it really felt like a vector for attack.
I up-voted all parties trying to prove me wrong, and someone already down-voted me(rightfully).
Presumably the { } has access to anything that's in scope.
(I'm not quite sure how common patterns are, but I assume the person is replying to is imagining a scenario where an attack is able to put some string payload into the { } before interpolation.)