From the course: CertNexus Cyber Secure Coder (CSC-110) Cert Prep
Guidelines for secure coding
From the course: CertNexus Cyber Secure Coder (CSC-110) Cert Prep
Guidelines for secure coding
- In this episode of Cyber Secure Coder we're going to take a look at some common programming errors that could lead to security issues. It's up next on ITProTV - [Electronic Voice] ] You're watching ITProTV. - Greetings everyone and welcome back to ITProTV, today we're going to take a look at, well, common programming errors. As good as we like to think we are, and you probably really are, we all are prone to making mistakes. Justin, you're going to show us how we can avoid those and what they might be if we do make them, correct? - Well this is to bring those ideas to the forefront, now there are some things we've already talked about which are fairly common issues, right? 'Oh, I didn't sanitize user input,' but there are some other ones that start to crop up depending on the industry, what you're doing and we're going to make sure that you keep those in mind as well, and we'll do a little deeper dive in a few of those up for overflows, race conditions. Those get a little iffy because it's not a common... Nowadays, it's not as common 'cause I'm using dynamic languages that hide some of that away from me, or I have no reason to have concurrency. So with that said, just keep in mind do know repetition is important to... Just keep that in front of the mind. So with that said, lookout and take a look at the screen. Vulnerability is a lot of by and large are calls by us. As much as Daniel said, as much as we would like to think we are perfect, it's very hard to be perfect. We thought we were doing one thing, indirectly we were doing another. Oops, I'm using a dangerous function. XML, external entity expansion, oh, I'm allowing that function to do entity expansion which allows arbitrary code execution. Oh, well actually if I'd used this other function that wouldn't have happened. One that I've used, that I've built things in production, was using YAML, and in Python, it used to be, I think they've actually changed it now, YAML had a safe and an unsafe load, right? I'm reading it from disk. The unsafe load would do our arbitrary code execution whenever it's serialized or de-serialized the YAML. You go, well, that's bad, right? Now, that is the safe, like by default, it's safe. You have to opt in to not safe, if I'm not mistaken. Using deprecated libraries sometimes they force your hand on that. I've worked in some government institutions doing some contracting where this is the library you have to use. Yeah, but that has this issue where people can do the thing. They go, yeah but we've already vetted this. We know about that one. We can protect against that. We're all good. This is the one you have to use. Okay. The worst part is is some people do that without being told to. They go, ah I just had this old version laying around, it'll work good enough. No, you need to make sure that's not the case. And then a few of these like race conditions, energy range issues, out bounds, array, indexing, unhandled exceptions, those occur sometimes in the ecosystem. I'm I'm going to take out of bounds, array, indexing and see, you actually start. If you do out of bounds, you start reading like uninitialized memory and you just get garbage. Which is actually a way you can leverage that to go, oh if I put this here at this memory address then I can read code and hey look shenanigans. But in Python if I do that, it throws an exception. Actually in Python, if I use a common construct, I'll never have that. Because Python stops at the end of the array. As well as some uninitialized variables and like dangling and null pointers, dynamic languages, that's less of an issue. I'm not manually handling memory. CC++, some of those lower level languages, I'm doing all that manually. The trade off there is, well unfortunately I would like to think it's safe. Never assume things are safe. It could be that underneath Python, Ruby, any of those a lot of times they have C extensions or something implemented in C. Indirectly you may inherit those, but you're not the one doing them. I trade off some performance or power using Python, JavaScript, Ruby whatever it may be, by giving up that manual memory control. But by doing that, hopefully I inherit some safety. There's some newer languages on the block that help address this. I still want performance. I want that manual memory handling because I know it's very performant for my application. Rust comes to mind, go comes to mind, where their goal is to help you write better code. Right? They have very opinionated views. Rust has something called the borrow checker which does not, it will not compile, unless there's an error in the compiler if it has a dangling pointer. If you have a dangling pointer, it goes, no, you cannot. You can't even compile it much less ship it. So that's good. And then configuration. Configuration, I want to do the simplest configuration possible but sometimes you can opt into configuration that helps you be more secure. Like, Hey, I know in JavaScript use strict. It keeps you from using parts of the language like exec or eval that may lead to injection attacks. It goes, Hey, don't do that. Or there's this com this very little known width keyword, that allows you to do some like crazy stuff. It's considered bad practice because it leads to some security issues. In addition to a lot of compiled languages you can say, Hey, I need you to strictly check these, that configuration helps you protect against those. Do keep in mind these aren't always enabled by default some newer languages Rust. I like Rust. I enjoy it. Haven't used it a great deal professionally, but it's fun. It is strict by default. Haskell some of those very strict type driven languages are strict by default. So you keep that in mind. Other ones like JavaScript, you have to have tools that will enforce those and you have to turn those on or opt into those. Or you use something like type script that compiles the JavaScript to get some of that strictness. Right? Now, just a quick rundown of some things you should think about as you're designing, implementing, deploying, maintaining. How many things more complex than they need to be? What that, what happens there is I don't know what happens when I come back to it a month later and I'm not immune to this. I do it. Ah, this is complicated. This is why I actually like doing little programming puzzles and things and having other people look at them. They'll go, yeah, that works except, if you do this one thing it ends up being three lines long. That's way easier to maintain and to find errors in than that 15 lines of stuff that you did. So as simple as possible, write code to be read by someone else, right? That kind of follows into that. Daniel and I, some other people in the office we periodically have to, you know, write scripts or maybe even we're doing all those puzzles having it being readable by another person. Number one helps you. Number two, it helps you find errors. It helps you communicate with that person but also find errors. And then it's great if maybe you leave your job, or goodness forbid, you get hurt something happens. You have a family emergency and someone else has to take it over, they can read it. Testing. Making sure your automated common task and also doing your views of third party applications; codes, library API's that you are using. This is a throwback to another episode where I talked about I've used some JavaScript libraries that have aa RegEx denial service built in. I have to know about that. I need to do some research. Hey, is there a version that that's not the case was that introduced recently, is that fixable by us? Is there an update that does fix that? Keep that in mind. And then some languages enforce this more strictly than others. If you bring all of your variables to the top instead of defining them in line and you enforce that code style, then you go, oh here are all the things I'm going to need to know about in this program, or in this function or in this method, whatever it may be. That's helpful. I'll admit I don't always do that because there's sometimes throwaway variables that I just need in a very limited scope. And I don't need to have people thinking about them cognitively. So keep that in mind. Sanitize user input, dynamic languages are, are really bad about this, but if you're dynamically doing sequel queries any type of database access, any type of file access. Shelling out, which sometimes I've done, sometimes I feel compelled to do. You don't want to necessarily shell out, but if you do, maybe you shouldn't pass un-sanitized data or un-sanitized input to that shelling out because, oh look net cats are running and here's a shell. Or, Hey, I just did some bad things like deleted your hard drive. Whoops! So there you go. Don't ignore warnings. Don't enable your code to issue direct commands as we just said. And really these three bullet points are summed up of, don't trust users. You're like, we've heard that so many times, Justin. I mean, I bet some of you're going if I could roll my eyes at you, I would. But it happens and it's hard to check. It's hard to make sure, even though I teach it, I got hit with a, Hey, you didn't sanitize user data right here. Oh yeah, I didn't. I had it everywhere else but I missed one place. and all it takes is that one place for someone to go, 'Hey look I have a stored cross site scripting attack that now I can use to send over to a, I gathered all these people's credentials. I'm in your infrastructure, look.' So this takes one. It's helpful to just find one and fix it. Instead of going, 'Hey, you haven't validated a user input anywhere in the entire application.' Well, that's not bad. How big is that application? 14 million lines long. That's an exaggeration, but that would be horrible. And then there's some other things that we should think about that end up being edge cases, race conditions or shared memory. Or like shared calculations, shared resources. When you start to scale using like threading, external processes, anything like that, if you're not careful about how you program then you go, oh, well let me write this to disc. Oh, I need to read that, that's how I verified that person. But if someone can get in, they can switch that out from under you. And you read and you go, oh, that's good. Also it's a great place to do a denial service 'cause I can just start making threads, try to access the same resource, everything locks up, shenanigans. So be very, very careful there that has to do with the language you pick and also agreeing upon appropriate procedures. Is it going to be foolproof? No, but for instance, Go concurrency is, is number one Go has a built in tool that will check for deadlocks and race conditions. You can go and it'll start doing all kinds of, essentially fuzzes your application before a compilation. And it'll go, oh, well here, this is a deadlock, you should go fix that. So that's helpful. Lean on your tools. Also agree upon how those things work. And then always check the integrity. Make sure that it's coming from where you think it is, that hasn't been tampered within transit. That's user input but also if you're deploying an application we had to deliver applications to an external facility, and just by the way of it, we had to deliver a physical disc. So we would have check sums with it and say, here's the physical disc, here's a check sum. Just in case a bad actor was like, well let me move this around. I got access to the original application injected my own little back door. It's all good. Make sure signature lines up, check some lines up. And that's more of a physical security thing but you can do that in transit. Like if I'm dynamically downloading code, web applications are really good about this. I can do check sum checks and say, 'Hey this doesn't line up,' stop, don't do this. That way your GPO doesn't wind up and you start mining Monera or whatever it may be. So use those, they're actually not that difficult. It's just not something that when I first started I thought of very much, I was like, what, what is that? But it's great to be able to check integrity either during application use or when you're delivering, moving. And it may not even be malicious in nature, it just could be, Hey, there was a weird transmission glitch and now there's this like bid off that causes an error. And if an error can occur and you haven't handled it or prepared for it, then somebody may be able to exploit that, the circumvent controls that you've put in place otherwise. So keep those in mind and we'll dive a little bit deeper into a few of these. We haven't talked as much about to get you ready to go. All right. I feel good about making secure software with complete recognition that I'm probably not going to do it on the first try. Someone's going to find something bad and I'm going to have to fix it, but it's okay. Just tape them to your wall, you'd be good to go. - All right. Well Justin, thanks so much for showing us the stumbling stones that could set in our way and they're so easily overlooked or are passed over thinking, oh, it's not that bad, or I'll come back and fix it later. We need to keep these things in mind as we continue to develop our applications. Great job from Justin here, showing us how we can account for those and even look for them, get them out of there before we ship it. Right? And being said, thanks Justin for joining us. And thank you for watching, signing off for ITProTV. I've been your host, Daniel Lowrie - And I'm Justin Dennison. - See you next time. - [Electronic Voice] Thank you for watching ITPRoTV.
Contents
-
-
-
-
-
-
Guidelines for secure coding14m 16s
-
(Locked)
Buffer overflows and prevention13m 8s
-
(Locked)
Race conditions10m 9s
-
(Locked)
Challenge: Use locks to remediate race condition5m 54s
-
(Locked)
Solution: Use locks to remediate race condition8m 52s
-
(Locked)
OWASP top ten platform vulnerabilities10m 28s
-
(Locked)
Web application vulnerabilities deep dive16m 50s
-
(Locked)
Mobile application vulnerabilities deep dive16m 17s
-
(Locked)
IoT vulnerabilities deep dive19m
-
(Locked)
Desktop vulnerabilities deep dive13m 37s
-
(Locked)
Privacy vulnerability defects20m 41s
-
-
-