Looking for a great Software Engineer? Or just feel like having a chat? Visit my profile on LinkedIn and say hi! 😃
If you enjoy this article, please hit the clap button 👏🏻 so that someone at FAANG who read it thinks I’m cool and offers me a sweet dev job! 😉
Much of this content came from LinkedIn Learning’s fantastic course.
General Security Recommendations
- Validate & Sanitize inputs and outputs
- Provide a Content Security Policy (CSP)
- Use cookie settings like HttpOnly, Secure, and Expire
- Always use HTTPS
- Mark session cookies as Secure Cookies
- Force the User to perform an additional step for sensitive actions like changing passwords, wiring money, etc. Examples for this extra step are entering an SMS-sent code, or going to a confirmation page and forcing the User to click a Confirm button, etc.
Good Housekeeping Rules for Security
- Update your software regularly
- Apply security patches ASAP when the come out
- Back up your data so that it stays available, even if you suffer an attack
- Secure your domain ownership settings with MFA (see DNSSEC)
- Secure your server —consider using: virus scanning software, firewall, DDOS prevention services, intrusion detection, etc
- Join the security community and follow security people on Twitter, which is where a lot of security news breaks first
Terminology & Security Concepts
Zero Day Attack
The developer has had zero days of awareness and zero days to craft a solution for the attack.
Intelligence gathering and recon done on a system by hackers. A systematic exploration of a systems defenses and vulnerabilities.
Principle of Least Privilege
Every program and every privileged user of the system should operate using the least amount of privilege necessary to complete the job.
No regular user with limited priveledges should have enough system access to edit their own priveledges.
Grant as little access as possible.
Defense in Depth
Have multiple layers of defense. Don’t just have one login, and after that you have root access to everything.
There are three basic types of defense controls:
- Physical — locks, security guards, etc
- Technical — hardware & software protections, MFA, least privilege, etc
- Administrative — policies, procedures, training, risk assessments, security reviews and audits, penetration testing, etc
Security through obscurity (STO)
Give out the least amount of info needed to complete the job.
Loose lips sink ships
STO is most effective when added to other security measures.
Deny and Allow Lists
A Deny List filters out actions that are not allowed, with the rest being acceptable.
An Allow List filters out everything by default, and only accepts the actions which are specified.
Allow lists are usually the more secure approach.
Mapping Exposure Points and Data Passageways
Map all the points that are accessible to an attacker. It’s where they could get data in or data out.
Make lists and diagrams showing the paths the data takes.
Check where data enters your systems, how it moves between system parts, where it’s stored, and how it’s returned to the User.
Also consider if the data passes through other potentially vulnerable hardware or software not connected to your system.
Filter input, control output. Good data is allowed through, while bad data is kept out.
These measures provide Defense in Depth:
- Regulate requests
- Validate input
- Sanitize data
A website should be selective about which requests in accepts. Make sure your app only accepts the HTTP methods for a specific URL that you expect — e.g.
POST, but not
Other filtering criteria
You can also filter by
- IP Address
- Query Params
- User-Agent String
You can also use firewalls and proxies, which are powerful tools for regulating requests.
Many hackers use the regular data input access points to hack your site. They do this by sending in malicious data in regular pathways like forms and API requests.
Some basic validation rules are:
- data type
- format of data. e.g. email address looks like an email address
- that the value inputted is within an acceptable range
Be careful about values like zero, which can cause issues with conditional logic in your code later on.
Just because data has passed through your initial validation, that doesn’t mean that it’s safe.
The easiest attack is to send through malicious data that passes your validations.
To sanitize your data:
Make sure that the data is of the right type by expressly typecasting the data in your code. E.g.
parseInt(input). Even if the data is already a number, it won’t throw an error. Make sure the typecasting happens as early as possible, so we don’t forget to do it later.
How we apply sanitization depends on where the data will go next. A Map of Data Pathways will help with this.
You should NOT attempt to sanitize the code yourself! This is extremely difficult and dangerous to do. Instead, you should use in-built functions in a language for sanitization, or well-tested and trusted libraries to perform the sanitization.
Also, avoid the temptation to remove or correct bad data. Stick to encoding or escaping.
Any stored data that you retrieve (e.g. from a database) should be treated as new data, and it should be sanitized.
Label Sanitized Data
It’s important to keep track of which data has been sanitized, and which data has not.
We can use variable names and prefixes to label safe and unsafe data. E.g.
- dirty, raw, unsafe, unsanitized
- clean, sanitized, safe
Keep Code Private
Keep as much of your code, especially code related to security, as private as possible, so that hackers can’t see exactly what you’re doing.
Keep Credentials Safe
Separate configuration from code, and make sure you don’t hard-code credentials into your files.
Best is to keep them in a Secrets Service and then use constants.
Be super careful with version control, since it’s very hard to purge credentials in a file once it’s been committed to a repository.
Keep error message vague
Don’t give Hackers a warmer/colder error message — e.g. username not found, password not found. Don’t let them learn from previous attempts.
Turn off in-browser error messages in a Production website, because it gives Hackers a TON of information.
Instead, return generic error messages like 400 or 500.
Logging is helpful, but it can become a security vulnerability.
Make sure you don’t accidentally log sensitive data like usernames, passwords, and credit card numbers.
Types of Credentials Attacks
- Credentials theft
- Brute-Force Attack - checks all character variations
- Dictionary Attacks - uses words in a dictionary for guesses as well as regular letter number substitutions, as well as regularly used passwords
- Credentials Stuffing - as soon as a credentials database has been breached, hackers race around the internet to try these newly acquired credentials, because users usually use the same Logins & Passwords
- Use long passwords (more than 12 characters)
- Use character variety (A-Z, a-z, 0–9, symbols)
- Avoid patterns and dictionary words
Length is more important than character variety.
It takes less than 3 hours to discover any 8 character password
It takes 2 weeks to discovery any 12 character password that uses only lower-case
BUT…. it would take up to 9000 years to discovery any 12 character password that uses character variety!
URL Manipulation & Insecure Direct Object Reference (IDOR)
Make sure that no sensitive or private information is available just by changing the URL.
IDOR is where you can access a secure resource without providing authorization credentials.
By changing the end of the URL, you shouldn’t be able to see object references that you aren’t authorized to see.
Web Security needs to be part of our daily coding ritual, like standup, brushing your teeth, or trying to figure out who took our food from the shared fridge.
Don’t look at it as an extra chore that’s on your job pile. Rather, see it as a central skill that you need to consider and employ every time you press a key.
That said, Happy Coding! 😃