security testing
Security testing is the practice of probing software for weaknesses an attacker could exploit, rather than confirming that its features behave as specified.
The Open Worldwide Application Security Project (OWASP) frames the goal as verifying that the security controls a system is supposed to have are actually in place. That makes security testing the verification counterpart to threat modeling, which reasons about the same risks while the design is still on a whiteboard.
The cheapest form reads the source without running it. Bandit builds an abstract syntax tree of each Python file and reports the patterns it recognizes as risky:
$ python -m pip install bandit
$ bandit -r checkout/
>> Issue: [B602:subprocess_popen_with_shell_equals_true]
subprocess call with shell=True identified, security issue.
Severity: High Confidence: High
CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
Location: checkout/backup.py:5:4
4 def run_backup(path):
5 subprocess.run(f"tar -czf backup.tar.gz {path}", shell=True)
That finding describes a real vulnerability. Interpolating path into a shell string lets a caller append a second command, so the report points at the exact line that allows it.
How It Shows Up in Practice
A Python developer usually meets security testing as a set of automated gates in a CI/CD pipeline rather than as a standalone project. OWASP’s security-culture guidance puts each check at the point in the software development life cycle where acting on it costs least.
Static analysis runs on commit, dependency scanning runs at build time, and dynamic scans run against a deployed staging environment. The tooling splits along the same lines. Bandit and Semgrep read Python source, pip-audit checks installed packages, and ZAP drives a running application:
Findings then surface the way test failures do, as a failed status check on a pull request. Teams pick a severity threshold so that a high-severity finding blocks the merge and lower-severity ones become tickets. A scanner that fails every build over minor warnings gets muted or switched off, which is how the practice most often stops working.
Web applications also get periodic deeper passes. The OWASP Web Security Testing Guide is the reference checklist for those, and NIST SP 800-115 covers the surrounding assessment methodology.
Common Variations
Security testing is an umbrella over several techniques, each of which sees a different slice of the system:
- Static application security testing (SAST): Analyzes source code, bytecode, or binaries without executing them, so a finding can point at an exact line.
- Software composition analysis (SCA): Matches third-party dependencies against vulnerability databases, often by reading a lockfile or a software bill of materials.
- Dynamic application security testing (DAST): Attacks a running instance from the outside with no view of the source, catching flaws that only appear at runtime.
- Penetration testing: Puts a human in the attacker’s seat to chain small findings into a real breach, which is the part no scanner reasons its way to.
None of these subsumes the others. Automated scanners catch known patterns cheaply on every commit, while human testers find the logic flaws that no rule matches, so teams layer the techniques much as the test pyramid layers functional tests.
Related Resources
Tutorial
Preventing SQL Injection Attacks With Python
SQL injection attacks are one of the most common web application security risks. In this step-by-step tutorial, you'll learn how you can prevent Python SQL injection. You'll learn how to compose SQL queries with parameters, as well as how to safely execute those queries in your database.
For additional information on related topics, take a look at the following resources:
- Python Code Quality: Best Practices and Tools (Tutorial)
- Continuous Integration and Deployment for Python With GitHub Actions (Tutorial)
- Securely Deploy a Django App With Gunicorn, Nginx, & HTTPS (Tutorial)
- Ruff: A Modern Python Linter for Error-Free and Maintainable Code (Tutorial)
- Using Python's pip to Manage Your Projects' Dependencies (Tutorial)
- Testing Your Code With pytest (Course)
- Managing and Measuring Python Code Quality (Course)
- Python Code Quality: Best Practices and Tools (Quiz)
- Python Continuous Integration and Deployment Using GitHub Actions (Course)
- GitHub Actions for Python (Quiz)
- Deploy a Django App With Gunicorn and Nginx (Course)
- Modern Python Linting With Ruff (Course)
- Ruff: A Modern Python Linter (Quiz)
- A Beginner's Guide to pip (Course)
- Using Python's pip to Manage Your Projects' Dependencies (Quiz)
Have a question about this? Mentor AI can show you examples, compare related terms, and point you to tutorials.
By Martin Breuss • Updated Oct. 20, 2026