Module 1: Security in the SDLC
Why Developers Own Security
Most security vulnerabilities are not exotic. They are ordinary programming mistakes: a query built by joining strings, a missing permission check, a password logged in plain text, an outdated library. Firewalls and security teams cannot fully fix code they did not write. The person best placed to prevent these mistakes is the developer writing the code, at the moment it is written. That is why modern teams treat security as part of every developer's job rather than a separate stage at the end.
The cost of finding problems late
Think about the life of a feature in the software development life cycle (SDLC): requirements, design, coding, testing, deployment and maintenance. A security flaw can be introduced at any stage, and the later it is found, the more work it takes to fix:
- During design: a quick conversation changes the plan. No code is wasted.
- During coding: the developer fixes a few lines before committing.
- During testing: the fix must be re-coded, re-reviewed and re-tested, and the release may slip.
- In production: you may face an incident, customer data exposure, emergency patching, reporting obligations under data protection law, and damage to trust.
Moving security activities earlier in this process is often called shifting left, because the SDLC is usually drawn from left (requirements) to right (production).
What "owning security" means in practice
Owning security does not mean every developer must become a penetration tester. It means building a few habits into your normal work:
- Ask "how could this be abused?" when you design a feature, not only "how will it be used?"
- Use safe defaults and safe libraries: parameterised queries, framework templating that escapes output, well-known authentication libraries.
- Never trust input: anything from a user, a file, an API or even your own database can be malicious or malformed.
- Keep secrets out of code and out of logs.
- Review and test for security as part of normal code review and continuous integration.
- Keep dependencies updated and know what third-party code you ship.
A useful reference throughout this course is the OWASP Top 10, a widely used awareness document published by the Open Worldwide Application Security Project that lists the most critical categories of web application security risk. It is updated every few years, so check the OWASP website for the current edition.
Worked example: one small mistake
Imagine a hypothetical online shop in Nairobi that lets customers view their orders at a URL like /orders/1042. The developer writes:
@app.route("/orders/<int:order_id>")
@login_required
def view_order(order_id):
order = db.get_order(order_id)
return render_template("order.html", order=order)
The code checks that the user is logged in, but not that the order belongs to them. Any customer can change the number in the URL and see other customers' names, phone numbers and delivery addresses. This flaw, often called an insecure direct object reference or broken object-level authorisation, is one of the most common in real applications. The fix is one line:
order = db.get_order(order_id)
if order is None or order.customer_id != current_user.id:
abort(404)
No security tool installed later would have been as cheap as the developer asking, while writing the function, "who should be able to see this?"
Security as a team practice
Individual habits work best when the team supports them. Effective teams agree on secure coding standards, include security items in their definition of done, run automated security checks in their build pipeline, and keep a few security champions: developers with extra interest and training who help colleagues and liaise with any security specialists. When an incident or bug is found, they run a blameless review to fix the process, not to punish a person.
Common mistakes to avoid
- Assuming the framework or the security team will catch everything.
- Treating security bugs as lower priority than features until something goes wrong.
- Relying on client-side checks (JavaScript validation, hidden buttons) for security.
- Copying code from forums without understanding what it does.
- Believing "nobody would target us"; automated attacks scan every reachable site.
Exercise
Open a small project you have written, or a sample web application on GitHub. Find one route or function that reads a record by ID and check whether it verifies that the current user is allowed to access that record. Write down what you found and, if the check is missing, add it and test that another user's ID now returns an error.
Key points
- Most vulnerabilities are ordinary coding mistakes that developers are best placed to prevent.
- Fixing security issues gets more expensive the later they are found, so shift security left.
- Always check that the current user is allowed to access the specific object requested.
- Use the current OWASP Top 10 as a reference for the most critical web risk categories.