Python › The Python Ecosystem for Security
The Python security ecosystem
Python’s real power for security is its libraries. This lesson is a guided map of the essential ones — what each does and when to reach for it — so you pick the right tool instead of reinventing it. You’ve met several already; here they’re placed in context.
You'll learn to
- Know which library fits which job
- Pick the right concurrency model
- Recognise the offensive specialists
The map
| Library | Job | Reach for it when |
|---------|-----|-------------------|
| requests | simple synchronous HTTP | most web testing and scripting |
| httpx | async + HTTP/2 HTTP | you need async requests or HTTP/2 |
| asyncio | async concurrency, one thread | thousands of concurrent I/O tasks |
| threading | thread concurrency | I/O-bound work, simple parallelism |
| multiprocessing | true parallelism | CPU-bound work like hash cracking |
| BeautifulSoup | HTML parsing | extracting links/forms from pages |
| Selenium / Playwright | browser automation | JS-heavy apps needing a real browser |
| scapy | packet crafting | custom network/protocol work |
| impacket | Windows/AD protocols | SMB/Kerberos/LDAP attacks |
| pwntools | binary exploitation | CTF and exploit development |
The concurrency decision
Three models, three jobs. Choosing right is the difference between a fast tool and a stuck one:
# I/O-bound (network) -> threading or asyncio
# CPU-bound (cracking, hashing) -> multiprocessing
# CPU-bound example: parallel hash cracking across cores
from multiprocessing import Pool
import hashlib
TARGET = "5f4dcc3b5aa765d61d8327deb882cf99" # md5('password')
def try_word(w):
return w if hashlib.md5(w.encode()).hexdigest() == TARGET else None
with Pool() as pool: # one worker per CPU core
for hit in pool.imap_unordered(try_word, wordlist, chunksize=1000):
if hit:
print("found:", hit); break
The rule of thumb: I/O-bound work (waiting on the network) wants threads or asyncio; CPU-bound work (burning processor on hashes) wants multiprocessing. Picking the wrong model is a common mistake — threads won’t speed up CPU work because of Python’s GIL.
Checkpoint
You're writing a tool that cracks password hashes against a wordlist. Should you use threading or multiprocessing, and why?
Multiprocessing. Hash cracking is CPU-bound — it burns processor cycles computing hashes, not waiting on I/O. Python's GIL prevents threads from running CPU-bound work in true parallel, so threading wouldn't speed it up. Multiprocessing spreads the work across separate processes (and CPU cores), giving real parallelism for CPU-heavy tasks.
Try it yourself
Look at a tool you’ve built or seen and identify whether its main work is I/O-bound (network requests) or CPU-bound (computation). Decide which concurrency model fits. Then list which three libraries from the map you’d reach for in your next recon project.
Key takeaways
- requests for most HTTP; httpx+asyncio for high-concurrency or HTTP/2.
- I/O-bound work wants threads/asyncio; CPU-bound wants multiprocessing.
- BeautifulSoup parses HTML; Selenium/Playwright drive real browsers.
- scapy, impacket, and pwntools are the offensive specialists.
Quick quiz
Next, the advanced Python features — classes, decorators, generators — that make tools cleaner and let you read any codebase.