Hey welcome back.
We left off at the end of the previous lesson
with a challenge for you to try to find
the various points in the code that required to make
modifications to protect against the XML injection.
In this lesson, I will show you
the process I use to do that.
After this lesson, you should be able
to navigate a large code base to find
critical segments of the code and patch
vulnerabilities within the confines
of the code. Let's get to it.
So I was able to track it down to two entry points.
The very first entry point for lesson
3 is the simple XXE.Java class,
and the second one for the second lesson or for
which tests the rest framework
is the Content-Type assignment,
both of which call the parse XML method inside
the comments class and that's where we can
employ our modifications to
the code, at least some of them.
There's more defense in depth that we can employ.
So the very first part is this.
So if we go to the recommendation page,
it talks about XML,
factory, support for DTD
to be turned off if you don't need it.
The use cases for both three and
four certainly show us that we don't need it.
So we're going to turn off support for that.
I'm going to move this one up.
Now, the question becomes,
do we support external entities
or do we support validating?
I mean, without DTD,
there is no external entity,
so technically we don't need this two lines of code.
Obviously, we can always reference
our handy OWASP cheat sheet
for these types of information.
Now, we went ahead and disabled DTD.
However, there may be
times that you are not able to completely disable it.
From there, you have to specifically configure
your XML input factory to only
parse the types of documents and
the types of header information and
entities that you want it to parse.
You could give a detailed with it.
You could enable and disable certain types of
features and make it very custom to your use case.
But the idea behind this is,
you want the parser to have
the least amount of features
enabled in order to work for you.
So we'll go ahead and leave those off.
If you're not sure exactly what these do,
you can look into the documentation for it.
So in my IDE,
I can just simply click the properties,
turn off and implementing specific validation.
Since we're not doing any specific validation,
I'm just going to remove that line of code.
Support external entities.
The property is required for
the parsers to resolve external parse entities.
But since we have DTDs disabled,
we don't need that feature turned off.
So I'll go ahead and comment out these two.
We'll go ahead and recompile.
Close that extra page.
I'm going to reset their lesson plan
here after this loads.
Refresh and reset the lesson plan.
So the idea here is I'm going to send
a test just to get it in my bird proxy.
Go to my proxy,
find the most recent post,
send it to our repeater and inside the repeater,
I can just borrow the code that I have already
written to do this
for me and just see even see if this works.
Here it go and we get back a some failed.
But sorry this solution is not correct. Please try again.
Now, we know this used to work.
There's also another one we want to try which was
the dot dot slash dot dot
slash dot dot slash dot dot slash.
We'll see if that one works. Same issue.
Now, if we go back to
the web page and refresh the output,
nothing was committed to this.
We know this used to work,
so clearly we've disabled this wrapped.
Now, the second question asks
us if we can do it through rest.
So I'm going to do a rest test.
Go back to our proxy,
grab the most recent post,
send it to the repeater.
This is the one that we were able
to change to XML before,
and we were able to submit this text.In fact,
we can go back to
the previous versions we ran which are up here,
so like number 2 which worked or number 1 and copy those.
Obviously, this is the same one that
we tried before and it worked.
So application XML without payload,
send that through and again the XML parser fails
to parse that because entities are disabled.
Now, clearly these are getting called because I have
my print lines in the right place.
So this is not working.
But we can actually add another layer of protection
against our second instance because it's
only supposed to accept JSON data types.
So if we go to the content-type assignment and
the create user call which is
what's getting called under call 2,
is actually has a request mapping.
This is a spring thing.
The framework provides these types
of annotations that says,
accepts methods of typos,
it consumes media ball type,
it produces media of the JSON value type.
So we want to a strictly say,
we also want to only
consume application JSON value types.
So if you actually start typing,
you'll see the different options available.
We're going to use a JSON type.
I'm going to recompile this.
The idea here is we're not going to rely on
the implementations of our parser to protect us here.
We could actually have our framework not even
pass the data to the parser to
begin with if it's not presented to us in
the shape or in the type that we expect.
So going back to our browser,
I'm going to refresh just to get
a new session in case that one died.
Module 4 or section 4 of this,
I'm going to do another rest test.
Going back to our proxy,
grabbing the last post,
sending it to our trusty repeater.
I'm going to change this to XML,
and borrow the same payload that we used the last few
times and send it.
Now, you notice we actually got
a very different error message.
Previously, we were getting errors that
look like this and what they're
showing is that XML parser wasn't able to
parse what we had sent it.
In the new one, we're actually getting a different error.
It's saying, this application has
no expected mapping for air.
So web go wasn't set up to provide a proper error page.
But the content-type is not something that it expected.
So it did not expect XML.
So it's not even entering the function.
Notice that getting called was called the
first time that I did
my rest test to get a new session in my proxy,
but it was not called a second time
when I actually sent my payload.
So you want to always layer your defenses.
You never know where
a developer might accidentally enable some
of these things back for
certain use cases and for the classes that you control,
for the modules that you control,
you can at least have some certainty that
the datatype is coming in the shape that
you expect and you limit your exposure.
The cyber defense also helps you protect maybe currently
unknown vulnerabilities that could exist in
this XML parser from being leveraged.
May be limiting the input tag to JSON
types limits buffer overflows or heap overflows or
some implementation failure outside of
your codebase cannot be exercised simply
because the data type that you're inputting doesn't have
the proper structure to
take advantage of that vulnerability.
So getting your code to always provide the minimal set
of features that you expect it
to be working on is always advised.