[Inaudible] this presentation is brought to you by RingCentral developers. Revolutionize the way your business communicates with RingCentral's API is for voice, SMS, team messaging, meetings and facts. Don't just be a developer. Be a game changer with RingCentral developers.
All right, so this is me. You can find me on Twitter. Please feel free to follow me this way. I will feel good about myself. So I as Mike mentioned earlier I've been in this for a little while. I started writing software in the mid nineties for web web applications and I've been at it since then and I've been fortunate enough to work in different technology stacks that I've been able to get exposed to a lot of different issues and problems and challenges and threats. One of those threats are security in web applications. It's a, it's always been big problem and it continues to be a big problem. And so we will look a little bit that how we can improve our situation and try to take a practical look at a web application with application security.
So this slide in this presentation, we're going to go over a lot of topics several of which could be their own when our presentations. So I'll have links. I'm going to have links to articles and other presentations so that you can learn more and dig into the different topics. So so this is this Bitly URL that you see you can use that to download a PDF of the presentation and in that PDF every link is going to be clickable to the references that I mentioned in there. So, Mike, can you still hear me okay? We good? Yep. All right, sounds good. All right, so let's get started. So that's the slide. So yeah, let's look a little bit at the software. Before we dive into web applications. Let's, let's look at software because it's definitely everywhere.
I try to think of an aspect of your life that is not impacted by software, right? You think about it. Banking, healthcare, finance, software runs all these industries, travel, entertainment, communications, and this is where it gets creepy, right? Home automation, alarm systems, fire detection, surveillance. Military and, and also aerospace, right? But we also see a software in cars increasingly, right? So Tesla is doing just doing some really cool research with kind of a semiautomatic, autonomous, as well as autonomous cars. And of course you might ask yourself you know, what could possibly go wrong while this could happen? Of course. But, you know, there's, there's been a lot of security issues. If you go back to 2015 you know, I'd Def gone, you know, some, some hackers and researchers showed how you can just hijack a Jeep on the highway and you know, do bad things.
And then the following year in 2016, they found more vulnerabilities or the same kind as well. So yeah, you'll be able to click on those links to read those articles. It's it's, it's pretty creepy. It's pretty up there. So, but now let's go right back down to web applications. Let's look at your business and let's look a little bit at your threat model for your business, right? At the core of it one of the most valuable assets they're going to have in your business is your data. Right? and so let's say you've done things marginally well and your, your, your data lives on your own kind of network and that's pretty isolated. So inside of this network which is a private network, you may have two obligations. One is your inventory management and the other one is a customer relationship, relationship management application.
And these things are not exposed to the world. So that's pretty good. And then under the same time though so you're gonna, you're gonna have a VPN system that allows your employees to kind of get into your cloud and interact with that inventory or CRM system. So that's kind of a, from an employee standpoint. And then most often you also want to expose it to some of your business data to the world. It could be through your marketing website. It could be through a software as a service web application like app dot your business, osc.com, or it could be an API as well, right? So these applications on the right, you're going to expose them to the world, right through ports 80 or preferably four, four, three. If you're doing, you know, if you're doing KLI switch, you know, ideally you should be.
So, so now you kind of have two main threat vectors. Attackers are going to go after your employees by sending them phishing emails to try to get their credentials so they can get through to your VPN, for example. But then attackers are also going to try to exploit the web applications, which you are exposing to the whole world, right? Through ports 80 and four 43. So that's kind of the, your highlight very high level, very basic threat model. Of course there are many other things, but these are the main things to really keep in mind. So for the purpose of this presentation, we're going to focus on the latter part, which is really your web applications, right? I'm not going to show you the different phishing vectors that attackers are going to do to compromise their employees. So we're going to focus on those web applications.
Port 80 and four 43. All right. So what are the risks to people compromising your web vacations? Right? There's exfiltration data. So you have sensitive customer sensitive customer information and it's very valuable to hackers. You get intellectual property as well. And then there's doing things like performing on authorities operations, right? If you're performing a bank, you could have a vulnerability that allows somebody to, you know, send money to to some unintended person. Right? and you know, sometimes there's also kind of competitive pressures where people just want to disrupt your business. So that happens too. And then another thing is kind of advanced persistent threat. So that's gonna when a hacker is able to kind of infiltrate your network and they're able to just kind of sit there to do more or any affairs activities that are wrong.
So, you know, there have been quite a, you know, if you look at the news there, you'll see a lot of security breaches. So if you want to, you know, get depressed. I have a few links to, you know, some articles that talk about some of the higher profile data breaches. So you can, you know, check out those articles. Oh, so, you know, but a few of them, right? So Yahoo they were a victim of spearfishing, which allowed some hackers to compromise one of the internal web applications. And then 3 billion accounts were compromised and that happened just before their merger with Verizon, which was uncomfortable. And then you have the in the United States there's the office of personnel management, which is kind of government workers in the United States. A lot of information got stolen there through a combination of a contractor, credential theft malware advanced versus in threat and 9 million government records.
So one, so the Equifax story is really purely a web application. Compromise. I through a [inaudible] very well known kind of a O OS top 10 vulnerability. And we're going to look at what a wasp is, which was a non insecure comp component. I'm one of their templating engines had a vulnerability and they forgot to patch it and they got compromised. 143 million customers got compromised by with Equifax. So it's devastating. So, well, obligations are an interesting beast because you know, there are million millions of them. They're just kind of out there. And they're, they're up there 24, seven and scanning them is very easy to automate. And most of them will have some access to sensitive information and expose it. And so they, they present a larger tax or face surface with a lot of attack vectors.
And then do you know if service a is also a threat to a web applications? Not going to cover this in this talk, but I will be talking about denial of service attacks in my Midwest, PHB talk in April, I think. So if you're interested come to Midwest, PHB Mike will tell you more about that later. So yeah now we're going to look at some strategies to kind of make ourselves harder to hack, right? And it's, and it's tough because we have to be right 100% of the time and a hacker only has to be right once to compromise us. So the first thing we're going to try to do is educate ourselves. It's very important that we educate ourselves. We're short of doing that. We're going to look at code reviews. You know, when, when we do pull requests and once we've have educated ourselves, then our code review process can incorporate security review.
But then we're going to look at some tooling. So we're going to look at automated code scanning in your continuous integration pipeline. We're also gonna look at dependency, vulnerability check checks in your continuous integration pipeline as well. We'll look at automated manager penetration tests, whether we given firewalls and when all else fails, hope that you have some logging in place to figure out what went on. But you really want to try to catch things upstream, right? So if you look at this stack, you know, the higher you catch things in this stack, the better off you are, right? The lower you catch things in the stack, the more expensive fixing issues becomes. So, so we're, we're really gonna explore the areas that I have highlighted in bold right now. So let's start. So I'm also going to draw a red line. This red line is kind of a symbolic line where you really want to try to catch a shoes above the red line. Once you go below the red line, then issues are harder to catch and they're also more expensive to fix.
All right, so first, let's look at educating humans. Oh, wasp is a great organization, which has been around for a long time. And I highly recommend that everybody visits a wasp.org. It's free information to help you secure your web applications, free information as well as a lot of different tools. So yeah, and, and the nice thing about them is they, they look at this from a people process and technology standpoint. And I think that's very important because [inaudible], you know, security is not just a technology issue. We should all own it and people are core to this. And the processes that we put in place are core to this. So that's the nice thing about a wasp. They really look [inaudible] got it from a people process, process and technology standpoint. So every year actually no, it's sometimes it's every year. It's every couple of years.
They'll publish a list of top 10 types of vulnerabilities for web applications. And it, it tends to be, you know, the same usual suspects with some variations over several publications. So we'll look at several of those within the course of this presentation. But here is the URL to their, a top 10 projects. So please visit it and learn a straight from the source because they show you really the threat vectors and how to avoid them. So let's look at, let's get back to tooling now. Let's look at automated code scanning. So this is for code that we software engineers write for our web applications. And inside of our CIP pipeline, we can add tools that will do scanning for us. So here we go. [inaudible] Has a list of tools at this URL so you can check it out, but we're going to look at a few of them. So, so in our queue is a free open source project, which has plugins for virtually every language. And so if you use C sharp.net their security code scan if you're doing Java, you got find sec bugs for for Java spot bugs as well. So for PHB you have proc pilot peach BCS security audit as well as sonar PHB. So, so not PHB is a plugin for SonarCube, which we just looked at or earlier.
There are also if you look around, you'll, you'll see a lot of commercial tools, right? So I'm trying to stick to the open source side of things, but there are a lot of very valid and valuable commercial tools. I'm just trying to not highlight too many of them. Just so I don't look like I'm trying to show for one or the other. So, all right, so you got a dependency vulnerability checks as well. So these are for our, not for code that we write, but it's for third party code that we use, right? So if you look at your PHB project and you have your composer file with references to all sorts of third party open source software chances are some of that third party opens. Our software has vulnerabilities in there, so we're going to look at tools that will make you aware of those vulnerabilities. [inaudible]
So [inaudible] has created their own tool called old wasp dependency check which worked out of the gate with a Java and C sharp. But they've added the support for Ruby node, Python, NPSP. Now for PHP, we have two great tools that we can use. We have from Rove, we have the security advisory advisories framework, which will work for new packages. So when you install new packages and composer this plugin will kick in and it will look for any kind of vulnerabilities as you're adding that third party package to your dependencies, right? So it's really for new things that you're adding to your project and so as such, it as quicker. But you also want to look at everything yet that you may have already had before you installed a row Rose login. So you have a friends of PHB, they've got a plugin called security advisories, and that works for all packages that are referenced in your composer.
And it's of course it's going to be slower, right? So you can use one of the two or both in conjunction. They're a great tools to have and if you work with draw script there is a tool called retire Dodge ass, right? So that, you know, it's kind of a play on required jazz, what you require. You might one day retire because it has some real vulnerabilities in there, so you can check that out as well. Okay. So and then you get tools for C sharp and.net. There you go. So that was for vulnerability checks. So now we're going to look at automated penetration tests. If you think about it, you know, the nice thing about hackers is that they're very nice people. They are doing automated penetrate penetration tests for you for free pretty much constantly, right?
As soon as you put your web application out into the world there are going to be, you will, if you tell your logs, you will eventually see some script issuing some really weird requests. If you tell your log, you will see all those requests and that's beautiful. Running vulnerability scans of your application. It's, sometimes it can be hacker, sometimes it's just security researchers. Either way assume that it is happening in production to your web application. And as such, you want to try to do this to yourself well ahead of pushing code to production. And so we have a [inaudible], we're going to look at some penetration testing tools. So O wasp has made a tool of their own it's called ode WTF. And it does not stand for what you might think. It tends for offensive web testing framework.
There's also the a O OS Zed attack proxy project that you can check out. And of course there is the famous and longstanding Metis bloat framework. So meta sploid is a comprehensive framework for information security and that can run all kinds of exploits for a lot more than web applications, but it has a lot of plugins for web applications. So you can, and you probably should use Medis bloat to try to do penetration tests on your web applications as well. So, all right, so that was for automated penetration tests. So now we're going to look at web application firewalls also known as [inaudible]. So a WEF is something that you usually put in front of your web application.
Mmm. And it it intercepts all your, all the re incoming requests and it does some it'll do some realtime analysis against some known rules. And if it recognizes a penetration attempt then it will block that request. So I've worked with a few over the years. They're okay. They can get annoying very quickly because false positives, false positives are a thing. I found a lot of the rules in those labs to be, you know, pretty basic and in serious need of refinement. And even then it's kinda hard in, in many cases to avoid false positives, especially if you're running a web application which has a lot of user generated content. That's when you're going to trigger a lot of false positives, right? If somebody puts, you know, one equals one in a blog post for example, well, you know, your web application firewall might think that you're trying to do a SQL injection.
So it's not great. So you've gotta, you know, if you want to use a web application firewall and make sure that you spent a lot of time testing it and a lot of time vetting it and try to not roll it out to your entire population at first. Try to really give a time to make sure you test it and that you're not getting false positives. Mmm. So there are a few open source ones, so I have links to mot security the rest of the plugin for engine X there's also one called NAC C and then a shadow demon from a secure. So these are some of the open source solutions out there. Of course, again, there are a lot of commercial solutions as well. Yeah, I won't get into them in this presentation.
Okay. So this was for the tooling section of the presentation. So now we're going to go back to educating humans. So let's try to understand some of these vulnerabilities and I try to classify them as low-level vulnerabilities and then, and then kind of higher level application of vulnerabilities. So let's look at low-level vulnerabilities first. And among those we're gonna look at injection enrollment bilities such as SQL and no sequel injections cross site scripting cross-site request forgery. Those are pretty low level. All right, so let's start with SQL injection. You may have all seen this cartoon. Okay. From XKCD it's a, it's at least a decade old. So I'll let you digest that on your own. So the impact of a sequel injection is pretty devastating. I, it can a sequel injection, you can leak data, destroy data, overrode it, override it.
It, I mean, it's no longer your data with the right sequence, with the right type of signal introduction. It really becomes no longer your data. It's pretty terrible. So yeah, you can do things like escalate, you know, you could be become an admin on the web obligation. And for example so the [inaudible] tour of attack for SQL injection is quite simple. Anytime you inject a variable inside of an SQL query string, it kind of looks like this in PHP, right? You have an SQL statements. So like start from users where ID equals and then you just plug the user ID in there, right? And that user ID comes from and that user ID comes straight from the request and from the HEB request. So then it becomes very easy to make what should be a user ID a fragment of the SQL string to do something that it was not intended to do.
So to mitigate it it's pretty simple. Use prepared statements. That's the biggest thing. That's really the, the one thing you should be doing to avoid sequel injections. It's really to use prepared statements with like name parameter binding. And it kind of looks like this. You go select star from users where ID equals in the Eagle colon ID, right? So you're no longer modifying the string by injecting a viable, and it your, the string itself always remains the same and it's just say it's colon ID, but then what you're going to do is you're going to use like a bind parameter statement to buying an ID value to this ID parameter. So I have a link on how to do this in every programming language. That's the link right here in the wasp. Every relational database system supports this.
And every language supports this. So there is no reason to not be using prepared statements. So I want to stress that, you know, a lot of people say, well, you should sanitize your inputs. It's not enough. Sanitizing your inputs is not always practical in the sense that, you know, sometimes you're operating a forum and you have a forum posts and you can't really enforce that something is an integer. Sometimes it has to be a string. So then you start escaping the Strang. But when you start to escape things, things become brittle and things will get missed. And yeah, in the end, a prepared with a prepared statement. You don't even need to do any kind of input. Sanitation, it's a good idea to do some, some input, sanitation, but a prepared statement is the most effective line of defense. So definitely focus on that.
All right. So here's an example of a prepared statement and how you would do it with a, with the PDO. Here's, here's PDL. Okay. So now a lot of us do use RMS and you're not [inaudible], you're very likely not how the woods and when it comes to sequel injections, when you work with ORMs or if you work effectively with an RM, then you are in a much better position. But there are some things to watch out for. So a while back there was a, a MITRE vulnerability that was a, that was documented at this URL. That showed a a high bar hibernate query language injection, which is a HQL which is the hibernate is the RM. That's you. It's a data map or ORM that's used heavily in the job world and some in a little bit in C sharp as well.
And the thing in PHB land is that it a doctrine since doctrine ORM was a port of hibernate to PHB or regionally, chances are that this vulnerability could be applicable to doctrine, ORM. So here I have a link two on how to test for RM injections from the a wasp site. So you should kind of check that out and make sure that you are using proper patterns, but we're going to look at a little bit that whether that might be so there are two prevalent types of RMS that I know of. One are active record ORMs such as in Laravel you have the eloquent, eloquent, ORM. If you work with Ruby you got literally a skull active record and then you have that eye mapper pattern or AMS such as doctrine, ORM and PHB.
And then and C sharp.net you have entity framework. And then in Java you have the hibernate or the Java persistence API. So let's look at a, a vulnerability pattern on the when you're working with a Deadeye mapper ORM. So this is an example of Java code on no where you couldn't be making a vulnerable HQL stray. You select us, you select an entity where the ride's destinations ID equals and then, and then boom, you append, you append a string to the string, right? Right us inition ID you actually upending what should be an integer to a string. But if you're not careful, this ride destination ID could also be a string which could modify your SQL query in such a way that once it gets translated to SQL by your RM, then you've got an injection relevantly in there, right? So the good news is if you're working with a new RM, you should be doing whether the RM wants you to do, which is again, use parameter binding, which is very similar where you go, colon destination and then you can bind the destination object to the query and both. So if you work with Microsoft and say framework, I have a link to security considerations that you should keep in mind.
So if you're working with active record or ms such as an O'Quinn for example you want to be mindful of those raw methods. Here's an example here. Users equals user where raw and then, and then you passed kind of it's like a, a query fragment, right? It's like, so this is a string. You pass it a string and then inside of that string, again, you're going to inject something that came from the request, right? This is kind of not how you, an RM is intended to be worked with, but they do give you some flexibility to do raw queries and if you abuse those, then you can open yourself up to vulnerabilities. So what's what you should be doing in this case is instead of using their raw method to do this, you can achieve the exact same thing by calling. There were method static method I guess where you plug the target age as a parameter and that will make you no, no longer vulnerable to injection. Gotcha.
You should check out this website to kind of audit your work. I have a link to another article about what happens when you heck no G, no JS and Mongo DB. So the, the mitigation pattern. So first let's look at the role of vulnerability patterns. So hold on, let me just kind of go back here. This, you may have a quick draw script query that may look like this. And then instead of that query, you want to plug something that came from the request user input. So instead of zero you do less than some something that came from a re a request. If you're not careful, this user input vulnerable could actually turn into something like this. This is something that will basically cause a hundred percent CPU usage. So you're basically doing a denial of service to your to your database, to your data store, like your Mongo DB will crash if you're not very careful.
So yeah, I do. So I have a link on how to prevent that at this article. But really what they tell you to do is to cast arguments to strings and they kind of give an example of using string user name, string password. But please don't be [inaudible] querying directly for passwords. We're going to look at how we should handle passwords, but this is the example that they gave. So yeah, don't store the password in and ClearTax and don't query for that directly. All right. So now let's look at cross site scripting. So lots of things can happen through XSS. You can steal credentials, do unauthorized operations, leak data, do session hijacking. It's all bad. So the vector of attack is pretty simple. First this what's called a reflected attack where let's say, you know, you, you run a search site, let's say you're running google.com, right?
That's the most critical part. So for right now, we're going to focus on rendering if GML for whether it's an HTML page or if it's just Jason output for example. Whenever you render things that came from the server that may have come from the database, for example, you always need to make sure that the medium on which you're doing the rendering is protecting itself from cross site scripting. So here I have a prevention cheat sheet, a link to this, so you can just kind of read this. But here's the TLDR.
All right? So you'd never want to put untrusted data and script blocks a, an HTML comment, an HTML attribute name, because there's no, or even an issue mail tag name. You would not do any of this unless you're building something like an HTML page builder, for example. Right? If you're building yeah you will not do any of those things unless you're, you're, you're doing something like that. So it's unlikely to happen, but just know that you really should not put untrusted that are in there because there is no safe way to escape this data. CSS blocks as well. There are no escaping or in camp, our encoding mechanism that is reliable. Mmm. Now, if you are exposing a you know, Jason output. Now let's say you're, you know, you have a restful API and it exposes Jason. I'll put a common oversight is the content type that you set being text slash HTML because your server is kind of configured to do that by default.
And then your API is not overriding this header to what it should be, which should be like a, I don't text slash a J song or something like that. Mmm. So, so then what happens is if you are viewing this instead of your web browser, your web browser is actually going to renders it. It's as, as HTML. And so if there is a script tag in there and then the script is going to execute. So you want to make sure that you set us there. You go, that's applications I chased on. Do you want to make sure that you set the proper content type header if it is a J som output and make sure that your content type header says applications slash Jason [inaudible].
All right, so now let's look at saving data, right? Should you escape data whenever you are saving it to your data store, for example my recommendation is not escape, but instead to strip things that you don't need. Because if you, it's scape data, if you encode that out, when you save it to your data store, when you render it, because you always want to escape that. When you render it, you run the risk of doing double escaping. So you're going to see, you know, when the page renders instead of seeing ampersand, you know, users are going to see an percent amp semi-colon, which is not great, right? So okay, I would avoid Mmm. Escaping or encoding data when saving it. And I would instead focus on stripping things. If if you don't need, if you don't allow users to put HTML code in their forum post and then strip all HTML tags if it does not need to be there, then just remove it.
Right? and then also you get, you know, you should enforce proper data types in your, in your database schema. Not everything used to be a string, not everything needs to be a VAR char basically. Right? So if something is a number, make sure that you are storing it as a number, not a strength. You know, let's take a use case of, you know, you're, you're building a, a content management system where you allow people to set the font size for the size of the font store the units like PX as a separate look up table and then store 10 as an integer, right? Avoid storing things I strengths that came, that come in from the user requests. Try to normalize your data schema so that you avoid using strengths, strengths, AKA VAR, chars. So and like mentioned earlier, you want to, you want the escaping or encoding to really happen in rendering, not when saving data.
So [inaudible] to avoid double encoding. All right, let's look at cross site request forgery. So this one is pretty fun. [inaudible] The biggest impact is unauthorized operations. Imagine that you visit my webpage, imagine that I am evil and you visit my webpage and then the next day you look at your Amazon shopping cart and there's an item in there that you did not put in there, but I put that in there for you, right? Cross-Site request forgery allows you to do things like that. So, and the vector is kind of UNPRI protected transactional operations. Let's look at what it means on, let's take a, a pretty simple example. So you have 'em a victim, the victim website where they have you know, I don't know if any of you remember when soulful bookmarks were popular. These were applications where you could bookmark things.
And then you could share your list of bookmarks with other people, right? And so your social bookmark application may have a form a with a post post action that posts a new bookmark to an endpoint called bookmark, slash, ad. And it's got two simple parameters. The, the title of the bookmark in the URL, and then a simple submit button that says save. Bookmark. Okay. So this is, this is your website that you've built. This is your web application that you have built and it works. Your users can log in and they can save their own bookmarks, right? But now let's say that, Mmm, I am evil and I am an attacker site. And for some odd reason, I want to pollute your bookmarks with my own bookmarks, right? So what I can do if I really want to I can replicate your form.
I can replicate your form verbatim on my website with the same action, except that I, you know, put your, your full web host in there. And then I'm cool, I'm going to put the title and the URL as hidden parameters. So this form doesn't even show up when the user visits my site. They don't even know that it's there. But then I'm going to invoke a piece of Josh skit that is going to submit the form automatically as soon as the page loads, right? And it's going to and it's gonna set my website as the, as a bookmark, right? So I'm adding myself as a bookmark. This is me trolling the world, right?
So that's kind of what you can do with CSRF. Obviously, like I said, you can do things more evil things on more interesting transactional websites. You know, let's say a bank account. Right? I would love for you for to be able to just add 10 bucks to my bank account whenever you visit my site, you know, from your bank account. So there is a very simple mitigation to for this, it's to use a CSRF token. And I recommend use leveraging your MEC framework to build a form because when you build a Ishmael form using Laravel or using symphony they automatically take care of injecting a CSRF token in the form for you. But what does that look like? It's it's pretty simple. It kind of looks like this. So on your site, on your own web application, you're gonna add a hidden input parameter.
That is a non guessable token, right? And so when this form gets submitted in whatever business logic that happens in ad right here you're gonna check for the presence of this token and make sure that the value of this token is a value that you expect. So what you could do is kind of set this token kind of a, as a session value, right? You could do it on a per page load as well. But kind of a convenient way to do it is whenever a new session starts you could create a new token and that's part of the session. So whenever any form is submitted you check for that token to be present. But again, if you're working with a, a, an MVC framework like symphony or Laravel, they tend to take care of that for you as long as you use their constructs to build or the forms. So now the attacker site is not going to be able to guess what your token is so they can post all day to add. Your business logic is going to be like, sorry, that token is not present. So I'm literally going to ignore what you're doing to me. Boom. That was for CSRF.
Okay. So here's the documentation for CSRF protection on symphony, and here's the documentation for Laravel. So please be sure to read that and to follow the recommendations of your frameworks. All right. So yeah, it gets fun. When I'm, for a while there were a number of a home routers that you could compromise through CSRF vulnerabilities. I'm not going to go into that. Yeah, when they have found a vulnerability in Safaria, you've not got to get into that. But anyway, [inaudible] that was CSRs. Now let's look at higher level application vulnerabilities.
So we're going to look at three things. We're going to look at user authenticity, authentication off security as well as access control and multitenancy. So let's look at user authentication. So again, Oh, wasp has a cheat sheet on that, so I highly recommend reading it, but I'm going to cover a number of topics myself right here. We're going to look at failure messaging, failure handling, multifactor authentication, account recovery, password policies, password hashing, password transport, session duration and re authentication. And then what happens when there's a compromise, right? Yeah. So we're going to look at all these topics pretty quickly. So let's look at failure messaging first. What you want to do is to not give too much intelligence as to the existence of an account, right? So you want to keep all air messaging to be generic and vague for all failure modes.
What you don't want to say is things like wrong password. It's like, Hey, the user ID that you entered is actually correct, but the password is not quite right. You'll try again. So at least now they're hacker knows that they have a correct user ID, right? So it reduces the amount of things that they have to try. So don't even tell them that the user ID is correct. Just tell them, Hey, you have a wrong user ID, password combination. So same thing. What you don't want to say, Hey the password is correct, but the user ID is wrong. Right? so I don't want to stay account is disabled if you can. You know, if you can avoid saying it you don't want to say this user exists, but it's just not active. So again, you want to keep it generic and vague, such as login, failed, invalid user ID or password.
Right? It's, it's vague. A hacker doesn't know exactly what to do there. They have to keep trying different user ID and password combinations. Mmm. All right, so now let's look at failure handling. What happens? What do you do when somebody entered a password and it's wrong? So one of the things you want to be mindful of is to mitigate brute force login attempts. And to be fair, there aren't many elegant ways to do that. Aside from using a really good hashing framework, which we're going to look at later on you know, you might consider limiting failures by IP address. So if there are more than 10 failures for a given the IP you know, then just kind of normal gear accept requests for that IP, you know, for a period of 30 minutes, for example, it just kind of, you know, put them in a, a bad corner for 10 minutes.
You can do that. But you know, it can be bad if a lot of your customers have a lot of users on the same network, right? All it takes is like one user to have I'm wrong, username and password for more than N times, and then suddenly nobody in that office can log into your application. So that could be bad, right? So you've got gotta be mindful of that. Some sites will put captcha on on there login form, but that's a really good way to anchor your user. So I don't recommend it. Mmm. But some sites don't do that, so Mmm. And you definitely want to try to log all failures. You want to lock whatever the attempted user ID was, where the timestamp was and the IP address. And you might even consider logging and successes with those same fields in the sense that some accounts could get compromised.
So you want to try and lock things. All right, so now let's look at multifactor authentication. So here's the link. We could be yet for that. So multi-factor, you know, it's kind of when you log into a site and then they send you an SMS message with a code to verify that you are who you are. So that works really well. A lot of sites do that. Ring central allows you to do that, right, Mike? But the, the thing though is you know, some phones do get stolen or lost, right? So it's, it's not foolproof, but it's, it's, it's a pretty popular way to do multi-factor. Also carrier account sometimes get hijacked. I have an article to SIM cloning. So the thing I recommend is if you're sending an SMS verification, try to not put the name of your website in the SMS message because if the phone gets, if a user's phone gets stolen you don't want to give the thief too much intelligence as to what sites the person has been interacting and interacting with.
So they might get a bright idea of to try to compromise those sites, right? So if you can avoid it, I definitely recommend not disclosing your site in the SMS verification message. Okay. So now that's like an account recovery. So here I have a link to [inaudible]. What do you do for somebody who's a forgotten their password? Here I have a, also a link to an article that talks about security questions and the gist of it is that it's a big mess. Secure security questions are a bit of a security nightmare in and of themselves. A lot of application store them, store the security responses in clear text which is a security problem in and out of itself. So a better approach is to send an email with a onetime reset token. That's kind of what we do for account recovery these days.
And that works pretty well of course. Unless the email gets a hijack. So when it comes to recovery lengths, that gets sent into emails. What I recommend, what, what you'll do is you'll send a user a link with a token in the URL that gives them kind of a, a temporary session. So should I, they can update their password. That token, you should avoid to let it linger in the URL. You want to try to redirect away from it because it's possible that when you give the web page to the end user that offers them to reset their password. It's possible that you may have, you know, links in your footer that links to some other website. And if somebody clicks on one of those other websites the URL is going to show up in the issue, EDP refer header.
So they're going to ha, they're going to see what your token is. So try to not let that token linger in the URL and just kind of redirect you know, do a written direction because you know, you can just store that token in the session and then try to expire the token quickly, like within 24 hours. But also do remember that email accounts do get compromised. So yeah, like I said you know, nothing's perfect. And then another way to do it besides email, I used to do a onetime recovery code over S a SMS or some other site channel. But again, phones do get stolons and Sims get clone. So just keep that in mind, right? So that was for account recovery. So now, Oh yeah, and I forgot to mention and validate all existent sessions upon recovery. So once a user completes the recovery process, make sure that if there are any sessions in the wild that you just expire them right away.
All right, so now let's look at password policies. So there are lists of known passwords. As many web applications get compromised and passwords get discovered, a lot of folks are capturing lists of what those passwords are because you know what? They're in the wild, so you might as well know about them and avoid, you know, and prevent people from using those. So I have links to small lists and big lists by Daniel Missler. And another best practice is to forbid the user from using one of their last five passwords. The password length should be 10 characters or more of these days and the password should not continue to use her name. And the password must be made of at least three, or of the four available character types which could be lowercase, uppercase numbers or symbols. So try to make sure that users and a password that fits that contains at least three of those four.
You might also consider making users change our passwords every three months. You know, but that's kind of where when you have to wake convenience versus you know, security, right? So it's definitely something worth considering. All right, now let's look at password hashing password hash Jane could be its own talk. But the point of password hashing is that you never store a user's password in clear texts in your system. You never know what the user's password is. Yeah, okay. Outside of the, you know, incoming, it should be required, but basically once it's stored in your system, you hash it before you hash it, before storing it in your system, it one you and what you store is this hash value. And from this hash value, you can tell what the password is and somebody who steals your database can look at this hash value and have no way to guess why that password is.
So there had been a lot of hashing algorithms over the years. I don't use one pass hashing algorithms you know, don't use, you know, Shaoguan MD five shot to shout, two 56 shot five, 12. They are a one pass algorithms. What you want to try and do is to use an industry standard hashing framework, which will do more than one pass it. We'll do several thousand passes which add latency in the process which make it near impossible to brute force guest's passwords. So the features of a good hashing framework are having multipass which we'll put load which will put load on the CPU and load on the memory. And they will also create a unique salt that will be part of the hash.
So for a long time B crypt has been an industry standard. But some researchers found it to be pretty vulnerable to GPU based brute force. Especially with the advent of Bitcoin, people have been super creative and using GPU [inaudible] to do brute force calculations. And this type of architecture can be reused to crack passwords to passwords at a very high rate. So the nice thing though is that argon too is a thing since 2015 it won the password hashing competition and are gong to put sufficient load on CPU N N memory that it makes even GPU based brute force attacks to be impractical. So I have an article here by David Woodlock that just kind of compares are going to, to older algorithms. So are gong to, is supported in PHP [inaudible]. It was introduced in PHB I think 7.0. It's definitely as a PHP seven, but I think it's PHP 7.2 that w that it was introduced. So the hash password function and PHB supports arc. I'll do.
Okay. So he, if you work with a mean stack, I have a link on how to do proper hashing here with with a mean stack. All right, so now let's look at password transport, right? When, when the user enters the password in the web form that gets transfer it to your application. So you want to try, you definitely want to use TLS. So you know, it used to be called SSL, then it evolves to TLS, right? So now you can get a TLI certificate for free from let's encrypt.org. So it's a, it's very easy to get. So you should, you should try to use TLS for everything, but definitely for login and registration and re and recovery, right? Anytime a password may transit or sensitive information to make transit to your web application web application, you want to make sure that your, your, your, that you are using KLS.
Now the thing about TLS is that every once in a while there are some vulnerabilities. I don't know if any of you remember things like you know, Heartbleed in some other open SSL vulnerabilities. You know, there are, there are times where, you know, TLS fails us. So that's when I started looking at kind of doing encryption, kind of public private encryption on the client. So there's, I have a link to a JS encrypt here, which would allow to use a public key a public key to encrypt client-side a user's password. And then you can use a private key on the server to decrypt a password and then hash it and store it. You would still use TLS to transfer the password the encrypted password, but you're also encrypting the password yourself, so, Mmm.