Tutorials Logic, IN info@tutorialslogic.com

Python Security Basics: Untrusted Data, Secrets, Commands, Serialization, and Paths

Trust Boundaries

Data becomes untrusted when it crosses from a user, file, network response, environment, database, queue, or external command into the program. Validation, safe APIs, output encoding, authorization, and resource limits solve different parts of that boundary.

After this lesson, you can choose secrets instead of random for tokens, pass subprocess arguments without a shell, reject unsafe deserialization, constrain paths to an owned directory, and keep credentials out of source and diagnostic output.

Input Contract

Parse external values into a narrow internal type early. Check allowed shape, length, range, and relationships; do not treat type conversion alone as validation. Reject unexpected fields when silently accepting them would hide a client mistake.

Validate a Positive Limit

Validate a Positive Limit
def parse_limit(raw: str) -> int:
    try:
        limit = int(raw)
    except ValueError as exc:
        raise ValueError("limit must be an integer") from exc

    if not 1 <= limit <= 100:
        raise ValueError("limit must be between 1 and 100")
    return limit

print(parse_limit("20"))
Output
20

Secure Randomness

The random module is intended for simulation, sampling, and reproducible pseudo-random sequences. Use secrets for password-reset tokens, session-like identifiers, and other values an attacker must not predict.

Create a URL-Safe Token

Create a URL-Safe Token
import secrets

token = secrets.token_urlsafe(32)
print(len(token) >= 32)
Output
True

The token itself changes on every run and should be stored or transmitted only through the intended protected workflow.

Command Arguments

subprocess does not invoke a shell by default. Pass an argument list and keep shell=False for ordinary programs so spaces and metacharacters remain data instead of command syntax.

Run a Fixed Program

Run a Fixed Program
import subprocess

result = subprocess.run(
    ["git", "status", "--short"],
    check=True,
    capture_output=True,
    text=True,
    timeout=10,
)
print(result.returncode)

Choose the executable and permitted options in application code; do not accept an arbitrary command list from a request.

Serialization Choice

pickle can execute code while loading and must never consume untrusted or tampered data. Use JSON for simple external data, validate the decoded structure, and use a purpose-built safe format when JSON cannot represent the domain.

  • Do not unpickle uploads, cookies, queue messages, or network responses from an untrusted source.
  • shelve also relies on pickle.
  • A file extension does not establish trustworthy content.

Owned Paths

Resolve the requested path beneath a fixed storage root and reject paths that escape it. Prefer mapping public identifiers to stored paths rather than accepting filesystem fragments directly.

Constrain a Report Path

Constrain a Report Path
from pathlib import Path

root = Path("reports").resolve()
candidate = (root / "weekly.csv").resolve()

if not candidate.is_relative_to(root):
    raise ValueError("report path escapes storage root")

print(candidate.name)
Output
weekly.csv

Secrets and Logs

  • Load credentials from protected runtime configuration, not committed source.
  • Never log passwords, tokens, authorization headers, private file contents, or complete connection URLs.
  • Use parameterized SQL and library escaping appropriate to the final output context.
  • Set timeouts, size limits, and rate limits at expensive boundaries.

Inspect the Boundary

0 of 2 checked

Q1. Which module should create a password-reset token?

Q2. Can pickle safely load arbitrary uploaded data?

Try this next

Threat-Model One Script

0 of 2 completed

  1. List its source, validation, internal type, output destination, and resource limit.
  2. Replace a command string built from user text with a fixed executable and validated argument list.
Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.