Skip to content

Latest commit

 

History

History
110 lines (78 loc) · 4.26 KB

File metadata and controls

110 lines (78 loc) · 4.26 KB

Python Versions

Understanding Python 2 vs 3, how to check the interpreter version, selecting a specific python3.x, and why end-of-life (EOL) matters for security tooling.

Overview

Python 2 reached end-of-life on 1 January 2020 and receives no security patches — all new work should target Python 3. Even within Python 3, minor versions (3.9, 3.11, 3.12, 3.13) differ in syntax features, standard-library modules, and support windows. A security professional must know exactly which interpreter runs a script, because a scanner or exploit PoC written for 3.11 may fail on an older target's 3.6.

Syntax

python3 --version          # e.g. Python 3.12.4
python3.11 --version       # invoke a specific minor version
python3 -c "import sys; print(sys.version_info)"

Explanation

Python versioning is MAJOR.MINOR.MICRO. Compatibility is guaranteed within a minor line but not across them.

Version Status (2026) Notes
Python 2.7 EOL (2020) No security fixes — avoid; only for legacy target analysis
Python 3.8 EOL (2024) Do not target new work
Python 3.9 – 3.12 Security-supported Safe range for tooling
Python 3.13+ Current / bugfix Newest features (e.g. improved REPL, JIT)

Key Python 2 → 3 differences that break scripts:

  • print is a function: print("x"), not print "x".
  • Strings are Unicode by default; bytes and str are distinct — critical when parsing network/binary data.
  • Integer division uses //; / always returns a float.
  • input() no longer evals; urllib, http, and many modules were reorganized.
import sys

# Guard a script so it refuses to run on an unsupported interpreter
if sys.version_info < (3, 9):
    sys.exit("This tool requires Python 3.9 or newer.")
print(f"Running on Python {sys.version.split()[0]}")

Output

Running on Python 3.12.4

Examples

# List every python interpreter available on PATH
compgen -c | grep -E '^python[0-9.]*$' | sort -u

# Check versions of each
for p in python3.9 python3.11 python3.12; do
    command -v "$p" >/dev/null && "$p" --version
done

Output

Python 3.9.18
Python 3.11.9
Python 3.12.4

Security Use Cases

  • Confirming a target host's interpreter before dropping a Python payload — an exploit using f-strings (3.6+) or match statements (3.10+) will crash on older builds.
  • Pinning a reproducible interpreter version per engagement so a scan produces identical results months later during a retest.
  • Recognizing EOL interpreters on a client's assets as a finding: unsupported Python receives no CVE patches.

Best Practices

  • Target the oldest still-supported minor version you realistically need, then test on the newest.
  • Add a sys.version_info guard at the top of distributable tools.
  • Record the exact interpreter version in your engagement notes and requirements.txt (via python_requires).
  • Use [[Pyenv]] to keep multiple versions side-by-side for compatibility testing.

Common Mistakes

  • Writing python in scripts and shebangs — on modern distros it may be absent or ambiguous. Use python3 or a venv.
  • Assuming a feature exists on the target's interpreter (walrus := is 3.8+, match is 3.10+, tomllib is 3.11+).
  • Treating Python 2 as "still fine" for quick jobs — it silently mishandles Unicode and has no security support.

Practical Lab

Goal: detect and compare interpreters, and prove a version guard works.

  1. Run python3 --version and python2 --version 2>/dev/null || echo "no python2".
  2. Save the version-guard snippet above as guard.py.
  3. Run it with python3 guard.py (should print the version).
  4. If you have pyenv, install an old version (pyenv install 3.8.19) and run guard.py with it to see the guard trigger sys.exit.

References

Related

  • [[Installing-Python-on-Linux]]
  • [[Pyenv]]
  • [[Managing-Virtual-Environments]]
  • [[Python-Environment-Setup/Readme|Python Environment Setup]] — module index
  • [[Readme|Python for Security Professionals]] — course home