How to write insecure code

Revision as of 22:36, 19 August 2006 by Jeff Williams (talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


Help us out and add your favorite ways to discourage secure coding below.

In the interest of ensuring that there will be a future for hackers, criminals, and others who want to destroy the digital future, this paper captures tips from the masters on how to create insecure code. With a little creative use of these tips, you can also ensure your own financial future. Be careful, you don't want to make your code look hopelessly insecure, or your insecurity may be uncovered and fixed.

The idea for this article comes from Roedy Green's How to write unmaintainable code. You may find the one page version more readable. Actually, making your code unmaintainable is a great first step towards making it insecure and there are some great ideas in this article, particularly the section on camouflage.

Special note for the slow to pick up on irony set. This essay is a joke! Developers and architects are often bored with lectures about how to write secure code. Perhaps this is another way to get the point across.

General Principles

Avoid the tools
To ensure an application is forever insecure, you have to think about how security vulnerabilities are identified and remediated. Many software teams believe that automated tools can solve their security problems. So if you want to ensure vulnerabilities, simply make them difficult for automated tools to find. This is a lot easier than it sounds. All you have to do is make sure your vulnerabilities don't match anything in the tool's database of signatures. Your code can be as complex as you want, so it's pretty easy to avoid getting found. In fact, most inadvertent vulnerabilities can't be found by tools anyway.


Distribute security mechanisms
Security checks should be designed so that they are as distributed as possible throughout the codebase. Try not to follow a consistent pattern and don't make it easy to find all the places where the mechanism is used. This will virtually ensure that security is implemented inconsistently.
Spread the wealth
Another great way to avoid being found is to make sure your security holes aren't located in one place in your code. It's very difficult for analysts to keep all of your code in their head, so by spreading out the holes you prevent anyone from finding or understanding them.
Use dynamic code
The single best way to make it difficult for a security analyst (or security tool for that matter) to follow through an application and uncover a flaw is to use dynamic code. It can be almost impossible to trace the flow through code that is loaded at runtime. Features like reflection and classloading are beautiful features for hiding vulnerabilities. Enable as many "plugin" points as possible.
Mix languages
Different languages have different security rules, so the more languages you include the more difficult it will be to learn them all. It's hard enough for development teams to even understand the security ramifications of one language, much less three or four. You can use the transitions between languages to hide vulnerabilities too.

Trust Relationships

Rely on security checks done elsewhere
It's redundant to do security checks twice, so if someone else says that they've done a check, there's no point in doing it again. When possible, it's probably best to just assume that others are doing security right, and not waste time doing it yourself. Web services and other service interfaces are prime candidates for making the security assumption.


Use your logs for debugging
Nobody will be able to trace attacks on your code if you fill up the logs with debugging nonsense. Extra points for making your log messages undecipherable by anyone except you. Even more points if the log messages look as though they might be security relevant.
Don't use a logging framework
The best approach to logging is just to write to stdout, or maybe to a file. Logging frameworks make the logs too easy to search and manage to be sure that nobody will ever review them.


Build your own encryption scheme
The standard encryption mechanisms are way too complicated to use. It's much easier to make up an encryption algorithm that scrambles up secret stuff. You don't need to bother with a key or anything, just mix it all up and nobody will figure it out.


Build your own authentication scheme
Authentication is simple, so just use your common sense and implement. Don't worry about esoteric stuff you hear about like session prediction, hashing credentials, brute force attacks, and so on. Only NSA eggheads could possibly ever figure that stuff out. And if users want to choose weak passwords, that's their own fault.

Access Control

Just let your authorization scheme evolve
It's really hard to figure out all the access control rules for your application, so use a just in time development methodology. This way you can just code up new rules when you figure them out. If you end up with hundreds or thousands of lines of authorization code scattered throughout your application, you're on the right track.

Static Analysis

Don't use static analysis tools
These tools aren't perfect, so just forget about them. Static analysis tools are likely to create annoying warning messages that will slow down your development time. Also they're a pain to learn, setup, and use.


Don't document how security works
There is no point in writing down all the details of a security design. If someone wants to figure out if it works, they should check the code. After all, the code may change and then the documentation would be useless.


Don't use security patterns
Make sure there's no standard way of implementing validation, logging, error handling, etc... on your project. It's best when developers are left free to express themselves and channel their inner muse in their code. Avoid establishing any security coding guidelines, that'll just inhibit creativity.
Make sure the build process has lots of steps
You want to maximize the number of steps in the build process that have to occur in the right order to make a successful build. It's best if only one person knows how to actually set up all the config files and build the distribution. If you do have steps written down, you should have lots of notes distributed across a bunch of files and howto's in lots of locations.


Test with a browser
All you need to test a web application is a browser. That way, you ensure that your code will work perfectly for all of your legitimate users. And what do you care if it doesn't work for hackers, attackers, and criminals? Using a fancy security testing tool like WebScarab is a waste of your valuable time.
Build test code into every module
You should build test code in to all parts of the application. That way it will be very difficult to pull it out of the application before deployment.


Use lots of precompiled libraries
Libraries are great because you don't have to worry about whether the code has any security issues. You can trust your business to just about any old library that you download off the Internet and include in your application. Don't worry about checking the source code, it's probably not available and it's too much trouble to recompile. And it would take way too long to check all that source code anyway.