I think the point that you bring up about having the basics covered is really important. It is intimidating to think about all of the things you need to think about to be an expert in security, to know what different kind of vulnerabilities there are out there… And I’m gonna let you know a little secret – no matter how much you catch, there’s always gonna be something there. I don’t think it’s possible to have code that is completely secure, unless it’s maybe one line, developed in isolation, and has no callouts and no inputs. It’s almost impossible. I don’t think you can necessarily lose sleep over that. You have to look at it from the basics perspective, and then from there, I think what a good security person will do is understand — because the way to make something the most secure is to make it not functional at all. You have to have a tradeoff.
A good security person will look at something and understand the business risks and understand really what it’s trying to do, and find the best way to put the most security measures in place. But some of the basics — I mean, I can go over some of the basics you should probably know, as a reference, to cover the basics.
I think three main things stand out that you can easily do and keep in mind when you’re developing something, and then you’re covering a substantial amount of vulnerabilities. The first one is the patch. Just make sure your libraries are up to date as much as possible, especially if there’s a security vulnerability. So just be aware that the latest one is probably going to be the best for that. It’s not always possible to keep things up to date, I understand that. In an environment where you have so many dependencies, sometimes upgrading is not an option. From there, there’s other mitigations you can put in place – put something in front of it, or try to learn what the exact vulnerabilities are and find out the ways of mitigating it. So patching and keeping things up to date is probably one of the most important things and one of the easiest wins you can have. That applies to operating systems as well, and applications and libraries.
The second thing – and probably the most important thing – is input validation. Understanding that the input that you’re getting from a user is what you think it is, and checking that on the server, rather than on the client. Because client-side control can be bypassed very easily.
[00:28:01.24] In a browser, if you use a proxy like Burp or ZAP you can intercept the request, change the data after it’s left the browser, and then send it on and it completely by-passes any kind of client-side input validation. So checking that the information that you’re getting is what you think it is, and not some malformed input like a super long string to get a buffer overflow, or negative numbers when you don’t expect negative numbers, or special characters that you don’t expect… The best way to do that is to use a whitelist over a blacklist.
The difference between a whitelist and a blacklist means — a whitelist is looking for a set number of things that are allowed, whereas a blacklist is looking for a set number of things that are not allowed. The number of inputs that can be allowed through is significantly less when you use a whitelist, so you are much more aware and you’re much more in control about the data that comes through, as opposed to with the blacklist… Where there may be a ton of things that you haven’t even thought of that could come through and could get around your validation.
So input validation is probably the most important, because really any vulnerability, any exploit comes from user input. If you can control that, if you can find some way of mitigating that, you could probably reduce at least 50% of the vulnerabilities that you may have in place, which is huge.
So doing patching, input validation and output encoding are three of the biggest things. There’s a few other things that I can just briefly mention, in case you’re taking notes and you want some more depth… One is hardcoded credentials in API keys. I think probably like four months ago it showed up on Hacker News that you could just do a search for password in Git pushes – you search that and you find thousands and thousands of Git commits that had a password in it, or had someone mentioning a password, or taking a password out of their application. So having those hardcoded credentials, especially in open source software, is trivial to find, and then someone could take that easily; they don’t have to have any skills, and they could just access your machine. So making sure you have a safe way of passing up strings and secure information and secrets to an application is important.
Then two other key things is authentication and authorization, so making sure that people are doing the things that they should be doing, and they’re allowed to do that and they’re gated from doing things they shouldn’t be doing. Then the last key point is encrypting data arrested in transit; making sure that you’re using a TLS over the web, you’re implementing a security certificate. Letsencrypt makes it super easy to do that now. And then encrypting it at REST, so using proven crypto, like AES or Bcrypt for hashing – just some examples.
I know that was a lot to take in, and I’m sure that a lot of people are probably gonna go back and review over that… But if you can just cover those things, just keep those in mind as you’re developing, I guarantee you’ll reduce at least 90% of the vulnerabilities that can be introduced in your application just from those things alone.