Hello everyone.
And welcome to this Salesforce Security Demonstration
about protecting your apps, and your custom apex
from SOQL injection, and building security into your code.
My name is Roy Davis.
And I'm a Senior Product Security Engineer
here at Salesforce.
I've been a member of the security team
for almost four years,
and I love working at Salesforce.
It's a great company.
Now, as a developer,
you have a lot of power on the Salesforce platform.
You all know that.
And with that power comes a responsibility
to ensure that your apps are secure
and maintain trust in the platform.
Today we're going to talk about one type of vulnerability
called SOQL injection.
And we'll talk about one of the ways
that you can avoid introducing it into your code.
Now, there's two specific Trailhead modules
you'll want to review in relation to this demo.
They are called Understand SOQL Injection,
and Prevent SOQL Injection in Your Code.
To work the demo yourself,
make sure to visit
the Get Started with Application Security module
to create the Kingdom org that you'll see in this demo.
The first thing we're going to do
is take a look at the security vulnerability itself.
And to do that, I'm going to share my screen,
and we'll use my implementation
of the Kingdom org on Trailhead.
So go ahead and login.
And after logging in to the Kingdom org,
we're going to navigate to the SOQL Injection app
in the drop down list,
and then we'll select the SOQL Injection Demo.
Now, this is already on the SOQL Injection Demo,
but you'll see over here in the apps list,
there's lots of other demo apps that you'll be using
as you go through that trail mix of security topics.
So now, we're going to click the SOQL Injection Demo
and you can see now that we've got this page
where we can perform searches
across The Kingdom by title or by age, okay?
So, the first thing we're going to do is search by title.
So let's do title of search, all right?
Perform search.
And, you can see that we've got
a bunch of data returned here,
all of the titles are searched.
Now, I've added something to this demo,
just so that we can see the SOQL string
that's generated and being used internally
by the Apex controller.
And you can see, we have select name, role,
title age from personnel where title is like sir,
and then we've got these wildcard characters here.
All right, well, that was simple enough, right?
It behaved as expected.
And now, let's try and be malicious.
Let's put on our hacker hats,
and instead of searching for a valid input string
we're going to use a SOQL wildcard,
and an and condition to do some SOQL injection.
Now this condition should tell the SOQL query
to only return users with a low performance rating,
because the search string for the title is a wildcard.
Essentially I'm asking SOQL to return to me
all the citizens with a performance rating that's low.
So, this shouldn't be allowed, right, obviously.
And so, we're going to see how SOQL injection really works.
So I'm going to grab this string here,
and I'll go ahead and paste it down here.
We'll get rid of the sir,
and we'll paste in our injection string.
Now, you can see I started it with a single tick mark,
and then the and keyword,
and performance rating,
which is a column of data in the table,
and then less than 20
and name like single tick mark right there.
Let's see what happens to our SOQL string
and our resulting data set,
once I perform this search.
Ah, well, you can see the SOQL string
has our payload injected, right?
We've got percent tick,
and performance rating less than 20,
so the name is like percent,
that will match anything,
the title is like percent, that will match anything.
So basically I've shortcut, short-circuited,
the SOQL query to just return me rows
with performance rating of less than 20.
And look, there's two.
So, hmmm.
This shouldn't be allowed, right?
Based on the field level security settings
and what this app is supposed to do,
it shouldn't be allowed.
But it does work.
You can see Chris and Grace
apparently have low performance ratings.
So we've seen this application ends up
allowing you, an end user,
who can't normally do these types of things,
essentially run unlimited SOQL queries
without running into any permissions issues,
problems, that you normally would in Salesforce.
But why?
Well, let's open up the Apex controller,
that is actually handling getting these search results,
and let's have a look.
So we'll do that down here,
Visualforce page, Apex controller.
Let's pick Apex controller.
And we'll go to the edit window.
And then we're going to just up a bit.
And here, on line 23, is where all of the problems start.
So up here, we've got our query, which is static,
a static string, and our where clause,
plus equal title like, and then our input.
So this is input coming directly from the user, right?
And one of the first rules of secure development
is never trust user-controlled input.
So what's happening here is,
the application is trusting
that the user-controller data is safe.
And when a malicious user abuses that trust,
they're able to retrieve data
that they shouldn't have access to.
In this case,
who in the Kingdom has a low performance rating.
So, how can you develop Apex code
that is not vulnerable to this type of injection attack?
Well, there's several ways, in fact.
And implementing more than one may seem redundant.
But it's what security folks call defense in depth.
And you can think of this concept
in the same way that you might think
of protecting a castle, with a moat, and a drawbridge,
and huge stone walls,
and archers, and knights in shining armor.
You'll have several layers of defense to rely on.
No application or computer system is ever 100% secure.
But when defense in depth is implemented,
we can reduce the risk to an acceptable level,
while keeping applications functional for the users.
So in this short demo,
I only have time to show you one of the ways
to protect against this vulnerability.
But, if you want more,
keep an eye on the Salesforce developer channel,
and you can watch the full 25-minute video,
in which I go into more detail,
and more remediation approaches.
Now the one solution that we're going to talk about,
is the use of bind variables.
And as we've seen,
allowing user input directly in a SOQL query
opens the application to SOQL injection.
To mitigate this risk,
let's translate the query into a static query,
and let's use bind variables.
So you can see I've got the fix down here.
So let's go ahead and just comment out this here.
And we'll uncomment the fix string.
Now, look, we've got our where clause, records,
that's where we're keeping the records
that we get from the database.
And this time, there is no single tick mark on either end.
It's not a string.
This is actually a static query.
So you can see the square brackets on both ends.
And then down here where we have textural title,
it's preceded by the colon character,
which makes this a bind variable,
a bound variable to this query.
Now we have SQL string here just to show
that we are in fact using a bind string.
You can remember
it said the SOQL string equals bla, bla, bla,
and now it's going to say bind string.
So let's go ahead and try this out.
Let's do a quick save, and go back to our application.
And let's just reload it,
because we changed the Apex controller.
All right, now let's put in our SOQL injection attack here
with the quotes on either end,
and perform the search.
All right, look:
The SOQL string is now a bind string.
And we get no records back.
So, why does this solve the injection issue?
That's a great question.
The use of bind variables
ensures that all of the user input
is treated as part of the search string,
not as an executable element of the query.
With bind variables,
the attacker isn't able to break out
of the control of the SOQL query.
So while bind variables and using them,
are recommended, there are some limitations
that you need to understand.
And those are explained in more detail
in the SOQL injection trails on Trailhead.
So, in this short talk,
we've learned about SOQL injection vulnerabilities
in Salesforce Apex,
and looked at one way to remediate that issue.
For more information on this,
and additional security topics,
be sure to go to Trailhead.
Thank you for watching, and have a great day.