In the last two weeks servers of Debian, Savannah and Gentoo have been compromised, as you probably noticed. And they won't be the last ones. Many people brag about the security of free software, but I have never seen a single technical reason why free server systems should be more secure. The only reason why there are fewer worms is that there's more fragmentation and the users are more experienced. It's easier for a worm to spread when 50% of the Internet's computer are binary compatible rather than only 0.1%. But when an attacker wants to attack a specific server, a Linux or OpenBSD server is not more secure than a Windows or MacOS server. This year there were exploits in the Linux kernel, Apache, OpenSSL, thttpd, MySQL, Samba, CVS, OpenLDAP, ProFTPd, Sendmail, PostgreSQL, Kerberos, rsync, CUPS, lsh and OpenSSH. Most of these exploits can be used by an attacker even without having an account on the server. In other words, you will hardly find a single server that has not been vulnerable for some time this year. Even worse, it's highly unlikely that those were the last exploits to be found, so you are still vulnerable after patching them. It's just a matter of time until an attacker finds the exploits.
So what can be done against it?
Right now the only strategy seems to patch the vulnerable package as soon as possible. This certainly improves security, but there is still a window for attackers in the time frame between the public discovery of the exploit and the time the system is actually patched. Even if all patches are applied immediately, they do not help when the exploit is only known to the attacker, like the Linux kernel root exploit used for the Debian hack.
The only way to solve it is to prevent the servers from having exploitable bugs. To achieve this you need to look at the root of most vulnerabilities: bad memory management and buffer overflows. While there are also some other types of bugs, the overwhelming majority of fatal vulnerabilities is caused by error-prone low-level memory management that is used in most free software - including all the packages mentioned above. They occur mostly in software written in C and, when you not making use of higher level tools, in C++. Higher level languages like Java, C# and most scripting languages make buffer overflows either impossible or very rare.
There are several approaches to make buffer overflows harder to exploit. Projects like PaX protect you from many overflow types, but not all. It has been tried to make the stack non-executable. Windows 2003 and OpenBSD are adding extra code that detects when the stack is overwritten. The problem is that there is a large number of ways to use a buffer overflow, and so far all protection mechanisms can be defeated. They can solve the problem for a short time, but as soon as one of them is in widespread use hackers will certainly find a way to circumvent it.
Another solution could be running insecure C code in a virtual machine, like valgrind does. That would kill all performance advantages of C, but at least it would be secure.
Otherwise there is only one conclusion, as ridiculous it may sound: all the C software needs to be rewritten. Experience shows that even security-conscious projects like OpenSSL and OpenSSH are not able to produce C code without a yearly remote exploit. So if you want a program without exploits, you need to rewrite it.
It is almost impossible to write secure, complex code in plain C. The only way to do this would be to refrain from using pointers and arrays, and to use secured functions for all low level operations. C should be banned for everything but the most low-level tasks, and algorithms that are relatively straightforward and performance-critical.
The risks of C++ are somewhat similar, with the important exception that C++ makes it very comfortable to avoid pointers and arrays. With the right core-library it is easy to write code that is as secure as Java, as long as you do not use the low-level operations that C++ inherited from C.
And the problem is not limited to servers. Network clients are security critical, because they may connect to a compromised server. All applications that load files are critical, because the user may have acquired the files from an untrusted source (or someone sent the file using the identity from a trusted person).
Today there's hardly any non-trivial application that can not be used to attack the system. And many of these applications will be written by inexperienced developers, or developers who do not think about security while writing the application.
Right now it seems like the only way to make free software truly secure is to (re-)write it in higher-level languages that make it easy to write secure code and difficult to write vulnerabilities.

