Skip to content

Instantly share code, notes, and snippets.

@ksamuel
Created August 5, 2025 13:04
Show Gist options
  • Save ksamuel/2b30fd5572329f37000a3552fefc7add to your computer and use it in GitHub Desktop.
Save ksamuel/2b30fd5572329f37000a3552fefc7add to your computer and use it in GitHub Desktop.
Gemini t-string attempt
#!/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