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 alert, script
simply displays it for us rather
than embedding it in the code.
So our browser now knows how to
differentiate between this data that it received,
and it's not actually executing on it.
We can even see our scripts when in here,
and how it was being formatted,
and we can see how it was being
formatted after we started
doing the cleanup using our encoder method.
Now, this begins your cross-site scripting journey.
There's some really fun things you
could do with cross-site scripting.
I'm now going to cover it, but BeEF,
the Browser Exploitation Framework,
has some really cool utilities for playing around.
Essentially, it allows you to
navigate or have
another browser compromise through cross-site scripting,
and then you can start running
various different commands through it.
They have a bunch of different prebuilt commands,
you could prompt the user to download Adobe Flash.
There's some really cool things you can do with it,
and I recommend you if you have some time,
to go download it and play with it.
All right, I hope you guys enjoyed
this video and see you next time.