Sometimes it feels like everyone thinks security comes down to stopping people from breaking into your software. Sales people push vulnerability scanners to find flaws in your business's software and compare the security of web browsers by the number of discovered bugs.
I believe measuring the security of the system by counting the number of known bugs in comparison to its competitors and declaring a system secure if all known vulnerabilities are patched misses the point. Patching known vulnerabilities doesn't make you any more secure from the attack against the undiscovered bug.
Think about it for a second.
A professional programming environment considers only 1 bug in every 1000 to 3000 lines of source code as something to take pride in. The average commercial software package has millions of lines of source code. That means any commercial software package has around 1000 to 10,000 undiscovered bugs - each potentially capable of being used by an attacker. Any criminal skilled enough to steal from your business is capable of finding and using a completely unknown and undetectable attack to steal your crown jewels.
I believe the question we should be asking of our software is why was it designed to allow a bug to gain that level of access in the first place. I propose a new form of secure coding that focuses less on specific ways of writing code to avoid bugs and that instead teaches how to design software that is robust enough to be secure in spite of the bugs.
All software can and will be hacked. We should design our software to be secure in spite of this.
Let me explain, Our goal is to design software that - even when fully compromised - doesn't provide greater access to the attacker than the attacker already had.
How?
Instead of building one huge software package that contains millions of lines of code; design the product offering as a collection of very small programs that each do one thing well. The security principle I am talking about is containment. If any one program has a fatal flaw that can be attacked, the issue is contained to that one small area.
What do we gain?
- If the historic bug rate is 1/1000 to 1/3000 for a particular programming team then the goal is for any one program to contain less than 1500 lines of code. This means on average each program will only have 1 or 2 bugs.
- By designing each program to do one thing the the trust level and access rights the program requires can be minimized. If the operating system doesn't make available a capability; it cannot be used by an attacker.
How would this work?
I am currently designing and programming a web server that I call wput. My goal has been to prove the web server is secure by design before the first line of source code is written. When I release the program to the public it will contain a bounty of $1000 for any discovered bug that can exceed the access granted by the operating system configuration.
How can I do that?
Well, what does a program need to do to be considered a web server?
- Listen for requests from the network.
- Decode the request from a HTTP message to a resource request.
- (Optional)Determine who made the request (authentication.)
- (Optional)Determine if the request is allowed (authorization.)
- Complete the request.
- Encode the response into HTTP.
- Send the response across the network.
Thats 7 distinct things that have to happen. Going by my secure by design architecture that program needs broken down into multiple programs to be secure.
Network handler.
This program already exists e.g Inetd. Why make our own program when we can leverage an existing one with over 30 years of production use? By using a separate program, our code doesn't need to be network aware or even be configured to access the network. Containment: No bug will be able to access any other network connection or download code from some third party source. This alone makes wput more secure than any existing web server.
HTTP decoder/encoder
This is the bulk of what our program will need to handle.
Authentication/Authorization
Why reinvent the wheel? Let the host operating system do this.
Complete the request.
How can we avoid reinventing the wheel here? How about turning any HTTP request into a file system request? This leverages the host operating system to handle the request.
The plan
So wput needs to decode HTTP traffic and turn it into a file system request, pass that request to the host operating system file system to handle, and encode the response into a proper HTTP response. Much more simple than any current commercial web server, but can we design it to be even simpler?
libHTTP.
A simple library that can encode/decode HTTP formatted messages. The library will be HTTP 1.1 compliant and is nothing more than a text parser/formatter. This simple library can be used in any program that has to parse HTTP traffic such as web servers, network sniffers, etc.
wput
A simple program that accepts a few command line arguments, uses libHTTP to encode/decode messages, and only reads from standard input and writes to standard output. All requests are turned into operating system file access requests. The program runs as a completely untrusted user that only has explicitly granted file system access to the web files it can serve. It uses file permissions to determine if it should read or execute programs, or allow the web request to write to the file. A file permission denied message is turned into an authorization required web response. Any authentication HTTP headers are handed off to the operating system as login requests with a successful login causing wput to run as that user id.
So what can go wrong?
Even with a fatal bug that allows for the attacker to run code of its choice; the program is contained by the operating system to only have access to what it has been specifically granted. Because the network handler starts a new wput session per network request, the attacker cannot access another's session. All security controls are turned into configuration issues. Visible, audit-able, configuration issues.
I have glossed over many non security related benefits of the design that the thoughtful reader will discover.
The biggest complaint I expect is the expectation that my program will be slower than other web server designs. My answer when computer power doubles every 18 months; it makes more sense to buy bigger hardware than live with an insecure design.
0 comments:
Post a Comment