How to avoid the perils of the OWASP Top Ten (and plan for a more secure web application).
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.
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!
Any security assessment must begin with an understanding of what security is. OWASP defines the three pillars of web security as:
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.
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?
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:
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.
Am I using, as code, data which the user can edit?
Grabbing URL parameters, form data, etc. Really any time the user can store something in your database.
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.
<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.
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.
Is it possible to pretend to be another user?
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 more good ideas for your authentication:
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.
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:
Wait, what was that third one again?
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
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).
Can anyone access parts of our web application that they shouldn't?
/wp-config.php
to the end of your URL/.git
to the end of your URL"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.
Do I have a process for updating my software and software libraries as quickly as possible?
Something bad happens.