skills/python-security/SKILL.md
Guideline for designing, implementing, and verifying secure Python applications following OWASP Top 10 best practices. Use when the user wants to: (1) review Python code for security vulnerabilities, (2) design a secure Python application architecture, (3) implement security features (authentication, authorization, cryptography, input validation), (4) audit Python dependencies for known vulnerabilities, (5) create security checklists or verification plans, (6) fix security bugs or harden existing Python code, (7) set up security testing and static analysis (bandit, safety, semgrep), or (8) handle any Python security concern including injection prevention, secure deserialization, SSRF protection, secrets management, and secure deployment.
npx skillsauth add jim60105/copilot-prompt python-securityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Provide a structured approach to building secure Python applications, covering the OWASP Top 10, secure coding patterns, and verification checklists. Apply these guidelines throughout the secure development lifecycle — from threat modeling through deployment.
Before writing code, identify and mitigate threats at the design level:
Design with security controls built-in:
Never use these patterns. Violations are high-severity findings in any review.
| Never | Instead |
|-------|---------|
| eval() / exec() with untrusted input | ast.literal_eval() or a dedicated parser |
| pickle.load() with untrusted data | json.loads() or validated schema (e.g., Pydantic) |
| yaml.load() | yaml.safe_load() |
| shell=True + user input in subprocess | subprocess.run([cmd, arg1, arg2]) with list args |
| os.system() | subprocess.run() |
| String formatting / f-strings in SQL | Parameterized queries (cursor.execute(sql, params)) |
| random module for security purposes | secrets module |
| MD5 / SHA1 for password hashing | bcrypt or argon2-cffi |
| assert for security checks | if not condition: raise SecurityError(...) |
| Bare except: or except Exception: | except SpecificException: with proper handling |
| Hardcoded secrets in source code | Environment variables or secret manager (Vault, AWS SM) |
| DEBUG=True in production | Environment-specific configuration |
Apply a layered verification approach:
bandit — Python-specific security linter (AST-based)semgrep — Pattern-based analysis with OWASP and Python rulesetspylint — General linting with some security-relevant checkspip-audit — Check installed packages against the OSV databasesafety — Check against the Safety vulnerability databasedetect-secrets — Baseline-aware secrets scannerQuick tool commands:
# Bandit — static analysis
bandit -r src/ -f json -o bandit-report.json
# pip-audit — dependency vulnerabilities
pip-audit
# Safety — alternative dependency check
safety check
# detect-secrets — secrets scanning
detect-secrets scan > .secrets.baseline
# Semgrep — advanced pattern matching
semgrep --config=p/python --config=p/owasp-top-ten src/
For complete verification checklists (code review, architecture review, dependency audit, deployment, testing, incident response): See references/security-checklist.md
requirements.txtpip install --require-hashes -r requirements.txtpip-audit in CI/CD pipeline on every buildtrivy; use minimal base images (distroless, alpine); run as non-root userStrict-Transport-Security headerContent-Security-Policy, X-Content-Type-Options: nosniff, X-Frame-Options: DENYMap each OWASP 2025 category to Python-specific risks and primary mitigations:
| # | Category | Python-Specific Risks | Primary Mitigation |
|---|----------|----------------------|-------------------|
| A01 | Broken Access Control | Missing @login_required / auth decorators, IDOR via sequential IDs, path traversal, SSRF via requests.get(user_url) | Centralized auth middleware, object-level permissions, pathlib.resolve(), URL allowlisting |
| A02 | Security Misconfiguration | DEBUG=True in prod, CORS(origins="*"), Swagger/docs exposed, default SECRET_KEY, XXE via xml.etree | Environment-specific config, explicit CORS origins, disable docs in prod, defusedxml |
| A03 | Software Supply Chain Failures | Unpinned deps, typosquatting, no SBOM, unvetted transitive deps, CI/CD secrets exposure | pip-audit in CI, pinned versions with hashes, SBOM generation, CI/CD hardening |
| A04 | Cryptographic Failures | random module for tokens, MD5/SHA1 password hashing, hardcoded API keys, no encryption at rest | secrets module, bcrypt/argon2, env vars / secret manager, cryptography library |
| A05 | Injection | SQL via f-strings/.format(), shell=True, Jinja2 |safe / SSTI, eval()/exec() | Parameterized queries, subprocess.run([list]), Jinja2 autoescaping, ast.literal_eval() |
| A06 | Insecure Design | No rate limiting, missing input validation layer, no abuse case modeling | Threat modeling, validation at boundaries (Pydantic), rate limiting middleware |
| A07 | Authentication Failures | Weak session config, JWT algorithm="none" or HS256 with public key, no brute-force protection | Secure session settings, explicit algorithms=["RS256"], account lockout / rate limiting |
| A08 | Software or Data Integrity Failures | pickle.loads() / yaml.load() deserialization, unsigned updates, CI/CD pipeline injection | json.loads() / yaml.safe_load(), signed artifacts, pinned CI actions with SHA |
| A09 | Security Logging and Alerting Failures | Logging passwords/tokens, no auth event logging, missing alerting, no playbooks | Structured logging with field filtering, audit trail, alerting thresholds, honeytokens |
| A10 | Mishandling of Exceptional Conditions | Bare except: pass, failing open, transaction rollback failures, sensitive info in errors | Specific exception types, context managers, centralized error handlers, fail-closed patterns |
For detailed vulnerable → secure code examples for each category: See references/owasp-top-10.md
Follow this procedure when reviewing Python code for security:
pip-audit and safety check. Flag any unpinned dependencies or packages with known CVEs.bandit -r src/ and review findings. Run semgrep with Python and OWASP rulesets for deeper analysis.# === Static Analysis ===
pip install bandit && bandit -r src/ -f json -o bandit-report.json
pip install semgrep && semgrep --config=p/python --config=p/owasp-top-ten src/
# === Dependency Audit ===
pip install pip-audit && pip-audit
pip install safety && safety check
# === Secrets Detection ===
pip install detect-secrets && detect-secrets scan > .secrets.baseline
# === Pin Dependencies with Hashes ===
pip install pip-tools && pip-compile --generate-hashes requirements.in
# === Container Scanning ===
# trivy image <image-name>
Consult these files for detailed guidance beyond this overview:
development
Generate images via the Stable Diffusion WebUI / Forge HTTP API (AUTOMATIC1111-compatible `/sdapi/v1/*`). Use when the user wants to (1) discover or pick a model / extra module (TE/VAE) / sampler / scheduler / style preset from a running sd-webui server, (2) generate an image with a given prompt (txt2img), (3) check generation progress, (4) cancel/interrupt an in-flight generation, (5) inspect or change a global sd-webui option (e.g. active checkpoint), or (6) test connectivity. This skill talks to a *generic* sd-webui-compatible server (AUTOMATIC1111, Forge, reForge, sd-webui-forge-classic). Do NOT trigger for requests that are purely writing the prompt itself.
testing
Verify implementation matches change artifacts. Use when the user wants to validate that implementation is complete, correct, and coherent before archiving.
development
Update an OpenSpec change by revising its existing planning artifacts and keeping them coherent with one another. Use when the user wants to revise a change's plan, fold new decisions into it, or reconcile its artifacts after an edit. Never edits code.
data-ai
Sync delta specs from a change to main specs. Use when the user wants to update main specs with changes from a delta spec, without archiving the change.