Secure coding for Python with SheHacksPurple
Episode Deep Dive
Guests Background
Tanya Janca, also known as SheHacksPurple, is a long-time developer turned application security (AppSec) specialist. She spent 17 years in software development before moving into penetration testing and ultimately finding her true calling in AppSec. She loves helping development teams make their software more secure through collaboration, training, and practical guidance. Tanya also founded the website shehackspurple.ca and is the author of two books in the "Alice and Bob" series, including Alice and Bob Learn Secure Coding.
What to Know If You're New to Python
If you’re just getting started with Python and want to get the most out of this episode’s focus on secure coding, pay special attention to core practices like parameterized queries and frameworks such as Flask. Lean on Python’s built-in features for error-handling and input validation. Recognize that user input can be dangerous—never trust it without proper checks.
The 4 Steps of Threat Modeling
Threat modeling is “evil brainstorming”: thinking like an attacker to uncover vulnerabilities and proactively defend against them. Tanya mentioned Adam Shostack’s approach:
What Are We Building?
Define the system, its boundaries, and data flows. Draw diagrams that represent all components (APIs, databases, front-ends).What Could Go Wrong?
Brainstorm the ways an attacker could misuse or break the system. Challenge assumptions, like whether components trust each other too freely.What Are We Going to Do About It?
Prioritize the findings and decide on preventive and detective controls. This might include authentication, encryption, or rate-limiting policies.Did We Do a Good Job?
Revisit the models to see if critical threats were missed and whether newly added features introduce further risks. Update accordingly.
Key Points and Takeaways
1. Begin Threat Modeling Early
Rather than waiting until the end of development, bring in threat modeling at the design stage to identify potential attack vectors and build more secure systems from day one. Tanya emphasized how brainstorming “what could go wrong” and “how we’ll address it” pays off significantly down the road.
- Links and Tools:
- OWASP Threat Modeling
- Adam Shostack’s Blog (author of notable threat modeling books)
2. Proactive Over Reactive: Security Champions and Collaboration
Security shouldn’t be a lonely or purely reactive endeavor. Assigning a dedicated “security champion” within each dev team spreads knowledge, fosters better decisions, and ensures security becomes part of the culture.
- Links and Tools:
3. Input Validation and Least-Implied Trust
Humans tend to trust by default, but software systems need the opposite approach. Always validate and sanitize inputs—check that the data is the type, shape, and format expected. This applies equally to API calls, database queries, and internal functions.
- Links and Tools:
4. Distinction between Pen Testing and AppSec
While penetration testers focus on breaking systems, AppSec professionals focus on both break-and-fix. Tanya’s journey showcased how a developer mindset brings empathy, leading to better fixes and stronger collaboration with the dev team.
- Links and Tools:
5. Memory Safety and the Risk of RCE
Exceeding buffer limits or mismanaging memory can lead to remote code execution (RCE). Although much Python code is less exposed to these issues than C/C++ projects, understanding memory safety remains important, especially when combining Python with lower-level modules.
- Links and Tools:
- Rust Language (memory-safe option for new system components)
6. Dependency Management and Pinning Versions
Pinning dependencies (e.g., via a requirements.txt
or pyproject.toml
with locked versions) ensures consistent environments across dev, test, and production. This practice also helps reduce the risk of bringing in insecure or untested updates at the last minute.
- Links and Tools:
7. Database Security and Least Privilege
Use separate, minimal-privilege accounts for read vs. write (rather than always using db_owner
). Keep the database behind proper firewalls and do not assume trusted sources internally. Tanya reminded us that compromised internal systems often cause the biggest problems.
- Links and Tools:
- SQLAlchemy (Python ORM supporting parameterized queries)
- OWASP SQL Injection Prevention
8. Logging, Backups, and Incident Response
Logs are invaluable for detecting breaches and understanding the scope of an incident. Regular backups—tested in real-world restore scenarios—ensure minimal downtime if something goes wrong. Tanya shared cautionary tales of teams that lost entire codebases or historical data.
- Links and Tools:
- Semgrep Academy (Tanya’s free secure coding course resource)
- ELK Stack (logging platform)
Interesting Quotes and Stories
- SQL Injection Gasp: Tanya recalled demonstrating SQL injection so effectively in a training session that a participant literally ran out of the room to fix their production code.
- Pen Testing Revelation: Tanya’s early revelation came when she learned how easily a pen tester could bypass login with just a small snippet of malicious SQL, causing her to rethink how she approached coding and trust in user input.
Key Definitions and Terms
- Threat Modeling: The process of systematically identifying security threats and planning ways to mitigate them during software design.
- Purple Team: A blend of “red team” (attackers) and “blue team” (defenders), focusing on both breaking and fixing security gaps.
- SQL Injection (SQLi): An attack method where malicious SQL code is inserted into requests, allowing unauthorized access or data manipulation.
- Remote Code Execution (RCE): The ability of an attacker to run arbitrary code on a target machine or server over a network connection.
- Zero Trust: A security concept where no user or piece of data is implicitly trusted, and every interaction is strictly verified.
Learning Resources
To dive deeper into the security and Python topics discussed:
- Secure APIs with FastAPI and the Microsoft Identity Platform: A practical look at protecting Python APIs with industry-standard identity solutions.
- Managing Python Dependencies: A deep dive into best practices for pinned dependencies and virtual environments.
- Building Data-Driven Web Apps with Flask and SQLAlchemy: Learn how to safely interact with databases, using ORM best practices to prevent SQL injection.
Overall Takeaway
Securing a software project requires more than just fixing vulnerabilities at the last minute. As Tanya Janca emphasizes, it’s about working closely with developers, applying threat modeling early, enforcing strict input validation, and continuously focusing on both detection and prevention. By blending the mindset of a pen tester with the empathy of a developer, teams can create robust solutions that stand up to modern threats—and even transform security from a chore into an integral, rewarding part of the development process.
Links from the show
She Hacks Purple website: shehackspurple.ca
White House recommends memory safe languages: whitehouse.gov
Python Developer Survey Results: jetbrains.com
Bandit: github.com
Semgrep Academy: academy.semgrep.dev
Watch this episode on YouTube: youtube.com
Episode transcripts: talkpython.fm
--- Stay in touch with us ---
Subscribe to Talk Python on YouTube: youtube.com
Talk Python on Bluesky: @talkpython.fm at bsky.app
Talk Python on Mastodon: talkpython
Michael on Bluesky: @mkennedy.codes at bsky.app
Michael on Mastodon: mkennedy