Designing for security is something that needs to be done at all programming levels. Even if you are writing a quick piece of software that few will have access to, you need to consider the security impact this program can have. If the software has a public interface, this security becomes the most important requirement of that software.
In this post, I will pass along some tips for design fundamentals to check off as you create your software product:
If you are using enterprise-level database software, there are many options for user access to your database. Here, more than any other place in your software, should you start with the Principle of Least Access. It is easy during development to give a user SA access and then forget to scale back that access when you deploy to a production environment. Instead, start right out with a user that has the least possible access to the database. Give the user access to only execute stored procedures that you implement. Start safe, and you will end safe.
In addition to the user access restriction, there is the idea of Stored Procedures. Make sure you use them exclusively to access data in your database. You will avoid stupid simple SQL hacks from the old days without even thinking about it, and since they are pre-compiled with an execution plan, you should notice a great improvement in execution time.
True Multi-Layered Development (not just Architecture)
This one is difficult, especially in small development shops. In big development organizations, the developers don’t even have access to the databases at all unless they have a specific need. Database admins give them access, and create users as described above, and they get limited access to the actual data. In small shops, however, it is easy to “cheat” here and there and give a little too much access to the database from the object layer. Tsk-tsk.
Here is where you have to keep a lot of hats on your desk. When developing the object layer, try to imagine yourself as the “customer” of the DATA, not the DATABASE. Pretend you have no IDEA how the data is stored. Heck, it could be in flat files for all you know. You just know you expect to see a certain result set for a certain call to the database. If you need more, stop, put on your DBA hat, go make that happen, then come back and be the object programmer again. I know it sounds like semantics, but if you discipline yourself you can become more able to think like this.
This idea also applies to the presentation layer. Become a “customer” of the object layer. You can be ignorant to the implementation and not know how the objects do what the object programmers made them to do. A good practice would be to make ALL of the methods on the object layer internal or even private to start. Then, slowly give access to the presentation layer method by method to make sure that the objects are not too exposed.
Incidentally, an even BETTER approach is to add an explicit SECURITY MODEL layer. I am certain I did not come up with this on my own, and I am certain my idea is not unique even if I did come up with it independently, but I have a nice blog post about this from a few weeks ago at https://michaelmayle.com/2015/07/17/the-best-defense-is-a-good-security-layer/. The basic idea is that in this layer you create a stateful object initialized to a specific scope (in my case, an end-user of a multi-account system), and verify access to everything as the user is requesting in that object. It is pretty boss.
TESTING TESTING TESTING
Ok. I know it is tedious. Unit testing is the BEST tool I have for finding the smallest errors when I make some pretty big code changes. Want to add a field to a database? Then you have to add it to the object, then use it on that page you wanted in the first place, blah blah blah…
Now, what have you messed up along the way? If you start this game out with a good set of unit tests, you will know the answer to that in about two minutes flat. If not, you may not find out until you get a complaint about some obscure function that no longer works, or even worse, gives too much access to a database. Ouch.
Which would you rather???
Look, just don’t do it. I know you want an easy way to see an admin-level view of your software. I know you think that the username “politically” and password “incorrect” are clever enough to thwart any would-be guessers. Just… don’t. It WILL bite you in the ass eventually.
Rely on the Reliability of Tested Technology!
Look, I am not preaching to the merits of the mega-corporations of this world. I get it, Microsoft Bad! Google Bad! Apple Bad! Linux Only Good System in WORLD!
Well… look. I have all of these in my home. I have a Linux computer as my primary computer. I have a pretty kicking Mac in the basement that I use for recording music. I have a couple of Windows machines (a pretty cool pad that just got upgraded to Windows 10, and a laptop for the kid), a Chromebook and an iPad for the wife, a Raspberry Pi (first batch! Jealous much?), an Android pad, you get the picture. I have a lot of toys. And how many viruses have I had? None. Why? Because, as long as you keep them up to date, keep the recommended security software on them, and stay away from the nether-regions of the Internet, you are going to be reasonably safe from attack.
Guess what – the same applies to your server environment. So, if you are using IIS7 on a Windows Server, or an Apache LAMP implementation, or an OSX server, or a Solaris server, or whatever… just keep it up to date, keep it free from sketchy software, use the principles of Least User Access for the users running all of the services, make sure your firewall is only allowing traffic to ports you really need, and you will be fine. These companies are in business because their stuff works, no matter what the fanboys of other environments may say.
Be smart, from the start. Design from front to back with security in mind. Know exactly what you are doing and why. Keep all of this in mind and you have done the best you can to create a secure application.