TL;DR
Using Python f-strings directly with user input is dangerous. It can allow attackers to run arbitrary code on your system. Always sanitise or validate user input before using it in f-strings, or use safer alternatives like the format() method with explicit type specification.
Understanding the Problem
Python f-strings are a convenient way to embed expressions inside string literals. However, if you directly include unsanitised user input within an f-string, it’s possible for malicious code to be executed. This is because Python will evaluate anything inside the curly braces {} before creating the final string.
How It Works: Code Injection
Imagine you have a script that takes user input and uses it in an f-string:
user_input = input("Enter something:")
print(f"You entered: {user_input}")
If the user enters something harmless, like “Hello”, everything is fine. But if they enter {os.system('rm -rf /')} (don’t actually do this!), Python will try to execute that code.
Step-by-step Solution
- Never Trust User Input: Assume all user input is potentially malicious.
- Sanitise or Validate Input: This is the most important step. You have a few options:
- Whitelisting: Only allow specific characters or patterns. For example, if you expect a number, only accept digits.
import re user_input = input("Enter a number:") if re.match(r'^[0-9]+$', user_input): print(f"You entered: {user_input}") else: print("Invalid input!") - Blacklisting (Generally Avoid): Try to remove dangerous characters or patterns. This is less reliable as attackers can often find ways around your filters.
- Whitelisting: Only allow specific characters or patterns. For example, if you expect a number, only accept digits.
- Use
format()with Explicit Types: Theformat()method offers more control and doesn’t automatically evaluate expressions in the same way f-strings do. Specify the expected data type to prevent code injection.user_input = input("Enter a number:") try: number = int(user_input) print("You entered: {}".format(number)) except ValueError: print("Invalid input!") - Escape Special Characters: If you absolutely must use f-strings with user input, escape any special characters that could be interpreted as code.
user_input = input("Enter something:") escaped_input = user_input.replace('{', '{{').replace('}', '}}') print(f"You entered: {escaped_input}")Note: This is not a complete solution and should be used with extreme caution.
- Consider Alternatives: If possible, avoid using user input directly in f-strings altogether. Use pre-defined strings or data structures instead.
Example of a Vulnerable Scenario
Let’s say you’re building a simple web application that displays a welcome message:
username = input("Enter your username:")
print(f"Welcome, {username}!")
An attacker could enter {os.system('whoami')} to execute the whoami command on your server.
Key Takeaways
- F-strings are powerful but can be dangerous with user input.
- Always sanitise or validate user input before using it in f-strings.
- The
format()method is a safer alternative. - Prioritise security and assume all user input is malicious.