Languages, new code
I completely agree that writing servers in this day and age in a language such as C is a bad idea. However, we also need to realize that not all security vulnerabilities come from the things that C is poor at, namely type safety, boundary checking and manual memory management.Temp file races, race conditions, information leaks, improperly implemented authentication or encryption schemes, file system traversals due to maliciously crafted paths, programmer assumption of well-formed data, etc... are not unique to any language. They are unique to people. With higher level languages it's also often much easier to exploit problems since they often allow the loading and running of code directly from a running process.
So while we should be writing our next generation of security minded software in languages such as Ruby (as one example), we need to remember they are not automatic safe havens.
Which leads to the problem with rewriting everything we do have. Not only would it mean a huge investment in manpower which we do not have (where "we" is the world in general; open source or closed), but it would mean raising the spectre of introducing new bugs. Most of the servers we rely on right now have had the biggest issues fixed. 2003 has not been anything like 1999-2001 for new security issues in free software, despite there being many more people looking into it. So I don't think rewriting everything over, now that we have a rather secure set of software (the hard way), is a good plan.
Languages, new code
Temp file races, race conditions, information leaks, improperly implemented authentication or encryption schemes, file system traversals due to maliciously crafted paths,
These issues are certainly not caused by programming languages, but most of them could have been solved by designing libraries with a focus on security.. The problem with temp file race is that on many platforms the easiest way to create a temporary file is the insecure way. When a authentication scheme like SASL is the easiest way to authenticate, no one would think of re-inventing it. And quite a lot of problems could be solved by avoiding that every second server comes with its own HTTP implementation...
Why the attacks were possible (and will slow down)
The attacks were actually the combination of two social factors. First, of course, the smuggling of passwords.
But the second social factor was not less important. Before the incidents one thought that a simple bug (even one in direct contact with memory) was not a showstopper. Had thought differently the bug would have gone directly to a security alert. As we know now this is not true. I don't think a mistake of this magnitude (oversee a quite dangerous bug as "not too dangerous") will happen again.
Oh, and of course migrating to a safer language may be a good idea, too. I'm sure tjansen will be giving us all the example by developing mostly in Ada from now on.
"Many people brag about the s
"Many people brag about the security of free software, but I have never seen a single technical reason why free server systems should be more secure."
If you are willing to accept that free == open source then:
The fact that the underlying source code is open to everybody. As the old saying goes "Given enough eyeballs, all bugs are shallow."
In addition to this, bugs found in open source software are usually made public immediately whilst bugs found in closed-source (M$FT) software are usually buried.
Just my $0.02
James
Given enough eyeballs...
The fact that the underlying source code is open to everybody. As the old saying goes “Given enough eyeballs, all bugs are shallow.
You are completely right abou
You are completely right about C. And the problem is not only security, it is also the high risk of failure due to bad code. A friend of mine had to stop the production of 300000 mobile phone because of C bug.
The problem is that we are still using a language with no basic checks about the security of operations. Ada for example is a lot more suitable for safe development. Everything is safe in Ada. It is heavy to write code with it, but an int is an int and does not become an enum or an unsigned int in other circumstances. If you go over the end of an array, if you mix two enum, if you downcast dangerously, the Ada compiler will stop you.
The other alternative is dynamically checked languages, which unfortunately are a lot slower. But so much safer. Java seems a really good contender for writing safe code, although I hate the language and its buzz.
Java's not so great :-/
The trouble with Java, is that the type checking, combined with exceptionally badly written base classes has the effect of confusing the coder. Naming of classes is bad; they act in unpredictable manners, and most certainly, not the way most experienced programmers expect. Moreover, due to this, bugs are hard to track down, and often, they are simply because the JFC has a different philosophy to the coder (this happens a lot, thanks to Java's bewildering range of 'frameworks' and 'models').
For the most part, Java's design forces programmers to spend their time working around lingual damage and fixing quirks. The "Why is it doing that? Why is it forcing me to do that?" problem.
Java's type checking would be great, if you didn't have to cast back and forth between types all the time to try and find a type that a class will take. Moreover, because in some places, the JFC coders have done strange things and missed out the use of the most logical data type, you have to build and maintain _interesting_ data structures to route around the problem, which by itself brings a wonderful potential for bounds errors.
My thoughts... Start with a language like C++, add a toolkit like QT and begin with a system which works as expected. If the coder wants to use a class in a particular way, it should work that way. QT is great for that; working intuitively, and not putting obstacles in the way when I want to do something simple, like open and read a text file.
Qt in these projects...
Hmm, do you really mean using Qt in these "the Linux kernel, Apache, OpenSSL, thttpd, MySQL, Samba, CVS, OpenLDAP, ProFTPd, Sendmail, PostgreSQL, Kerberos, rsync, CUPS, lsh and OpenSSH" projects?
All we need in these projects in something that prevents us from coding "bad memory management and buffer overflows". PaX is suggested, and to be honest I have way too little programming experience to help here.
I guess using C++ + aditional security measures would be a nice start, and offcource: extra security wont make it faster.
And reprogramming these project in an interpreted language would also be madness. If absolutely no-one should be able to get in, than you need: seperating tasks, very-heavy-firewalling, intrusion detection, dedicated securirty crew and programs without "bad memory management and buffer overflows".
Cies.
P.S.: I wouldnt be supprised if M$ would use all this 'news' on security issues against us... At least we admit it when it happened.
:)
I point was not that C++ and QT be used for everything, because patently there are some things that do need to be done with pure C and some pretty funky pointer work to really get good performance and certain desired results.
The thing is, if a strong toolkit can be used as a foundation for basic tasks, ensuring that the programmer doesn't have to worry about managing every data structure and file access in a secure way, it leaves the coder free to work on other things, safe in the knowledge that the basic, generic things, left to the toolkit are secure.
Many large projects still have flaws with incoming data overflowing data structures and strings. A good toolkit to organise those things would be able to reduce that. That's not to say that certain input might not run the program into a dicey logic process later, but the obvious things are covered.
Qt in these projects...
do you really mean using Qt in these “the Linux kernel, Apache, OpenSSL, thttpd, MySQL, Samba, CVS, OpenLDAP, ProFTPd, Sendmail, PostgreSQL, Kerberos, rsync, CUPS, lsh and OpenSSH