We do custom software development to capture our uniqueness and bring new services to our customers. However, that also opens the possibility for bad people to hack our systems and cause us and our clients pain.

If your existing solutions collect sensitive data, it’s crucial that you use secure coding practices to prevent security breaches that can make you look bad and put the people you serve at risk.

3 Common Attacks on Web Apps

There are a few easy things we can do to build secure custom software and make sure we don’t make it easy for any would-be hackers.

Obviously, it is a good idea to have an outside software development company review your custom solutions for security risks and to have a process run as the development team checks in code. However, there’s plenty of other things that we can do to keep our applications safe.

In order to build secure software, we have to be aware of common attacks that might be used to compromise our new and existing systems.

Most often, these are not brute force things people are going to do to us but rather things that they can do to get what they want from us (get free stuff, get data, cause pain) and can be mitigated with simple design changes to our software development.

All 3 of these examples have one thing in common. They can take our normal processes and use them against us. And they’re more prevalent because they’re very easy to do and take very little knowledge or experience.

SQL injection

Most applications need to save data. Only software used for its own value (calculator) or testing hardware (bandwidth, Wi-Fi signal) wouldn’t.

When an application saves data it must run a “query” in order to save or retrieve that data. If we can change that command, then we can make it do something it is not supposed to be doing. Like delete all of the data, for instance.

Let’s pretend we have a page that looks up customers. This page has a field for a customer name to be entered and a button to click for it to do the search. That button is going to take the entry for the customer name and execute a SQL command to get the customer’s information.

select * from customer where customername like ‘%CustomerNameEntered%’

This command would get the customer with a name containing “CustomerNameEntered”. Now, since I used SQL Server for this example, I know that I can end a statement with a semicolon (there are only a small number of databases and I can usually guess what they use by which webserver they picked).

So, if instead of a customer name I were to enter something else that closes the command and does another, I can execute anything I want in the database. For example, if I entered

‘;delete from customer where customername like ‘

into the box, I would go from

select * from customer where customername like ‘%[CustomerNameEntered]%’

to

select * from customer where customername like ‘%’;delete from customer where customername like ‘%’

That new command would delete all the customers from the database.

Parameter Tampering

Along with data storage, we need a way to access that data. Often people put that into the URL of the page. For instance, if I have a page https://www.geneca.com/customer/customerid=123, a user can bookmark this page very easily.

Unfortunately, it also means someone can look at other customers just as easily. They can change the 123 to be any number they want and most likely they will find someone.

Obviously, there are bigger/worse examples than this, but you get the idea.

I am certainly not going to tell you that you should make your application so users can’t bookmark things. I prefer to bookmark a bunch of places rather than traverse or enter criteria. For instance, I make shortcuts in my browser that open all the pages I need open for each project’s daily stand-up meeting.

Since, often, we don’t want users to be able to switch to different customers (in this case), not everyone should be able to do that.

So, if we just check to make sure the user has access to the customerid being passed in, we eliminate most of this problem.

Cookie poisoning is very similar to parameter tampering. If the application stores information in a cookie (e.g. the user’s customerid), then the cookie could be changed to look at a different customer’s information. Since cookies are just text files, it is super easy to do.

There a few simple security practices that can help mitigate these risks.

5 Secure Software Development Practices

In custom software development, we can build secure software if we just check security access for each request.

Users should only be able to do the things they are supposed to be doing. To be safe, we can’t assume they are still doing what they are allowed to do at every transaction. We want to recheck their credentials to make sure they are allowed to do the thing they are doing each time.

Especially now, with so many different technologies involved in the software development process, and different capabilities in different objects throughout the tiers of the software, many companies can fend off possible attacks by just checking permissions again before doing any data operations.

In our software development, we should centralize our security checking so we can continue to evolve the sophistication over time. If every method in our data layer confirms identity and permissions before it performs an operation, we make it much more difficult for people to trick the system into doing something that user isn’t allowed to do.

5 secure software development practices

As such, we’ve invented a standard secure way to process security so that every custom software development project we do works the same way, we don’t have to invent something new each time, and our clients’ systems remain safe from security threats.

Special Characters

In order to do much of the SQL injection tricks, the user has to be able to trick the software into thinking that multiple database commands are really one command. To do that, special characters are normally involved. Things like single-quotes, double-quotes, semi-colons, and percent signs are very common.

The best thing you can do is to confirm that any information you are going to use for a query is “sanitized” before use.

For instance, if we are going to replace the [CustomerNameEntered] with the name of the customer that we received in the CustomerNameRequested variable in

select * from customer where customername like ‘%[CustomerNameEntered]%’

it may be done in C# like this:

var sql = @$”select * from customer where customername like ‘%@CustomerNameEntered%'”;

var args = new DynamicParameters();

args.Add(“@CustomerNameEntered”, CustomerNameRequested );

In this case, we could just run the value through a sanitizing function first.

args.Add(“@CustomerNameEntered”, SanitizeParm(CustomerNameRequested) );

where SanitizeParm is a function that makes sure there are no special characters in the variable. Or better yet, white label the characters you do want (a-z, 0-9).

Authentication

Certainly we need to have a way to have the user login. We need to make sure, though, that the user we authenticated and the user we are performing an action for are the same person. Something as simple as storing the user as part of the session information on the server and comparing it every time will do that.

If you do something to allow for session sharing across servers so you can load balance your application, you had to do something that would store the user information. If you put that in anything that went client side, stop! A cookie, a hidden field, etc. are all easily changed (i.e. hacked!). Keep it on the server.

However, keeping the authentication information on the server in the session is not enough. You have to have some information that gets sent back and forth so each request knows the session it is in. If you don’t use a session, you have to send all the information to the client – and that is just asking for trouble.

Some people like to send session identifier information in the information to the client so they can verify it and look up the session when the next request is made. What if the would-be hacker intercepts that information? I like to keep the session identifier changing with each answer so it cannot be used again.

Often I will not use a GUID but rather invent an identifier that includes information I know about the person, their location, their machine, and the request history to ensure that they are still them. At least then the hacker would have to be very quick. If I find anything weird, I close that session, disable that user, and block any communications.

Function Security

Once we can confirm that the request is coming from the same person that we expect, we can just confirm that the function they are trying to perform is indeed a function they are allowed to perform.

I know some people like to store that information in memory of the session for speed. I prefer to keep it in the database behind all the security logic that I put into the data layer and do something to make it faster (proper index design, multiple queries in one request, concurrent threads, etc.). Then I get the best of all worlds.

Data Security

Now that we’ve confirmed that (1) the person requesting the action is the person we think it is and (2) they are requesting an action that we allow them to perform, the last thing we need to do is to check that they are allowed to take that action on the data they want to act upon.

If the user is trying to make a profile update or place an order, we can confirm that the user is indeed that customer or that user before we do the transaction (or that the person is permitted to perform the action on that user’s behalf).

Containing Security Risks

This article was not intended to be an all-inclusive guide to preventing attacks and building secure custom software but rather to hit on just 3 small things you can do to keep the majority of people out of places they don’t belong.

Of course, there are other security measures you’ll want to implement throughout the software development life cycle in order to address security concerns that could impact your custom software solutions in other ways.

However, by taking these few little steps in custom software development we can prevent a whole bunch of bad actors from taking advantage of our software application and endangering our business and our clients.

Looking for a software development company to help you update your security processes and safeguard your data in other ways? Contact us and let’s find out what we could build together.