How to not get hacked
How to avoid the perils of the OWASP Top Ten (and plan for a more secure web application).
Table of Contents
Planning a More Secure Web
There are no certainties in life. What we think of as secure today may very well be insecure tomorrow. The being said, having a plan - a plan for learning, preparing and responding - means that we can be ready to adapt to the unknowns that are always waiting around the corner.
Today we'll look at just this kind of plan, based on the upcoming OWASP Developer's Guide Opens in a new window. (Version 3 is still an open-source work-in-progress, but these principles are time-tested.)
After this, we'll have part 2 of last week's lesson - solving for the vulnerabilities we learned about in the Top Ten.
Warning
This next section is boring - but important
I find this kind of organizational management stuff really boring to read. And, if you do too, I think that makes total sense! It's actually boring by design.
The World Health Organization found when surgical teams use a checklist, including things like proper sanitary practices, it reduces post-surgery mortality by 47% Opens in a new window.
The purpose of a checklist is to make sure that people, like surgeons and astronauts, don't have to remember complicated procedures. Checklists are boring, but they are important.
But at least checklists are about something specific. If you take a checklist, and remove the specificity, you've got yourself an organizational framework.
Frameworks are essentially a checklist of problems to solve. Even if the solution is, in your circumstances, obvious, it's important that you've taken the time to say it out loud. You'd be surprised how many unsolved problems can make themselves apparent when you say your "obvious" solution out loud.
Some very smart, experienced people have put a lot of thought into the framework we're looking at today.
I personally find things boring when they are complicated, vague, and don't immediately seem to apply to me.
The whole reason this framework is important is because it is boring. People don't like to spend time thinking about boring stuff. So, instead of thinking about it, we can just reach for this framework.
Every company is different, and has different security needs. A large public company is highly visible, and will likely present a tempting target for many. Larger companies may have sprawling digital properties, which, by their sheer numbers, are difficult to audit on a regular basis. On the other hand, they likely have a lot of money, and may have an easy time convincing stakeholders to spend top dollar on security. (Whether that money gets spent wisely is another matter.)
Smaller firms may have less time and money, but may also have an easier time staying "below the radar", and, using agile processes, keeping their applications and infrastructure up-to-date.
A food-delivery startup will have different security concerns than, say, a cryptocurrency exchange, or a public library.
Security needs have to be assessed on a case-by-case basis. If there was a "silver bullet", a way to solve all problems in any context, this would be a much shorter course!
Wait, what is security?
Any security assessment must begin with an understanding of what security is. OWASP defines the three pillars of web security as:
- Confidentiality
- Keeping data, both user data and architectural data, both in transit and at rest, available only to those who should have access to it.
- This is my diary - no one can read it.
- Integrity
- Making sure data is only altered by those who should be able to alter it.
- This is my diary - only I can write in it.
- Availability
- Making sure that data (and, by extension, the services that provide access to that data) is available when ought to be.
- This is my diary - I have considered burning it on multiple occasions, but I need to remember how it all went down.
Makes you think of CRUD, doesn't it? Making sure that the right people, and only the right people, can read, create, update, and delete data.
Okay, but what are the principles of actually accomplishing this?
- Authentication
- Making sure people are who they say they are.
- This is my diary - I have the only key.
- Authorization
- Making sure people can do the things they're supposed to be able to do (no more, no less). If they're supposed to be able to do nothing, that's what they can do.
- This is my diary - if I forget to lock it, my Mom will definitely snoop on me.
- Auditing
- Having a reliable "paper trail" - a record that confidently shows that what has been happening is what has been happening. And if that's not the case, shows how to track down what when wrong, when, and what caused it.
- This is my diary - I have scotch-taped a single strand of my hair joining the front and back covers. If anyone sneaks in, I will know.
Alright, now that we agree on what security is, and the principles for increasing security, how does an organization go about turning those ideas into something real?
Policies → Standards →
Guidelines → Procedures
- Policies
- High-level documentation of how security is going to work in your particular circumstances.
- I will never let a living soul read my diary - not even my best friend, or a detective in a murder investigation.
- Standards
- Standards are practical rules that aren't limited to specific circumstances, for example organization-wide rules for password complexity.
- My diary must be kept out of plain view to keep people from the temptation of learning all my secrets.
- Guidelines
- Guidelines are specific "best practices", like a style guide.
- My diary should be kept between a mattress and a box-spring, or on top of a tall bookcase. Height is an advantage because my stupid brother is not only stupid but also short.
- Procedures
- Procedures are the "nitty-gritty", specific and work "out of the box". If guidelines are like a style guide, procedures are a component library.
- Every night that I write in my diary, I also write an entry in my decoy diary about how everyone is nice to me at school and how I wish I hadn't lost that green sweater that Aunt Janet bought me.
Risk Management
We've been learning how to identify risk, and how to plan to deal with, but what can be done with risk? Once you have identified where you're vulnerable, you've effectively got four choices:
- Acceptance
- Make peace with the risk. If it happens, it happens.
- If someone reads my diary, I can just move to Manitoba.
- Mitigation
- This is what we've been learning - work to make bad things less likely, have a smaller impact, and get caught quickly.
- My diary is written in a cipher, so even if someone reads it, they probably won't understand it.
- Transference
- Make your risk someone else's problem. For example, buy insurance.
- My brother know if I catch him reading my diary, mom and dad will find out why the basement sometimes smells like Grandpa's pipe.
- Elimination
- They say, "no risk, no reward". By the transitive property, we can say, "no reward, no risk". Eliminate the target.
- I sleep better knowing that I burned the pages I wrote while I was at summer camp.
The Top Ten
Okay, time for the big reveal - how to protect your application from anything bad that might ever happen!
Well, not really. What's important here is not learning specific scenarios or techniques. What's important is recognizing patterns of vulnerability and patterns of defense.
So take that as our caveat - what we're looking at today will not keep you safe, but learning these examples will help you keep yourself safe.
Injection
What to ask yourself
Am I using, as code, data which the user can edit?
A few scenarios
Grabbing URL parameters, form data, etc. Really any time the user can store something in your database.
How to fix it
Prepared statements and stored procedures
Most server side languages offer some kind of "prepared statement Opens in a new window". Most database servers offer some kind of "stored procedure Opens in a new window" (remember those?).
Both prepared statements and stored procedures effectively tell your database, "this is a single statement". You pass variables into these statements which the database understands are parameters. This means that you can't "piggyback" an additional statement or clauses onto your intended statement.
Escaping and serialization
<div id="target">
What's wrong with putting a quote (") inside
a quoted string?
</div>
<script>
let myStr = "What's wrong with putting ";
myStr += "a quote (\") inside a quoted string?";
document.getElementById("target").innerHTML = myStr;
</script>
"Escaping" is turning individual characters into something that doesn't mean anything to a computer.
"Serialization" is turning whole groups of characters into something that don't mean anything to a computer.
Either of these will serve to harden your security, but escaping can be bypassed, and neither is effective if it's done in the browser.
Black/whitelisting
You can make choices to restrict what characters are allowable when you accept user input.
Does anyone need an equals sign in their first name? Does that text input need to be a text input, or can you have a drop-down list that you validate against? This could have potential negative impacts on user experience (remember, names Opens in a new window and email addresses Opens in a new window are complicated). You know what else has negative impacts on user experience? Identity theft.
Broken Authentication
What to ask yourself
Is it possible to pretend to be another user?
A few scenarios (of many)
- You allow weak passwords.
- You enforce password complexity so stringent that your users all write their passwords down on a sticky note taped to their monitor.
- Users don't need anything except a password to log in.
- Users forget their password, and when they ask to reset it, you ask them what email address they want it sent to.
- You don't see anything wrong with a user trying to log in 800 times in 70 seconds.
- Security questions are known or easily guessed, like, "Where is the Eiffel Tower?" or "What's your favourite Fast & Furious?"
- You have default usernames and passwords like "admin/password1234".
How to fix it
Passwords are hard. Authentication is hard. The American government has a massive document on authentication Opens in a new window best practices. It is not an easy read.
One thing people are starting to admit: passwords are not that great.
There are so many leaked credentials out there that "brute force" attacks (where a hacker tries every possible combination of characters) have given way to "credential stuffing", where leaked usernames and passwords are used instead of random characters. This could be done with credentials specific to an application, or a hacker could simply use a list of the top passwords.
Here are the top 200 passwords for 2020:
123456, 123456789, picture1, password, 12345678, 111111,
123123, 12345, 1234567890, senha, 1234567, qwerty, abc123,
Million2, 000000, 1234, iloveyou, aaron431, password1,
qqww1122, 123, omgpop, 123321, 654321, qwertyuiop,
qwer123456, 123456a, a123456, 666666, asdfghjkl, ashley,
987654321, unknown, zxcvbnm, 112233, chatbooks, 20100728,
123123123, princess, jacket025, evite, 123abc, 123qwe,
sunshine, 121212, dragon, 1q2w3e4r, 5201314, 159753,
123456789, pokemon, qwerty123, Bangbang123, jobandtalent,
monkey, 1qaz2wsx, abcd1234, default, aaaaaa, soccer,
123654, ohmnamah23, 12345678910, zing, shadow, 102030,
11111111, asdfgh, 147258369, qazwsx, qwe123, michael,
football, baseball, 1q2w3e4r5t, party, daniel, asdasd,
222222, myspace1, asd123, 555555, a123456789, 888888,
7777777, fuckyou, 1234qwer, superman, 147258, 999999,
159357, love123, tigger, purple, samantha, charlie,
babygirl, 88888888, jordan23, 789456123, jordan, anhyeuem,
killer, basketball, michelle, 1q2w3e, lol123, qwerty1,
789456, 6655321, nicole, naruto, master, chocolate,
maggieown, computer, hannah, jessica, 123456789a,
password123, hunter, 686584, iloveyou1, 987654321, justin,
cookie, hello, blink182, andrew, 25251325, love, 987654,
bailey, princess1, 123456, 101010, 12341234, a801016,
1111, 1111111, anthony, yugioh, fuckyou1, amanda,
asdf1234, trustno1, butterfly, x4ivygA51F, iloveu, batman,
starwars, summer, michael1, 00000000, lovely, jakcgt333,
buster, jennifer, babygirl1, family, 456789, azerty,
andrea, q1w2e3r4, qwer1234, hello123, 10203, matthew,
pepper, 12345a, letmein, joshua, 131313, 123456b, madison,
Sample123, 777777, football1, jesus1, taylor, b123456,
whatever, welcome, ginger, flower, 333333, 1111111111,
robert, samsung, a12345, loveme, gabriel, alexander,
cheese, passw0rd, 142536, peanut, 11223344, thomas, angel1
Here are the top 10 million passwords Opens in a new window.
A few ways we've gotten smarter about passwords

- Complexity isn't as important as length.
- Multi-factor authentication is pretty strong.
- Default passwords are a bad idea.
- You can check a user-supplied password against the top 10,000.
- Your password policies should be evidence-based Opens in a new window.
A few more good ideas for your authentication:
- Hackers can figure out user credentials like usernames if your application tells them when a username exists. This is called an "account enumeration" Opens in a new window attack. Don't communicate that a username exists without successful authentication.
- Session IDs should be newly generated after a login, destroyed afterwards, and generally kept secret.
- It's a bad idea to keep users logged in when they're not doing anything, at least after a reasonable amount of time has passed. Kick them out for inactivity.
Sensitive Data Exposure
What to ask yourself
- Which data is sensitive?
- Am I ever receiving, storing, sending, or displaying sensitive data that is not encrypted?
- Can we just avoid having anything to do with that data altogether?
- Is our encryption up-to-date?
A few scenarios
Let's say you're a social media company. You're really good at making assumptions about people Opens in a new window, even if it might get them killed Opens in a new window.
"Personally Identifiable Information" (PII) is generally thought of as data that can be directly tied to someone's identity. Of course, you want to protect information that is obviously sensitive - names, addresses, credit cards, passport numbers, etc. But in today's algorithm-driven world, what constitutes PII might not always be obvious.

It's the responsibility of anyone collecting data to understand what they're collecting, and how it's being transmitted, stored and displayed.
There are common patterns of transmitting and displaying information that may not be as secure as you might assume. For example, it's not unusual to have a site display the last four digits of your credit card, but that can get a person hacked Opens in a new window.
How to fix it
Encrypting data is complicated. That's why we'll spend all next week looking at encryption (and similar techniques).
For the most part, though, dealing with sensitive data is a matter of:
- Categorizing data so you know what is and isn't sensitive
- Minimizing risk by dealing with as little sensitive data as possible
- Encrypting in transit by enforcing HTTP over TLS
- Encrypting at rest with a reliable encryption process
Wait, what was that third one again?
HTTPS & TLS
Alright, so last week we talked about HTTP Opens in a new window. You've probably noticed these days that most URLs begin with "https://" instead of "http://".
Both transmit data via the hypertext transfer protocol. If a URL begins with 'https' though, it means that the HTTP protocol is actually within another protocol - TLS.
TLS encrypts connections (and the data within them), so you can have your HTTP requests and responses happening without the risk of someone reading (or changing) them along the way.
TLS is a newer version of SSL, and is sometimes still called SSL. When you're getting an SSL certificate for your website, you're actually getting a TLS certificate!
While we're on the topic - SSL certificates are necessary for enabling HTTPS on your website, and are how you get that little "lock" icon in the URL bar on your site, meaning that a Certificate Authority has verified that you own your site.

