Single Responsibility Principle in Security Scripts
The Single Responsibility Principle (SRP) says a function or module should have one reason to change — it should do one thing, and do it well. In security scripting, this means breaking a script into small, focused functions rather than one long block of code.
Why It Matters for Security Work
Security scripts often evolve quickly. You might start by parsing IPs, then add hash extraction, then add reporting, then add command-line arguments. If everything is in one block, it becomes fragile.
Small functions make it easier to:
- Test — each function can be checked independently
- Debug — find which regex or parsing step is wrong
- Reuse — use
extract_ips()in another script later - Review — a teammate can read and verify one logical step at a time
A Bad Example
One function reads, parses, counts, and reports everything:
def analyze_logs(path):
with open(path) as f:
data = f.read()
ips = re.findall(r"\d+\.\d+\.\d+\.\d+", data)
counts = Counter(ips)
for ip, count in counts.most_common(5):
print(f"{ip}: {count}")
This works, but it is hard to extend. If you later want to extract hashes or paths, you modify the same function.
A Better Example
Each step is its own function:
def read_log(path):
with open(path, "r", encoding="utf-8") as f:
return f.read()
def extract_ips(text):
return re.findall(r"\b(?:\d{1,3}\.){3}\d{1,3}\b", text)
def top_items(items, n=5):
return Counter(items).most_common(n)
def main():
text = read_log("access.log")
ips = extract_ips(text)
for ip, count in top_items(ips):
print(f"{ip}: {count}")
Now extract_ips() could be reused in another script, and top_items() works for any list of strings.
Guidelines for Applying SRP
- Name functions by what they do, not by where they are used.
extract_ips(text)is better thando_log_stuff(). - Return values, do not print inside functions. Let the caller decide what to do with the output.
- Keep functions short enough to read at once. If you need to scroll, it may be doing too much.
- Group related steps in
main().main()is the coordinator, not the worker. - Separate parsing from file I/O and output. Parsing should work on a string, not depend on a file.
When to Break It
SRP is a guideline, not a rule. For very small scripts, a few extra lines in one function is fine. But as soon as a script is shared, reused, or handles attacker-controlled data, the cost of a messy function grows fast.
Related Concepts
- Python Essentials for Security Scripting — clean script structure and file I/O
- Defensive Input Handling for Security Scripts — validating input before parsing
- Designing Python Scripts for Automation and Pipelines — output design for reusable tools
- Python Functions — defining and returning values from functions
- Python File I/O — reading and writing files safely