Intermediate · Malware and web security · topic 27 of 43 · 35 min
Secure coding basics
Explanation
Why security analysts need this
You do not need to be a full-time developer to work in security, but you will review scripts, read code in incident investigations, write automation in Python, and explain fixes to developers. Knowing a few secure coding habits lets you spot the bugs behind most web incidents.
1. Never trust input
Input is anything that comes from outside your code: form fields, URL parameters, headers, cookies, uploaded files, API calls, even data from your own database that a user once typed. Treat it as possibly hostile.
Validation means checking input matches what you expect before using it. An allow-list (only these characters, this length, this format) is much safer than a block-list (block these "bad" words), because attackers find what you forgot to block.
import re
def valid_pincode(text):
return re.fullmatch(r"[1-9][0-9]{5}", text) is not None
print(valid_pincode("560001"), valid_pincode("56000"), valid_pincode("560001; DROP"))2. Encode output for where it goes
The same text must be treated differently depending on where it ends up: HTML, a URL, SQL, a shell command or a log. For HTML, encoding turns special characters into safe versions, so a comment containing <script> is shown as text rather than run.
import html
comment = '<script>alert("hi")</script> Nice post!'
print(html.escape(comment))3. Parameterised queries and safe commands
Use ? or named placeholders for SQL (previous lesson). For operating system commands, avoid building a command string from input; pass a list of arguments to subprocess with shell=False, and validate the input first.
4. Secrets stay out of code
- Never hard-code passwords, API keys or tokens in source code. Code is copied, shared and pushed to Git, and secrets leak with it.
- Read secrets from environment variables or a secrets manager.
- If a secret was ever committed, consider it leaked: rotate (change) it, do not just delete the line.
- Add secret scanning to your Git hosting so pushes with keys are blocked.
5. Errors and logs
- Show users a short, friendly error; write details to the server log.
- Never log passwords, OTPs, full card numbers or full Aadhaar numbers. Mask them: UIDAI's own "masked Aadhaar" shows only the last four digits.
- Do log security events: logins, failures, permission denials, admin actions.
def mask_aadhaar(number):
digits = number.replace(" ", "")
return "XXXX XXXX " + digits[-4:]
print(mask_aadhaar("1234 5678 9012"))6. Path traversal
If a user can choose a file name, they may send "../../etc/passwd" to climb out of the intended folder. Fix: never use the raw name. Allow-list the characters, or map an ID to a file name on the server, and check the final path is still inside the allowed folder.
7. Dependencies and least privilege
- Use well-known libraries, pin versions, and update when security fixes come out (pip-audit, npm audit, Dependabot-style alerts).
- Run apps with the least privilege: a web app should not run as root or connect to the database as an admin user.
Common mistakes
- Validating only in the browser with JavaScript. Attackers skip the browser; validate on the server.
- Using a block-list like "remove the word script".
- Committing .env files or keys to GitHub.
- Logging full request bodies that include passwords or OTPs.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Secure coding basics · 1/7
Secure code stays safe when people send unexpected or hostile input.
Prefer a video by a teacher? Find free videos on “secure coding basics input validation output encoding secrets management” on YouTube ↗
In real life: The API key on GitHub
A developer at a Hyderabad fintech start-up pushed a test script to a public GitHub repository. It contained a live cloud access key. Automated bots scan public repositories for keys constantly; within hours the key was used to start expensive machines for crypto mining. The company rotated the key, removed the unused permissions it had, turned on secret scanning for all repositories, and moved keys into a secrets manager.
Practice (0/4 done)
Which validation approach is safer?
Write render_comment(name, text) that returns "<p><b>NAME</b>: TEXT</p>" with both name and text HTML-escaped using html.escape (quotes too).
Write mask_aadhaar(number) that accepts a 12-digit number with or without spaces and returns "XXXX XXXX " plus the last 4 digits. If, after removing spaces, it is not exactly 12 digits, raise ValueError.
Path traversal check. Write safe_name(filename) that returns True only if the name uses letters, digits, "_", "-" and at most one "." in the middle (like "report_2026.pdf"), with no slashes, backslashes or "..". Use re.fullmatch.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- How defenders detect malwareMalware and web security · same module
- Malware types and how they get inMalware and web security · same module
- SQL injection and how to stop itBackend Development · Backend security
- A full-stack security reviewFull-Stack Development · Performance, security and testing
- SQL injection (SQLi)Ethical Hacking and Penetration Testing (legal labs) · Web attacks and their fixes
- SQL injection and safe queriesJava Programming (Core to Spring Boot) · JDBC, Maven, Gradle and JUnit
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Where must input validation always happen?
Answer: On the server
Attackers bypass the browser; the server must check.
A password was committed to Git last month and then deleted. What now?
Answer: Rotate (change) the password: it is in the history and may be copied
Git keeps history and copies spread; treat it as leaked.
What should never be written to logs?
Answer: Full passwords and OTPs
Logs are read by many people and systems; secrets must not be in them.
A user sends filename=../../etc/passwd. What attack is this?
Answer: Path traversal
The ../ climbs out of the intended folder.
Why should a web app not connect to its database as an admin user?
Answer: If the app is hacked, the attacker gets admin power on the database
Least privilege limits the damage of a compromised app.
What does "least privilege" mean for the app's database user?Related
Answer: It can only do what the app needs, nothing more
With only the needed rights, even a successful attack cannot drop tables or read unrelated data.
A secret API key was committed to git last month. What is the right fix?Related
Answer: Rotate the key and move the new one into environment settings
The old key stays in git history, so it must be replaced. The new key lives in environment variables, not in code.
Parameterised queries protect you because input is…Related
Answer: Treated only as data, never as SQL code
The database treats placeholders' values as pure data.
From SQL injection (SQLi)
What does "least privilege" mean for the app's database user?Related
Answer: It has only the permissions the app needs
Limits the damage if something goes wrong.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- This is the last topic of “Malware and web security”. The module exam comes next.
- Module 6 exam: Malware and web security · 13 questions · 25 min, without help. 4 topics of this module still to finish first.
- Then the next module, Cloud security basics. 43 topics left in the course before the final exam.