Previously we talked about common client-side security hacks we should mitigate in Basic Client-Side Security Concepts. Server-side injections are also very common and can be very dangerous if the hackers manage to get to the database or use your server-side code to send malicious data to users’ devices. The server-side side can be attacked by either going through the client-side or by going directly to the server-side code. Aside from hacking the server, the server-side code can be used to cause havoc if it has been opened up to the world as an API and access to it has not been properly secured.
Access Point #1: Pass the Client-Side
In the article Basic Client-Side Security Concepts we talked about how to mitigate client-side attacks through XSS. Let’s say that we have done everything possible to escape our client-side code and we have successfully escaped a hacking on that side. The user input has gotten through the client-side swiftly as text and is now entering the server-side for further processing. There are many ways that our user’s input can now wreck havoc in the server-side code. Similarly as in our client-side code, hackers can use ending characters such as a quote or a double quote to inject troublesome commands. On the server-side, however, text will not be carried out as code instructions. The server-side distinguishes between code and text more strictly than the client-side and, instead of processing the text as code, will throw an error. Even though this is a good thing, it doesn’t mean that we are safe from hacking on the server side.
There are many ways to communicate with the database in order to insert/delete/update data. Some are safer than others. You can, for example, construct a text query on the fly in the server-side code and send it over to the database. Or, you can call a query that has been previously created in the database and only pass it the parameters that need to be saved. You can start to see how the second method is safer when we understand that in the first method the entire query is being treated as text – including the user input. If we’re creating the query using user input text, we open up the possibility of a database code injections (commonly known as a SQL injection for SQL databases.)
Say for example we have the following code to save a user’s comment into the database…
//server-side code in blue, server-side text in red and yellow representing the construction of a textual database query, database code in red and database text in yellow.
server-side code here to send the following text as query to database "database code to save 'this comment text'"
The text in yellow is the comment text that user will type into a text box. Let’s see what happens if a hacker types in an escape character such as a single quote into the comment…
//here the hacker has injected anything after the comment' as database code due to injecting a single quote into the text of the comment
server-side code here to send the following text as query to database "database code to save 'this comment' text'"
It’s important to note that not every user that inputs the wrong character into the comment text will mean to hack your system. Single quotes in user input are very common as apostrophes and even quotes. It is up to you to make sure to account for all possibilities in user input and mitigate this risk.
An approach mitigating this risk uses queries stored on the database. Instead of constructing a textual query on the server-side and passing the whole thing to the database, use a query stored on the database and only send it the comment text. This way, the text you pass into the database is not treated as code and any text the hackers want to pass in as database code will be purely treated as text.
Access Point #2: Direct Access to API
I write more on what APIs are in What is an API?. But, in general, you will know if you have an API vs. when your server-side code will be in the same project as, and tightly bound to, your client-side code by whether you have a mobile app or a web app. Mobile apps need to have an API because the client-side is saved on the user’s device and the device is not capable of running server-side code. So, the two cannot be coupled together. The client-side will still need to have a server-side and, so, it will need to be outside of the device wrapped in an API. Of course, web apps can also have an API, and many do, but I leave that explanation to the above article.
Having an external API that your client-side or server-side will call means that we need to expose entrance points (called endpoints) for the API. Never mind the technology around this or the syntax for these end point. Our focus is that these endpoints have to be opened if we are to access them from user’s devices. If the security around these entrance points is not handled correctly, the server-side will be exposed for attacks. For example, if a user would like to delete a comment they have made in your app, the app’s client-side code will need to make a call to the server-side API to delete it from the database. Now, if the API has not been properly secured, anyone can perform this same procedure without using your client-side app by going directly to your API’s endpoints. The consequences of this are endless. In this scenario, hackers will not only be able to delete/insert/edit any user data, but they will also be able to perform any actions your API can – like emailing, or spamming, all your users.
There are many methods to secure your API. Make sure your developer employs them to eliminate unauthorized access.
Access Point #3: Direct Access to Code
A more direct, less programmatic approach to getting at your information is by getting at the files of your application directly. In the next article on basic security, Basic Database Security Concepts, we discuss securing your data as much as possible in case of a server hack. However, hackers can also get at your information in much simpler ways without involving any technical knowledge. That is, if you simply expose the files of your app straight to the public without knowledge or with carelessness. Many developers store code on gitHub or bitbucket. This is a good practice for many reasons discussed in Why Are Repositories (like GitHub and BitBucket) Needed? However, both gitHub and bitbucket give users the ability to make the code public or private. If you make it public, anyone can have a gander at your code, which, in itself is not bad, until you consider storing your configuration files in there as well – which, in fact is the default. Configuration files, in general, store very sensitive data like usernames, passwords and API keys. Make sure your developer does not store these in the repositories, or makes the repository private.
Secondly, if your database has been hacked and your server-code files on how to decrypt the data are stored in your public repositories, your hackers now have a way to decrypt the data and get all your users’ sensitive information. So it’s not only the configuration files that we need to protect. I’ll continue this thought in the next article Basic Database Security Concepts.