Created
August 5, 2025 13:04
-
-
Save ksamuel/2b30fd5572329f37000a3552fefc7add to your computer and use it in GitHub Desktop.
Gemini t-string attempt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3.14 | |
# -*- coding: utf-8 -*- | |
""" | |
A demonstration of PEP 750's t-strings for safer command execution. | |
This script defines a `run_command` function that utilizes a custom | |
t-string tag to safely execute shell commands using the `subprocess` module. | |
It then contrasts this safe approach with a vulnerable command execution | |
using `os.system` and regular f-strings to highlight how t-strings | |
can prevent command injection attacks. | |
Note: This script must be run with a Python 3.14 interpreter that | |
supports t-strings (PEP 750). | |
""" | |
import shlex | |
import subprocess | |
import os | |
import sys | |
from typing import Any, List, Tuple | |
# --- T-String Implementation (as per PEP 750) --- | |
class ShellTag: | |
""" | |
A t-string tag processor for shell commands. | |
This class implements the `__process_string__` method, which is the | |
core of the t-string mechanism. It takes the literal parts of the | |
string and the interpolated values and processes them into a safe | |
list of command arguments. | |
""" | |
def __process_string__(self, literals: Tuple[str, ...], values: Tuple[Any, ...]) -> List[str]: | |
""" | |
Processes the t-string into a list of shell arguments. | |
This method is called by the Python interpreter when it encounters | |
a string tagged with an instance of this class. It reconstructs | |
the string and then uses `shlex.split` to safely parse it into | |
a list of arguments, preventing malicious input from being | |
interpreted as part of the shell command itself. | |
Args: | |
literals: A tuple of the literal string parts. | |
values: A tuple of the interpolated values. | |
Returns: | |
A list of strings representing the command and its arguments. | |
""" | |
print(f"--- T-String Processor Invoked ---") | |
print(f"Literals: {literals}") | |
print(f"Values: {values}") | |
# Reconstruct the full string from its parts | |
full_string = "" | |
for lit, val in zip(literals, values): | |
full_string += lit | |
full_string += str(val) | |
full_string += literals[-1] | |
print(f"Reconstructed String: '{full_string}'") | |
# Use shlex.split to safely parse the command. | |
# This is crucial for preventing injection, as it correctly | |
# handles quotes and spaces. | |
args = shlex.split(full_string) | |
print(f"Parsed Arguments: {args}") | |
print(f"----------------------------------\n") | |
return args | |
# Create an instance of the tag processor. | |
# This 'sh' object will be used to tag our t-strings. | |
sh = ShellTag() | |
# --- Safe Function using T-Strings --- | |
def run_command(cmd_args: List[str]): | |
""" | |
Executes a command safely using subprocess. | |
This function expects a list of arguments, which is what our `sh` | |
t-string tag provides. It uses subprocess.run, which, when given a | |
list of arguments, does not invoke a shell. This is the safest way | |
to run external commands. | |
Args: | |
cmd_args: A list of strings, where the first element is the | |
command and the rest are its arguments. | |
""" | |
if not isinstance(cmd_args, list): | |
print(f"Error: run_command expects a list of arguments. " | |
f"Did you forget to use the 'sh' t-string tag?", file=sys.stderr) | |
return | |
print(f"β Running safe command with subprocess: {cmd_args}") | |
try: | |
result = subprocess.run(cmd_args, capture_output=True, text=True, check=True) | |
print("--- Command Output ---") | |
print(result.stdout) | |
print("----------------------") | |
except FileNotFoundError: | |
print(f"Error: Command not found: '{cmd_args[0]}'", file=sys.stderr) | |
except subprocess.CalledProcessError as e: | |
print(f"Error executing command: {e}", file=sys.stderr) | |
print(f"--- Stderr --- \n{e.stderr}", file=sys.stderr) | |
# --- Demonstration --- | |
def main(): | |
""" | |
Main function to demonstrate safe vs. unsafe command execution. | |
""" | |
print("="*50) | |
print("Demonstrating Command Injection Prevention with T-Strings") | |
print("="*50 + "\n") | |
# --- Scenario: Malicious Input --- | |
# An attacker provides a filename designed to inject a command. | |
# The injected command is `&& whoami`, which should not be executed. | |
malicious_filename = "non_existent_file.txt && whoami" | |
print(f"π Malicious Input: '{malicious_filename}'\n") | |
# --- Vulnerable Example: os.system with f-string --- | |
print("1. VULNERABLE ATTEMPT with os.system and f-string") | |
print("-" * 45) | |
# Here, the f-string directly embeds the malicious string. | |
# os.system passes this entire string to the system's shell (/bin/sh). | |
# The shell sees the '&&' and executes the `whoami` command as a | |
# separate, subsequent command. | |
unsafe_command = f"ls {malicious_filename}" | |
print(f"Executing unsafe command: os.system('{unsafe_command}')") | |
print("\n--- os.system Output ---") | |
os.system(unsafe_command) | |
print("------------------------") | |
print("π± VULNERABILITY EXPOSED: The 'whoami' command was executed!\n\n") | |
# --- Secure Example: run_command with t-string --- | |
print("2. SECURE ATTEMPT with run_command and t-string") | |
print("-" * 45) | |
# Now, we use our t-string. The `sh` tag triggers our ShellTag processor. | |
# `shlex.split` inside the processor correctly interprets | |
# "non_existent_file.txt && whoami" as a SINGLE argument. | |
# It does not see '&&' as a shell operator. | |
# The `run_command` function then receives a list: ['ls', 'non_existent_file.txt && whoami'] | |
# The `ls` command is executed with this strange filename, and it will | |
# (correctly) fail to find the file. The `whoami` command is never run. | |
try: | |
# This is the new t-string syntax. | |
# The `sh` before the quote marks it as a typed string. | |
run_command(sh"ls {malicious_filename}") | |
except Exception as e: | |
print(f"An unexpected error occurred: {e}", file=sys.stderr) | |
print("β INJECTION PREVENTED: The malicious input was treated as a single, literal") | |
print(" filename argument, and the 'whoami' command was NOT executed.") | |
if __name__ == "__main__": | |
# Check for Python 3.14+ | |
if sys.version_info < (3, 14): | |
print("This script requires Python 3.14 or newer to demonstrate t-strings.", file=sys.stderr) | |
sys.exit(1) | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment