In this video you will learn to describe additional OS command injection attacks, explain why it is safer to use some functions over others, explain why it is safer to modify user input before execution, explain why it is safer to sanitize user input using whitelists and not blacklists. Next recommendation is to use proper functionality when running OS system commands. So we started with not running OS commands at all and we are going down the line now assuming that you have a real business need to run an OS commands and we are trying to tell you how to better write your code and execute those. If you still have to execute those commands, but execute them correctly. So in Java for example, there are different ways of running an OS command. One way that's very common is to just build a full string of your executable and the parameters and execute things like that. With that, injection is more likely than with another type of function, the one that takes a string array. The reason for that is that the second variant already gives the operating system the command and the parameters pre-passed as individual strings. So attacker has control of, in this case, IP address parameter and tries to jam more stuff into it, go from one parameter into many. With a second variant of the function call, they won't be able to do that. They will not succeed but with the first variant they might. So when you run OS commands, please evaluate what's available and use the safest functionality that's available. The next recommendation is if possible do not let user Input reach the place where you execute the command unchanged. What I mean by that is, you could deal with different entities that the OS command will be operating on in the UI as symbolic IDs. So instead of letting users specify a particular file to do it, you could have a numeric ID that corresponds to that file and when the parameters come in, that ID is passed in. Inside your code you could use a translation table to convert that number to real filename and then delete the file. This is much safer because now attacker cannot really specify anything malicious as that parameter value. If they specify something that does not exist in that internal mapping table, then we can just reject that request with an error. They won't be able to sneak any operating system commands or any malicious parameter in because that parameter will not be recognized. It's another good recommendation for them. Sanitization. That's going to be universal advice that we give. The users communicate with your application through parameters most often. So carefully sanitizing them with strict whitelists and not blacklists. If you saw our previous talk, we talked about the importance of whitelists. I'll quickly mention that, with blacklists, we mean a list of input that's known to be dangerous and in your logic you may look at it and see well, that's the parameter that was passed in. Does it match any of the bad stuff on this list. If it doesn't, let it through. The problem with that is, it's incredibly hard to build a successful blacklist and I'll give some examples shortly. Attackers are usually very inventive and there's a link in the slides. If you click on it, there are lots of examples there of what at first seems like a good blacklist can be easily bypassed by an inventive attacker. So instead of using blacklists, please use whitelists. By whitelists, we mean a very tight, very controlled list of what's allowed and all other inputs should be rejected. That way you're dealing with a known entity that's fairly small. You can analyze it and you can really come up with all the use cases that the user could specify and see if there are dangers or not. So just some examples here. These are actually real life examples that we saw in the applications that we tested. So let's say we have, in our application code, a blacklist of, we reject things that contain semi-colons, ampersands, and pipes. The attacker could still sneak in internal OS command that's surrounded by backticks. That's a valid Linux syntax. Let's say you add backticks to the blacklist. There's another syntax with the dollar sign. You could blacklists spaces. Let's say my file name should not contain any spaces because that's an indication of something malicious going on. There is a way in the operating system commands syntax to replace spaces with a value from a known system variable that contains a space. So with tuition here acts as your space. So they could still sneak something in. You could say that well, I'll enclose the value in double quotes and then also escape double-quotes in the value. That should be secure. Unfortunately, there's a way around it as well. It's a bit of more complicated example, but if you look closely, it's this last line in the table. The red input is what the attacker would send. They would actually send in the double quote already escaped with a backslash. Because your application would escape the double quote anyway, the single backslash turns into double backslash, that's one real backslash and the double quote goes unescaped and that allows the attacker to chain an additional set of commands. As you can see, attackers can get really, really creative and you usually don't have time and cycles to think about all these very complicated cases. So it's best to use a whitelist and the regular expression whitelist at the bottom would have taken care of all of these cases easily. You just accept filenames that are alphanumeric. There's a possible dot in there and that's it. So none of those cases would work if you were to use this whitelist. So what are the key takeaways? Try not to use OS commands. There are much safer ways of executing functionality that's usually done in the context of OS command. So only use OS commands if absolutely necessary, if it's dictated by your business logic. Try to run your code with least possible privilege. Do not run OS commands with shell interpreters. Try to run them directly. Use explicit paths when running applications and shared libraries. Try to use safe library functionality, there're usually multiple variants or some safer than the others. Try not to let user input reach the point where OS command is executed unchanged. It's better to try and use generated IDs and try to sanitize all user input with whitelists.