
Okay, thanks everyone for your patience. Please don't let that affect your judgment of my technical ability. Uh, today I'm going to be talking about Salesforce and how certain aspects of coding for it can uh affect something called Saucil injection or SOSL injection. Usual disclaimers at the start of any hacking presentation. This is for learning and knowledge and not for world domination or minor theft. basically what I'm going to be talking about quick intro and who I am overview of Salesforce for anyone who doesn't know then a quick discussion of the SOSL or SOS language and how injection in that can work then we'll work on how to locate the issue how to exploit it and obviously how to fix It's
so that's me. Used to be a a software developer in the financial sector. Uh and eventually at some point became a penetration tester. Started to do more and more work on code review and then threat modeling and eventually started to do much more work in developing my own tools and scripts.
Right. The this talk it's going to be as I said about uh injection into the SOSL language and it will be about uh customuilt APIs and customuilt set pages for Salesforce. It it's not an issue with Salesforce. It's literally just other people's bad coding or carelessness or misuse of Salesforce. And the whole reason I wrote this talk was uh I I was testing Salesforce applications. Stumbled across this vulnerability but could not find anywhere online that explained how to exploit it. Like any pest at pentester, I just took the lazy option and looked for readymade exploits and was horrified to find nothing. But just to repeat, the vulnerability is definitely a coding issue, not a sales
force issue. And to add to that, I am not a sales force experts. Having clarified that, I'm going to explain Salesforce to you. It's a CRM system that you'll often find managing like large data sets at different companies. It can be used to manage product lines, various sets of inventory. And you might find it in use in some government departments in some countries to manage uh people and processes rather than inventory things like uh I guess applications for citizenship, that kind of thing. Um it's Salesforce comes as this package that allows you to build a website for that kind of inventory management with its own uh underlying data structure that they happily refer to with these
CRUD permissions for create, read, update and delete. So different user levels in Salesforce have different permissions and that's both for what they can do to the data and for what they can read. Uh it looks a bit like this but if you do encounter it in any sort of real life setting you'll find somebody's gone to far more effort than I did to make it look more polished and a bit more user friendly. And if you're thinking of practicing this for yourselves, there is a free developer version that you can get and use to practice these kind of attacks and fixes for them. Importantly the Salesforce uh terminology for the way it handles this data they data is always referred to as
objects which an object is a table holding data conceptually similar to a table or worksheet and a spreadsheets and fields and records are the other two aspects of this where fields would refer to the columns as you would get in a spreadsheet and records would be the rows and in terms of those you could use permissions. You know, some reader might only have permissions to look at particular fields on a certain object or may be able to read but not modify. In terms of the handling and how Salesforce is customized, there's a number of languages available that Salesforce uses. Apex is something that's quite similar to Java or a sort of customized Java for with its own Salesforce stuff in there
and that can be used to build these uh APIs that can sit on top of your own Salesforce instance. Sock is something that's used to more for the date a query language that's very similar in syntax to SQL and DML is also very similar to SQL. The difference between those two is that sock can only read and DML can only write. Saucel is also a query language but it it has quite different syntax and different behaviors from the other from SLE and it stands for Salesforce object search language and it can really be used as part of your API part of the APIs that someone builds to search through Salesforce instances for all those objects.
As I said, it's limited to queries. You even if you do discovery injection, you can't update any data. It's just information disclosure. I've mentioned there's two different languages, suckle and saus. uh Salesforce gives this handy sort of guide to when you would use one or the other and um you can read fast and talk so I'm not going to read those all out individually but basically the sil language would be used for far more general querying uh particularly if you don't know if you want to search all fields or don't know which search fields are being targeted. And in terms of when it's written, it looks very much like this. Uh these are syntax examples taken from
online tutorials. But as you can see, it's very similar in some ways to SQL, but just different enough from SQL to be confusing. It it be begins with that always begins with find followed by the search term and then it's got a number of other qualifying cl optional clauses. So it can be used to build kind of dynamic statements in apex or java code.
saus shown. You can build these uh dynamic statements in in Apex code or or in Java if you've got a sick twisted mind and want to use Java instead of Apex for your API developments. and it's uh an accepted vulnerability type that's mentioned on a few websites and very similar to SQL injection. It's that result of incorporating user inputs directly into dynamically built statements.
As we said, DML is the uh the update language. So any injection that you do find, it's strictly an information disclosure issue. You'll be able to read records or fields that you should not be able to see, but you will almost never be able to cause any corruption or rewriting of records unless there's some contrived situation of output data being passed into DML.
The uh the Salesforce official documentation does give a description of sausal injection. uh and it universally just says the escape single quotes method will cure it which isn't strictly true but we'll come on to that later. So as I' like stumbled across this vulnerability when I was testing I found that and immediately wanted to find out more. And as I attempted to find out more, I I I found there wasn't any more information anywhere. My search results just brought back a couple of web pages that said this vulnerability exists. But there was no payloads or examples I could reuse or customize. There weren't really that much of an explanation for for most on most of the
pages I did find. Um, so I've uh gone through this way of finding it. There are a few ways to uncover instances of it depending on the scope of your application test and what you are and aren't allowed to do. You can find this by code review, web application testing and API testing
which you you can do by this fairly standard pentest methodology of the initial sort of scanning or investigation confirmation and then the test to find out just how bad or or how not so bad the extent of the exploitability is.
Typically when you're reviewing Apex code, you'll see these uh the exploitable instances will look in a code review very much like that where a user search string is injected directly into some dynamically built statements. And so you you uh c can use gp to find that but we'll look at improvements on how in a minutes.
Uh you'll also notice that previous statements
and this one uh this is the Java equivalent sort of implementation of a of a dynamic saus.
But the basic outcome of all this is that it will universally look like that when it's been dynamically built. The word find and then followed by a search term maybe or maybe not followed by anything else. So you can find instances in a code review just with the right kind of GP. Uh I know reg x's are a bit of a dark art that there's probably more ways of doing it than what I've given there. But the the instance that you would be looking for is the word find as a single demarcated word followed by zero or more spaces and then followed by uh quote marks or an opening brace.
Once you've got that list of uh different injection points, the important or that different list of statements, the important point is to go in there and look for the level of injectability and exploitability. In terms of web and API testing, it's uh surprisingly easy to use these values as fuzz values or into whatever web scanning tool you're using. Those uh values there will bring back some confirmation. And you'll see a asterisk or a in quotes that despite being two or three characters will bring back that response of your search term must have two or more characters. That would always universally indicate that your search term is being passed directly into a sausal statement. And for kind of additional confirmation
that fourth one would bring back the results of a search. So the results would look like that in terms of web application and API responses. That's bottom one. That HTTP 500 error is universally the kind of response you would get for a asterisk score a in stars.
You you can also see if you're allowed to enter entire longer, more complex search terms, what level of sanitization or or trimming is being done to what you put in. If you try uh complex statements like that and if you do know good or bad values, you can have that variation. although that does rely on a bit of prior knowledge.
From there, once you've got those injection points, you can really look at uh what you can do to cause uh I guess either havoc or confirmation depending on your uh your role and what you're trying to do. as you do confirm all these that there's this uh additional aspects you you need to have roles that are allowed to see different data levels. Um, and although I've been showing you how to do it in web applications, typically the web front end is built in some gooey system where Salesforce controls what you can and can't do where people are given a bit more freedom to implement their own things that there tends to be slightly more missteps taken in customuilt APIs.
And Salesforce does have these uh two modes of user mode or system mode. So someone writing an API would uh would be able to set either user mode or system modes for the query level. System mode would allow uh a complete search of things the user is and isn't allowed to see and would bring back those results.
The main limitations on injection um like that very first example I showed you with unsanitized user input being put in. You can't just go in and write a load of your own wacky statement that does various searches and whatever you like and then comment out the rest of the statements. Um, Sausel and Sle both have no comment character, which is uh a bit of a limitation to try and inject. And that does enforce you having to come up with correct statements that fit the correct grammar. And of course, as I said, there's no data modification constructs, which is, I guess, an additional kind of limitation on what you can do.
Since our chief concerns like exploitability and the levels of risk, we would be uh uh looking at the injection points. That's the example from earlier. As I said, it looks like it's got an injection point, but of course, it's uh that there are limits to what you can do with that without any ability to put in the comment character.
Um but uh as we look more at uh the way these statements are constructed, Salesforce does have this all fields uh which this is from the Salesforce developer guide which explains that ignores system level security when a search is made in all fields. So ideally it's good to have injection points later on in the statements. So the the basic thing about this is uh I if you're used to SQL injection you might it might seem a bit odd or counterintuitive that some of the best injection points in soil are right at the end and in terms of what's being brought back or how the search is carried out injection points in the actual search are not quite so useful.
So if we look at this uh contrived example that I made up th this uh this is what one example of how the escape single quotes recommended defense would not protect this statement. If that uh second field in there uh was injected the uh I'll explain like that uh if that was populated by a drop-own list where where it would populate that field with name, email, telephone, uh somebody using a web prox C could intercept that, populate it with their own value for all fields and carry out that re wider search of the full data set without those uh security restrictions being enforced. Salesforce helpfully gives you a an example of how to use that in clause.
as well as some of the examples of standard uh uh standard examples. There are number of fields that are always present in certain record types.
So in terms of what you're actually looking at the the although you're looking at what will be done with this after your main outcome or main objective will be to see if you're a able to inject at a point that where you can do as we've seen just to violate the security restrictions or on either fields or other stuff and bring back data that that user should not be able to see. For anyone who any developer who's built this stuff in in the web interface, those searches are universally carried out in user mode. So uh it's a lot of the time as I said the APIs uh will could be running in system mode and you will be able to find a much
wider range of searches and to sort of uh I guess enforce or uh or or to bring back those uh restricted records that that user shouldn't be able to see
uh if you're using this uh I if you're attempting to confirm exploitability but with application testing that there's a few basic tools you can use. It's all all the standard sort of web developer or API testers toolkits that you would use to go and and look manually at those injection points from your initial scanning and fuzzing.
First, one of the best ways of testing for sanitization or an absence of sanitization would be to look at the web well the API's responses to the the curly braces or to the quote marks and to see if that causes an error or just results in a regular search.
and broader search results than intended are what we're really after. Any sort of fields that are visible uh in the API test that were not visible when you did the same search in the web interface. You can do a kind of response comparison, bringing back regular data from the API, and then checking if the API allows weird constructs that should not normally be allowed to look if you get uh totally different results back in the API which are are not visible in the web interface. So that would be an example of the API running in system mode, the web interface running in user mode and showing that you get no results that way, but you do get uh results that way
and you may be able to get hold of information that you shouldn't be able to as I said some in some injection points are better than others. And so this uh initial search string after the find it is on its own not that useful. But an unsanitized uh search string being injected into fields can allow you to search all fields with no security restrictions. And that would bring back information that that user would not normally be able to see.
As well as the fields clause being a targets, the returning and wear clauses can be another target. That is again something where you can enforce a search on on things that that user would not be able to see.
So the the where sub clause is that final parts or or final two parts of that statement where it carries out some additional tests and returns data based upon what's actually within those wear clauses. So if they are built up in a dynamic way like this, you you might be able to get a workable attack vector where you would see something like a user parameter being in uh being in placed into that wear clause. That is at the the end of that. that allows a fairly sort of complex attack like this other one as we saw just you can have multiple wear clauses within this returning statement. And so, uh, a lack of sanitization would
allow you to add on add on this whole other search of a of a field name within a different record. And that could be carried out on behalf of that user to see uh, records that were not normally visible to that user.
So, as the developers intended, it would just be that injection point at the end, the use of search term being injected into being placed in that final wear clause. In the event of unsanitized data, you would have that chance to uh not only sort of put your thing into the proper wear clause, but add on your whole additional of the search of a different records uh causing that search to bring back an additional set of data and the response. And I know it sounds like I'm recommending something where you would need to know what records were available and what you can search for. But uh there are standard objects available on the system and certain standard fields like within
the returning clause that you can look up in order to get yourself some foothold and uh at least prove that that kind of injection is available and that you can bring back data. You shouldn't be able to
Um, obviously uh all that stuff shows you how to, uh, cause issues or do damage, do things you shouldn't, but we're all here to fix things for people and show them how to do better. So let's take a the the a few mitigations possible in terms of uh sanitization. You can use the escape single quotes function but as we saw earlier that's not enough. Um really like one of the main things is that avoiding direct use of user controlled string literal where it could appear in some other parts of the clause and just really checking for those valid values as you build things. the uh the colon operator is uh something that you can use as in
the bottom one there where a bit like uh a parameterized SQL statement. It it prevents people building up dynamic statements with just any old random characters in them. And and it always enforces this safe search. That that is always the safest way to do it. And relying on escape single quotes is never safe.
And of course uh it's always best to put some additional input validation as we said to avoid certain kind of words in there. the uh really things like that allowing field names to be placed into an all statement with the field names named by the user is one of the most unsafe things that could be put in there. It's far better to build up those as the way web developers are told to do in a safe way like this of the the front end or API takes an input value of 1 2 3 4 and the back end maps that onto the field name.
Okay. Everything we've looked at so far has concentrated on SOSL syntax and usable payloads ways around different uh input methods for the sock and DML. Uh a lot of the standard SQL payloads will work for those and anyway it would have made the presentation too long. Um but but really you should uh there are numbers SQL injection issue uh payloads that will work for that as long as you bear in mind that there's no comment character.
So, I know there's been a lot of information there and uh and quite a sort of long syntax driven discussion of things that I know not everyone is familiar with. But just to recap, saus it has information disclosure issues, hardly ever has information integrity issues. The injection points towards the end of the statements are almost always more exploitable than the ones in the find clause. One of the real fun things about testing it is that it's not a well-known issue. So you got a good chance of finding things that have been missed by other testers. Um, and really it's a uh the not so fun side is that sometimes you find systems where every user is allowed to view
everything and you've pro proved a vulnerability that has no consequence. But um this is all that I've been able to find from my own reading and research. But if anyone does find out more, I'm always happy to hear off others. I know I've probably run over a little bit in terms of time. So any questions? All right. Thank you, Nick. Questions.
Thank you for your uh for your research. Uh compared to regular act databases, is all the information that you can pull out using these types of attacks, is it all related to like that specific Salesforce object or application or is it can you see like broader information about the organizational organization's Salesforce information? Tragically, it's limited to uh that organization and whatever they've put in Salesforce. Uh yeah, there's no way to >> to kind of like bust out and see like let me let me see all the applications or can I search can I search from one application and I know about another one over here that I don't have any access to and >> yeah I I guess it would be whatever
objects sit under that particular Salesforce instance. >> Okay, thank you.