Demo time for injection.
Yeah, we're looking specifically at SQL injection.
There are some defenses that are specific to SQL,
and that's what we're focusing on.
This applies to creating raw SQL strings. Using LINQ to
generate your Entity Framework queries already parameterizes
them, and so it won't be a problem.
ASVS requirement 5.3.4 verifies that data selection or database queries are
parameterized. For both ADO.NET queries and Entity Framework queries, we're
going to see how we can do just that. In our SurveyController, a quick note
on LINQ. Here we've got some LINQ using FirstOrDefault with a lambda, which
is effectively saying give us the rule where the ID is the ID passed in
from a web request. Using LINQ like this is safe because it does
parameterized values for you. Scrolling up, we've got
SurveyCompleteMessageAdo, which is using a ADO.NET to make a raw SQL query.
In the interface, we're going to see how it's used normally. After
completing a survey, it can be used to deliver a completion message.
The ID in the URL is a string, so it is lacking input
validation. If we change that, we can add a single quote,
and the response gives us an error.
That strongly suggests we have a SQL injection issue. Adding OR
1=1 ‑‑, we get the message from 2 surveys.
There are only two rows in the database. That shows us
we've managed to use OR 1=1 as a command.
This verifies that we can send commands to the database. From there, we would be
able to do other things like drop tables, perhaps. To fix that, we're putting
our query into command text, but using @id as the placeholder in there instead
of concatenating the id into the string.
We're then using Command.Parameters.Add to create a parameter with the name
ID and the value from the ID. That should be it. Back to the interface, it
works for a valid ID. If we add a single quote, it returns nothing. That's
because it's trying to find an ID with a single quote on the end. It looks
like we've got a defense.
Add the rest of the injection. Again, we can see it doesn't
work. Moving on to Entity Framework, the URL is slightly
different, but the functionality is the same.
Going to that, it works. We add a single quote, and there's an error to suggest
vulnerability. Adding the injection, and we get both records, so that is
vulnerable. To the code, and we're just going to make a slight change. Instead
of concatenating the value into the string, we're adding a placeholder, then
providing the ID as a parameter.
We can add as many placeholders and parameters as we need here. And that's it.
Running that again, it still works from the correct ID, so we
add a single quote, which gives us an empty page. Adding the
full injection also doesn't help. That's both ADO and Entity Framework protections working.