Some website hosting will try to charge you an arm and a leg for your certificate, but you can get one for free from the non-profit Let's Encrypt Opens in a new window.
It's actually just a little plain-text file that you install at the root of your server, but it needs to be updated every 90 days. You could do it manually, but that just sounds like you're asking for trouble. The very cool non-profit Electronic Frontier Foundation Opens in a new window provides a free automated client called Certbot Opens in a new window that will automatically renew your certificates.
Once you have a valid SSL certificate installed on your site, you can make sure that all connections to your domain have TLS enforced (i.e. no 'http' without the 's', for all requests, including images, CSS and JS files) by setting your HTTP Strict-Transport-Security
header.
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
XML External Entities (XXE)
What to ask yourself
- Can we use JSON instead?
- Is our XML parser up-to-date?
A few scenarios
Honestly, you shouldn't be using XML data from untrusted sources. However, it can sneak in via older frameworks such as older versions of the SOAP messaging protocol Opens in a new window (used for communicating between different languages, like PHP and .Net, in a web application), or SAML Opens in a new window (meant for allowing a single web sign-in to be verified across different security domains).
How to fix it
- Use JSON instead
- Patch or upgrade all XML processors and libraries
- Learn how to restrict XML permissions Opens in a new window in the language of your choice
Broken Access Control
What to ask yourself
Can anyone access parts of our web application that they shouldn't?
A few scenarios
- I can see all your secrets by adding
/wp-config.php
to the end of your URL - I can see the location of all your files by adding
/.git
to the end of your URL
How to fix it
"Deny by default" - make sure that anything that is not public is hidden by default, and give out access in the smallest increments possible. Set up these rules both in your server configuration Opens in a new window and your user authorization flow.
Don't put private stuff anywhere it doesn't need to be (i.e. .git
files in the root of your server.
Security Misconfiguration
What to ask yourself
- Where is our security configured?
- Is it configured properly?
- How will we check, on a regular basis, that it's still properly configured?
A few scenarios
- Somebody broke the formatting of the HTTP header configuration
- Somebody installed a framework with bad default password settings
- Error messages give out sensitive info to public users
How to fix it
- Minimize the attack surface, or, in other words, deal with as few features that require securing as possible.
- Have a regular security review
Cross-Site Scripting (XSS)
What to ask yourself
- Have I taken all precautions against injection?
- Have I set my Content-Security Policy header?
A few scenarios
- Social engineering is used to get some poor sucker to click on a link with a nasty query parameter.
- Someone has injected a bad script into your HTML files
- Someone has taken advantage of a vulnerability in your SPA Opens in a new window to manipulate how the DOM is displayed to a user.
How to fix it
- Take the same precautions you would against injection
- Escape any user-editable data (including query parameters) before you trust it
- Set a strong content-security policy Opens in a new window via your HTTP headers
- Take advantage of XSS prevention in frameworks Opens in a new window, but don't rely on it Opens in a new window.
Insecure Deserialization
What to ask yourself
- At any point, are we accepting serialized data? Not just from our users, but from APIs, file servers, or any other web services?
- Are we then deserializing that data?
A few scenarios
- Allowing admin access based on a user-editable cookie
- Consuming data from an API that gets taken over by a very sketchy person
How to fix it
- Don't de-serialize data if you don't have to!
- If you do, do it in a "low-permission" environment so that you're not exposing your whole server.
- Perform "type checking" on deserialized data to make sure it's the right type of data (i.e. a string) before you do anything with it.
Using Components with Known Vulnerabilities
What to ask yourself
Do I have a process for updating my software and software libraries as quickly as possible?
A few scenarios
- You use software on the web. You thank your past self for going into a software field that makes updating so easy and take a moment of silence for everyone who is actually reviewing all your open source software for vulnerabilities.
How to fix it
- If you can turn on auto-update, turn on auto-update.
- Have a manual audit process.
- Additionally, have an automatic audit process (like retire.js Opens in a new window, for one example)
Insufficient Logging & Monitoring
What to ask yourself
- Where do we keep the server logs?
- Do the server logs actually contain actionable information?
- When was the last time anyone actually looked at the server logs?
A scenario
Something bad happens.
How to fix it
- Have a plan for what to do when something bad happens. Best to make this plan before something bad happens.
- Have a monitoring tool Opens in a new window - something that is gathering as much information as is reasonably possible about any risk you've taken on.
- Identify suspicious or malicious accounts
- Have a "paper trail" for any transactions.