Hey there. Welcome back. In our previous few lessons, we focused on reflected cross-site scripting attacks. Hopefully, you had fun playing with the cross-site scripting activities and resources. In this lesson, we're going to specifically focus on stored cross-site scripting attacks. After this lesson, you will be able to distinguish between reflected and stored cross-site scripting attacks then try patching the vulnerability. First let's compare these two types. The payloads are relatively the same. So I don't want you to get distracted by that. In the reflected attack the page is being built once, sent to the user, and the attacker executes on the user's browser. In the stored cross-site scripting attack, the same payload is stored on the database or some sort of memory on the back-end server and then being served to the user as they go and visit the page. Let me show you what I mean. So let's play around with it. So this is just like a regular comment box. So we can comment here. I love ramen. We can even add to it some scripts of our own, document.cookies. If we submit that, obviously the cookies didn't come up, but we can see that the alert just popped up and you can also see that our script alert is not showing here. So let's go about fixing it. We should be able to employ some of the same methods that we did on the last one with a reflected cross-site scripting. So this org owasp encoder should work for us. So let's see what we can do here. I'm assuming the code is calling this create new comment for us, and it's parsing a Json string and the Json string is being saved as a comment. So let's look at what that parse Json string is doing. It looks like it's just doing an object mapper. So simply reflecting values into a particular object, and then it tries to map that to a comment class using the read value. So it's like an object mapper class that just maps those things to a common class, and our common class is a user, a date time and a text. Okay. So if you're new to Java or this doesn't make perfect sense to you, let's break it apart little by little. But essentially what it's doing is it's taking that Json body and its mapping it to an object that we have a type four. So let's do it little by little just so we can see what's going on. So I'm just going to do a basic system out print line. So I'm just going to print what we're getting at here, which is the comment string. So this is before we turn it into a comment and, I don't know if it's going to print anything but let's try it. I'm just going to print our comment object. So I'm going to recompile that. All right. So if I go to here and I just put in a simple comment and submit that, what we'll see in our print line is a Json object that has a text that is simple comments. So essentially, our text is being put inside this comment object. Alright. So, if we're going to defend against this cross-site scripting, we need to make sure that the text that's coming out of this and going into our comment is actually being escaped. Now, you'll also notice that my second print which was printing the comment doesn't actually have a print that makes sense to us, it's just bringing the object of the hash for it. So we're going to modify the common class a little bit to make this a little bit easier for us. So we're going to override the two string method for this and we're going to maybe return something like string.format user equals percent s, and a new line date time equals percent s, and a new line and then maybe text equals percent s, and let's make this the same case as the original, and let's append user date time and text to this. I'm going to recompile that and see what we see next. The only reason I'm doing this two-string method in here in this class is because I want to see what my comment looks like after it's been created to see if it give me some intuition of how this codes are working. All right. Let's give it a try. Simple comment. So let's see. User is null. Date time is null, and our text just simply got placed in that simple comment. Okay. That's a good start. So the question now becomes how do we go about modifying this command Str to not have the payload in it. Let's see if we do a final string clean comment. So we can't do encode.ForHtml here. So this won't work because it's going to encode this entire thing and really all we're trying to encode is this comment line here. So this next part isn't exactly security-related, but it does present a an actual view of how doing coding in real life could have security implications because simply patching this isn't as easy as the one-liner that we had in the previous slide. So you're going to have to play around to make sure that this works. So my thought process is, let's go ahead and we know we're getting a map that is at the string in a string; that's what a JSON object is. Or actually maybe we're not sure if the second part is an object on Zone, and we're going to map this comment out. So I'm familiar with the Jackson JsonParser. Now if you don't have that, we can add it as a Maven. There it is, I just misspelled that the first-time; JacksonJsonParser, and we're going to parse the map, that is our comment string. So what I expect here now, is an actual map that I can play with. Oops forgot an equal sign there. Is a map that I can actually play with. Let me minimize this just so we have the full screen, and I guess let's extract the textComment equals. So from my comment map, I should be able to get a string out. So let's pull out the string value of the comment in our map, and we know that they're calling it texts, so we're just going to pull it out by name and let's clean that up. So I guess that's where we can clean it up now, and now we can just take our text comment and clean it up. So essentially what we've done so far, is we've created a Java object that we can simply get things out of, and we took the text out and now we have a clean comment. You could go about rewriting a bunch of stuff to redo how this all works, but working within the confines of our code and how the code wants to work, we're just going to put it back in the same structure. So essentially we're going to recreate this and give it back to the rest of the code, so we can leave the rest of it unmodified essentially. So that comment map that I created, we're just going to put into it with the same key. So we're going to use the same key of texts, and we're going to put in it the clean comment. We want to maybe put that back to shrinks, and since the parsed JSON expects a string from us, we can maybe replace a common strain, which was what came into the code, using an object mapper. This is similar logic to what they were doing down below. We're just doing it in the inverse essentially. Then they can take that common string, and make a new comment out of it. I'm going to leave my print line in here, maybe leave a comment for myself to remove this, and then we want to also maybe remove this. So technically there's a bunch wrong with this code. It'll compile and it will work, but for instance this mapping may fail, so we might want to catch those exceptions. This Comment could have a potentially to fail if the common map doesn't have a text. So we also want to be careful about how we're going about doing this, because it has the potential to fail if that key doesn't exist. This HTML looks like it doesn't have any failure, so that's good. We know failure is expected there. Putting back into this, could fail, let's see if there's any exceptions that are thrown. Yeah, it does throw a bunch of different exceptions. So we got to be careful with those. Then there's a lot that can go wrong here; this right value of string could throw exceptions. So we want to be careful when we're doing this. Now this module focuses on cross-site scripting and that input validation. So I'm not going to confuse the code by adding a bunch of extra exception handling code in here, but we always want to be careful when we're writing code not to have exceptions. So I'm going to recompile that. It's not up yet. Took about 10 seconds if I refresh this, simple comment. So it looks like a simple common got through. Now if we simply do something like