When getting a company started, first impressions are everything. With hackers abound and data breaches all over the place, you don’t want your new company to fall victim.
For a startup, having big losses associated with a data breaches would literally close the doors. Below, you’ll find 25 programming errors that any startup should avoid, and everyone else should, too.
Buffer overflow errors can happen in one of two ways. You can either incorrectly calculate the desired size before filling up a buffer or you can copy from one buffer to another and overflow the copy. Unicode characters are wide so can take up more than a byte. And with translations from & to & to display HTML correctly, it is very easy to cause overflow.
Cross-site scripting (XSS) errors happen when untrusted scripting code gets injected into the web page to execute without security controls, or at least bypassing the controls limiting access by code origin. The easiest fix here is to rely on libraries that deal with the encoding for you, versus trying to roll your own.
Cross-site Request Forgery
When you travel through an airport, do they ever ask you if you accepted a package from a stranger? That’s basically how Cross-site Request Forgery or CSRF works. Don’t automatically trust packages of code delivered by strangers. If you do accept the code, it will execute with your credentials, giving the code your permissions.
SQL Injection Errors
SQL injection errors happen when a user provided string is executed by your database and it isn’t properly escaped or sanitized. Do you prompt your user for text to find anything in the database? Make sure you don’t let them enter a command that could either alter the system security or expose protected data.
OS Command Injection Errors
Just like with executing SQL commands, any time you pass a user-provided string to an OS command, you need to make sure the OS command is sanitized before it executed. You might use perl or PHP to execute a search. What would happen if the user escaped something like “rm -f -r /” and you let the command execute?
Break-ins typically happen through the weakest link. While you might have a deadbolt on the front door, if the back door or slider or air conditioning duct has no lock, intruders will find the other way in and wreak havoc. Make sure all critical functions are controlled by appropriate authentication controls.
Where authentication controls who has access to the system, authorization controls what they have access to once inside. Are they authorized to access a resource or perform an operation?
A badge might be the authentication enough to get through the front door, but authorization limits where someone can go or what they can do. Don’t blindly let everyone do everything once you know who they are.
You might have great authentication and authorization controls in place but some developers are lazy and may try to group permissions together in an effort to save time. Or, you may place authorization controls within YOUR web app, but if someone creates an alternative client, it could totally bypass those controls.
In short, these days just encrypt everything. CPUs are powerful enough that they can handle the extra load. Hackers can sniff out data sent over the wire. Anything sent in cleartext can be intercepted, manipulated, and passed along as if it was the original source. Don’t rely on protocols like FTP that work with unencrypted passwords.
Broken / Out-dated Encryption
Encryption standards evolve for a reason. First, never roll your own. You might think you’re protecting yourself by doing something cute and simple to encode your messages differently.
Stay up to date with standards and use as a wide key as possible to keep your data secure. AES-256 seems to be the preferred standard for now.
Quite simply put don’t hard code credentials in code, like done to protect an Iranian nuclear site. If source is a scripting language, someone can just read the page source.
If Java, class files can be decompiled. If someone gets fired who knows the password, or an attacker discovers it on their own, you need a quick way to change it and protect your data.
Incorrect Permission on Critical Resource
Run your code in a sandbox with as few permissions as possible. Here, we’re talking about things like file permissions on configuration files or even just images.
If you have a config file that is world writable or an image file that anyone can replace, you’re doomed for failure or at least exposure of more than you bargained for.
Executing Commands with Extra Privileges
If you just execute everything as root, any user-level permissions you have setup will be ignored. Run with as few permissions as possible and if you need to raise permissions to execute a command, make sure any lowering of privileges isn’t lost due to some exception happening. In Java-speak, that would mean putting the lowering code in a finally block.
Not Limiting Excessive Authentication Attempts
Let’s say you have all the authentication and authorization controls in place and a hacker tries to crack someone’s password. A computer can easily try to guess a password at least a BILLION times per second if attempts aren’t throttled. Consider locking out accounts for a short period of time if the number of attempts is excessive.
Do you have an area on your system where users can upload files, like avatar images or files associated with error reports? Consider limiting the size or else an attacker could blindly fill up your system’s disk space. Even if you limit size, make sure users can’t then download what was just uploaded, or you could become a conduit for illegal file transfers.
Path Traversal Exposure Errors
The tail of the two periods here. Simply put, you need to whitelist what can be accessed and not blacklist what can’t. If you rely on a blacklist, you’re bound to miss something new when created or added unknowingly. This makes sure someone doesn’t blindly include “..” in the path to a file that takes them out of a directory users can access.
Plan for a large number of users or items or elements or whatever. As many of us discovered with Y2K, two digits to store a year was not enough. Adding two numbers of the same computer type cannot “fit” in the same type. 127 + 1 is -128 if you only have a byte to work with.
Uncontrolled String Formatting
Log files and data like dates typically need to be provided in a known format so that the receiving program can parse the data. Just like with SQL and OS commands, don’t blindly allow a user to provide a formatting string for anything that needs to be later handled.
Does your application let a user define the order that date fields are displayed? If you have an “other” option that lets a user specify order with a string like MMyy, your application is at risk if you don’t validate the input string.
Assumed Trust of Downloaded Code
Imagine your computer application supports upgrades and asks a “home” server for an update. The application accepts the update and modifies itself accordingly to be the new version. How can this go wrong? You need to have integrity checks in place to make sure the code came from where it did and not from some man or woman in the middle or even a hacked server.
We’re not talking about the weather conditions on the day of a marathon here. When concurrent threads need access to a shared resource, a race condition can exist if operations aren’t atomic and a second thread manipulates an object in the middle of the first thread’s usage. There are ways for attackers to exploit this and it could just lead to an application crashing.
No Throttling of Resource Allocations
A web server can only handle so much demands. If you don’t have a way to load balance or throttle requests, excessive demands could take the whole system down.
When working with a limited resource, consider what could happen when an attacker or competing company comes at you with tons of requests at once. Distributed Denial-of-service (DDoS) attacks are all too common these days.
Ensure the range of values is correct and you don’t miss the minimum or maximum value, or you could go one beyond. This commonly happens when you switch between a zero-based index ranges and a one-based one, without realizing it. For instance, a common error when working with Java’s Calendar class, January is 0 not 1.
This can happen in any language but it happens differently in each. Basically, just don’t leave any dangling references to unused objects. With web apps that literally run forever, you can’t just restart the system every hour to clear any leftover memory references.
This is more a statement of don’t forget the little stuff. When you think of programmer errors, you typically think about big picture items. There are lots of little things that can cause big troubles, too, especially with interpretive languages, where there is no static analysis / compilation done before code executes.
Believing Programmer Resumes
Lastly, especially important for startups is hiring the right programmers. Don’t blindly believe everything on a programmer’s resume. While the resume might technically be correct about what a project does, their role in that accomplishment might not be as clearly stated. Have good hiring practices in place to build the best and brightest team.