The Lessons of Software Monoculture
digitalsurgeon writes "SD Times has a story by Jeff Duntemann where he explains the 'Software monoculture' and why Microsoft's products are known for security problems. Like many Microsoft enthusiasts he claims that it's the popularity and market share of Microsoft's products that are responsible, and he notes that the problem is largely with C/C++ and mostly because of the buffer overflow problems."
Any compiled language is susceptible to security holes. The problem is that the process of turning source code into binary code is opaque to the developer. He puts some code through the compiler and some binary object code pops out. Things like memory offsets, code areas, data areas, and all these esoteric issues that need to be dealt with are simply left to the compiler to decide.
Unlike interpreted languages which for the most part implement all code as either line-by-line interpretation or in bytecode form, compiled languages talk directly to the CPU. Interpreted environments have the additional benefit that they run inside of a sandbox that is abstracted from the hardware by some large degree. Because of this, the running code never actually touches the CPU directly.
Things like the "no-execute" bit on modern CPUs provide an additional layer of security and prevent purposely damaged code from running directly on the CPU. However, until operating systems implement this in their own code, any application that does not want to adhere to the no-exec flag does not have to. This is like flock on Unix which only sets a file locking flag which applications are expected to obey rather than true file locking as implemented on other systems.
As a programmer, I feel the continual march of progress in computing has been hampered as of late because of a major misconception in some segments of the software industry. Some would argue that the process of refinement by iterative design, which is the subject of many texts in the field -- extreme programming being the most recent -- demonstrates that applying the theory of evolution to coding is the most effective model of program 'design'.
But this is erroneous. The problem is that while extremely negative traits are usually stripped away in this model, negative traits that do not (metaphorically) explicitly interfere with life up until reproduction often remain. Additionally, traits that would be extremely beneficial that are not explicitly necessary for survival fail to come to light. Our ability to think and reason was not the product of evolution, but was deliberately chosen for us. Perhaps this is a thought that should again be applied to the creation of software.
It makes no sense to choose the option of continually hacking at a program until it works as opposed to properly designing it from the start. One only has to compare the security woes of Microsoft or Linux with the rock-solid experience of OpenBSD for an example. It makes little sense from a business perspective as well; it costs up to ten times as much to fix an error by the time it hits the market as it would to catch it during the design. Unfortunately, as much of this cost is borne by consumers and not the companies designing buggy products, it's harder to make the case for proper software engineering -- especially in an environment like Microsoft where one hand may not often be aware of what the other is doing.
Don't be fooled into thinking open source is free of the 'monoculture' mindset, either. While it is perhaps in a better position to take advantage of vibrant and daring new concepts because of the lack of need to meet a marketing deadline or profitability requirement the types of holy wars one might have noticed between KDE/GNOME or Free Software/Open Source demonstrate that there are at least some within every community that feel they hold the monopoly on wisdom.
Try not. Do or do not, there is no try.
-- Dr. Spock, stardate 2822-3.
From netcraft:
Apache 67.92%
Sure... Minority Product.
Author obviously isn't the most impartial of writers.
I thought that's why Microsoft was pushing for "managed code" with the .Net framework. Though I think it's some what ripping the idea(s) from Sun's Java. But I'm sure even with .Net, there will still be buffer overflows. Well...the GDI+ exploit is one prime example of that fact.
An interesting distinction to make is that .NET code itself isn't vulnerable to buffer overflows. GDI+ is an unmanaged component (likely written in C++), and is vulnerable. The problem is that .NET exposes GDI+ functionality through its graphics classes, and since those classes are part of the .NET framework, .NET itself essentially becomes vulnerable to buffer overflows.
Microsoft appears to be shifting its APIs to the managed world, either as wrappers to legacy APIs, or new APIs built completely in the .NET world (or both as is the case with WinFX). So to expand on your post, as long as legacy code is used, yeah, buffer overflows will still be possible, but by shifting more code to managed world the likelihood of such vulnerabilities will hopefully diminish.
It's really not that hard to avoid buffer overflows in C/C++. It's not the fault of the language, but of the programmer. Obviously, avoiding buffer overflows is an added thing to think about when coding in C/C++, but I've worked with enough Java programmers to know that no language can compensate for a poor/ignorant programmer.
It's just an excuse, plain and simple.
That's kind of like ending up with a "null pointer" eh?
http://www.rootstrikers.org/
Except that the CLI doesn't solve this problem, it just makes avoidable (which it already was to begin with). A developer can still write code to do pointer arithmetic. BTW, what kind of brain damaged designer allows for pointer arithmetic in a garbage collected language?
Pointer arithmetic automatically makes the code unsafe (you actually use the 'unsafe' keyword in C#), and you have to compile it with an /unsafe switch. Resulting binaries are not verifiable by .NET, and you can prevent unsafe code from executing via code security. I can't run C# code that uses pointer arithmetic off a network share because of this.
The Lessons of Software Monoculture
by Jeff Duntemann
November 1, 2004 --
Last summer, much was made of Slate author Paul Boutin's harangue in his June 30, 2004 "Webhead" column. Boutin basically told his readers to drop Microsoft's Internet Explorer like a hot rock and move to Mozilla's Firefox, because of the increasingly nasty security holes turning up in IE. Problem is, Slate is owned by Microsoft.
Ouch.
It really has gotten that bad, and it's easy to be left with the impression that Microsoft creates lousy software, rotten with bugs that allow the black hats to break into our networks and bring the global Internet to its knees. The anti-Microsoft tomato tossers insist that if only Microsoft cleaned up its products, we'd be rid of the security holes and the black hats who thrive on them.
It's not that simple. Microsoft has some of the best programmers in the world working on its products, and books like "Writing Solid Code" from the Microsoft developer culture are seen as classics that belong on every programmer's shelf. Nonetheless, Microsoft software has bugs; all software has bugs, which is a crucial point that I'll return to later.
What we have to understand is that our current problems with Internet Explorer have less to do with bugs than with success. When a product has 90% of a huge worldwide market, there will be problems. It doesn't matter what the product is, and it matters only a little how good it is. What matters is that Internet Explorer is virtually the sole organism in an ecosystem that the world's technology industry depends on. When IE catches a cold, the networked world gets pneumonia.
This metaphor from biology is called software monoculture. Ubiquitous high-bandwidth communication has turned the world of computing from countless independent islands into a single global ecosystem. The fewer distinct organisms at work within this ecosystem, the easier it is for a bug--any bug--to become a threat to the health of the whole.
Worms and viruses that depend on these bugs replicate and travel automatically, and unless they can assume that the next system is identical (bugs and all) to the one they're leaving, they can't propagate as quickly nor do as much damage. If only one in 20 systems allowed such worms and viruses to take hold (rather than nine out of 10) it's doubtful that they could ever achieve any kind of critical mass, and would be exterminated before they got too far.
Software monoculture happens for a lot of reasons, only a few of them due to Microsoft's sales and marketing practices. In the home market, nontechnical people see safety in numbers: They want to be part of a crowd so that when something goes wrong, help will be nearby, among family, friends, or a local user group.
In corporate IT, monoculture happens because IT doesn't want to support diversity in a software ecosystem. Supporting multiple technologies costs way more than supporting only one, so IT prefers to pick a technology and force its use everywhere. Both of these issues are the result of free choices made for valid reasons. Monoculture is the result of genuine needs. Technological diversity may be good, but it costs, in dollars and in effort.
As if that weren't bad enough, there is another kind of software monoculture haunting us, far below the level of individual products--down, in fact, at the level of the bugs themselves.
If you give reports of recently discovered security holes in all major products (not merely Microsoft's) a very close read, you'll find a peculiar similarity in the bugs themselves. Most of them are "buffer overflow exploits," and these are almost entirely due to the shortcomings of a single programming language: C/C++. (C and C++, are really the same language at the core, where these sorts of bugs happen.) Virtually all software written in the United States is written in C/C++. This includes both Windows and Linux, IE and Firefox. A recent exploit turned up in Firefox that was almost identical to one
Obviously it's all the fault of C++... because no other vendor but Microsoft uses this obscure and arcane language...
It's odd to refute specific points of the article when its basic premise is flawed, but the one that applies is "all software has bugs". This is a defeatest attitude that is contradicted by the existence of formal methods for proving a piece of software to be bug free, and even of automatic theroem provers for showing software to be bug free (such as ACL2). This is the part that I was complaining about, and it is fair to criticise that without having to go into the finer points of the rest of the article.
To further expound on my original complaint, the article argues that microsoft's bad reputation is due to the popularity of its software, but this is only valid if it is impossible to make software better than Microsoft. The article seems to lean this way by stating that Microsoft has some of the smartest developers around working for it, but having the smartest developers doesn't mean that it produces the best code. Microsoft has earned its bad reputation by allowing so many bugs into such critical software like an Operating System.
The problem is that nobody writes perfect code.
Yes, we're all nerds, and we're all arrogant. We all like to act as if _our_ code is perfect, while everyone else is a clueless monkey writing bad code. _Our_ bugs are few and minor, if they exist at all, while theirs are unforgivable and should warrant a death sentence. Or at the very least kicking out of the job and if possible out of the industry altogether.
The truth however is that there's an average number of bugs per thousand lines of code, and in spite of all the best practices and cool languages it's been actually _increasing_ lately.
Partially because problems get larger and larger, increasing internal communication problems and making it harder to keep in mind what every function call does. ("Oh? You mean _I_ was supposed to call that parameter's range before passing it to you?")
This becomes even more so when some unfortunate soul has to maintain someone else's mountain of code. They're never even given the time to learn what everything does and where it is, but are supposed to make changes until yesterday if possible. It's damn easy to miss something, like that extra parameter being a buffer length, except it was calculated somewhere else. Or even hard-coded because the original coder assumed that "highMagic(buf, '/:.', someData, 80)" should be obvious for everyone.
And partially because of the increassing aggressiveness of snake oil salesmen. Every year more and more baroque frameworks are sold, which are supposed to make even untrained monkeys able to write secure performant code. They don't. But clueless PHBs and beancounters buy them, and then actually hire untrained monkeys because they're cheap. And code quality shows it.
But either way, everyone has their own X bugs per 1000 lines of code, after testing and debugging. You may be the greatest coder to ever walk the Earth, and you'll still have your X. It might be smaller than someone else's X, but it exists.
And when you have a mountain of code of a few tens of _millions_ of lines of code, even if you had God's own coding practices and review practices, and got that X down to 0.1 errors per 1000 lines of code... it still will mean some thousands of bugs lurking in there.
A polar bear is a cartesian bear after a coordinate transform.
Methodology matters.
I would agree with TFA if the author were comparing Internet Explorer 4 with, let's say, Netscape 6 or Opera 7. If he were, then I would whole-heartedly agree that IE is a victim of its own popularity and that software monocolture is an "evolutionary" reality mirrored in biological systems.
But...
There is a difference between how IE code gets written and how Mozilla code gets written. I'm not going to make any asinine qualitative comparisons between the skills of Mozilla contributors and MS staff (I respect both), but let's face it....
YOU know the difference between writing a commercial product with an unrealistic deadline, a list of new features four pages long (most of which are crap) and under the direction of non-technical managers who like Gantt charts and daily productivity reports and writing a project for your own self-satisfaction.
Mozilla code is written incrementally, with the goal of quality in mind, under public scrutiny (no peer review beats public scrutiny) and many of the contributors are doing it because they want to do it and want to do a good job. It's their pet project.
Compare the quality of code you write for work or in college under strict deadlines, and the code you write for fun.
- How many alternatives algorithms do you go through with each?
- Do you settle for "good enough" when you are writing code for yourself?
- Are you doing your own corner-case QA as well as you could be when you make that check-in into the company CVS when you know that QA will most likely test it (as an intern, I used to share a desk with QA guys, the catch is that they love to cut corners).
Not to mention endemic problems with large corporate projects of any type: corporate pride which prevents people from going back on bad decisions (ActiveX and IE security zones), lack of management support (how many top coders are still actively developing IE? any?), and all kinds of office politics. Many of these are avoided with well managed open source projects.
Cheers,
AC
BTW, what kind of brain damaged designer allows for pointer arithmetic in a garbage collected language?
Umm, one who knows that it is required for proper interoperability with existing libraries? One who knows more about language design than you?
The CLI actually isn't a "garbage collected language". First, it isn't a language - it is a language infrastructure (the LI in CLI). Second, garbage collection is available to the languages, but not required. It is a complete virtual machine, and straight C/C++ ports just fine to it, including all the buffer overruns.
However, there is a convention for "safe" programming. If you follow the convention, the assembly loader can verify that there are no buffer overruns or similar problems in your program. The price you pay is access to low-level constructs such as pointers, since their use cannot be verified.
Loading assemblies with unverifiable code is a privilege, which allows security to be maintained.
I think it all boils down to: the decision was the right one, it was well implemented, so stop talking about stuff you know nothing about.
What is ultimately interesting is that if IE was not as popular as it is, the bugs would still exist, and it would still be exploited. The only difference is that it wouldn't have the impact that it does now.
The interesting thing is that C/C++ is not to blame. C and C++ provide enough means to avoid buffer overflows as they do the means to create them. But in any software company, getting products out in time takes precedence over good code. That is the problem. The language used only changes the exploits and vulnerabilities available, not the fact that they exist.
The only way to reduce such security concerns is to change the culture in the software world.
C/C++ as a language has bugs.
Actually, any program has bugs.
IE and Firefox are both programs written in C/C++.
Therefore,
1. What is wrong with IE is wrong with Firefox
2. The quality of coding is mostly irrelevant to the quality of a program, it being mostly dependent (inversely) on how many people use it.
3. If Firefox gains market share, it will have bugs! It has to! You'll see!!
Listen to little brother crying...
I don't want to read
OpenBSD and OpenVMS are written in C. Qmail and djbdns are written in C.
Is it difficult to prevent buffer overflows? If you are reading a string, either use a string class, or read only as many characters as the character array can store. (What a novel idea!) If you are writing a string, among other things, set the last possible character of that string to null, just in case.
These are but single simplified examples, but it is not impossible by any means, or even all that difficult, to write solid code.
Among other things, the problem is that it takes individual effort to make sure every static-sized buffer isn't abused. As Murphy would tell you, human error is bound to crop up--increasingly so as the complexity of the project increases. I believe there was a post on the formula for this not too long ago.
As to the solution, well, that's a tough one. Higher level languages (Java, C#) help reduce these problems (and help reduce performance as well), but are just a band-aid. Perhaps the Manhattan Project (no, not that one) will come up with something better.
Until then, try to avoid products which have proven themselves to be full of holes year after year, week after week. And no, this doesn't just include all Microsoft server software. BIND and Sendmail come to mind.
Computer Science is no more about computers than astronomy is about telescopes. --E. W. Dijkstra
His argument, spelled out, seems to be:
Personally I find this argument to be quite baseless, and I'll believe it when I see it. Even if he is correct and Firefox might have as many bugs (because hey, it's written in C/C++), he doesn't seem to've provided any logical reasoning for people who are about to move to change their mind.
Even Jeff Duntemann admits that MSIE supposedly has at least as many bugs are Firefox. Given this reasoning, there's the choice between deploying MSIE (which is proven over and over again to be unsafe and full of security holes), and Firefox (for which nothing is proven).
It seems very shallow --- he's pitting something proven versus something unproven, and essentially claiming that we should assume they're both identically bad. I'll take my chances with Firefox, thank you very much. If everyone flocks to Firefox and it suddenly becomes a big security risk, I'll deal with it at the time.
Where the problem with Microsoft has got a lot more to do with their management forcing competitors products into the ground ensuring that they get those high 90s market share figures.
Microsoft is rather better known for poor security tactics.
The argument that it's some inherent flaw in C doesn't hold water, as it can be not only programmed around, but a multiple layer approach to security would as a minimum ensure that each bug found had limited damage, instead of the typical issue in MS products which is that a single hole will render the entire system to be a remote control for anyone on the Internet. This is the same for viruses on the windows platform, and part of the basic structure of how the OS handles commands sent between software. (Such as the famous trick to elevate your priviledges in 'secured' windows boxes.)
In the end, shipping an OS with just about every internet service and port open by default is not a fault in the C programming language. It's a filthy oversight.
The real problem isn't C bufferoverflows. It's Microsofts ultra-agressive stragetegy to purge every single piece of non-Microsoft software from the marked. During the browser wars, Microsofts one single aim was add more and more features to IE. Security, if at all, didn't matter a lot. What was important was to get another release as soon as possible. As long as Microsoft maintains it's hostile strategy, it will never produce any piece of software that can be considered safe. Not even if they'd switch to managed code entirely.
"A poor workman blames his tools"
The same old canard is being recycled again here... if only OS X, GNU/Linux, et al were more popular, they'd be plagued by security holes just like Windows. Anybody who's thought about this for more than ten seconds knows this is crap for a single reason: not all software coded in the same language (C-ish variants, in this case) is created equally. Some software is just designed badly.
Just as a f'rinstance, here are three aspects of Windows that show just how much design, not installed base, drives vulnerabilities:
None of these issues have anything to do with the language they were coded in. For that matter, they could have been done in .NET. But they do help explain how certain design choices have helped create the Windows Security Pandemic. That monoculture's one hell of a petri dish.
My point here is not to trumpet the marvelous advantages of OS X (or, say, Linux) over Windows. It is simply this: there is no Law that says that the number of vulnerabilities automatically increases with popularity but without regard to design. "Duntemann's Assertion" (aka Ballmer's Baked Wind) ain't like Moore's Law.
The article says that IE is exploited so often because it is so popular. If Mozilla were as popular as IE, would it be just as often exploited?
It would not.
There are several reasons, but the biggest one is that Microsoft added some major features without ever considering the security implications. IE can install software on your system; this means you can use IE to implement Windows Update, which is kind of cool, but it also means that an exploit can use IE to put worms and viruses on your system. Firefox and the other web browsers do not have special permission from the OS to install things. In short, Microsoft spent a great deal of time and effort to tangle IE into the system, and that means that compromising IE compromises the system.
Microsoft was well served, for years, by a focus on features. Word 2.0 could be Word 1.0 plus a hundred new features; no need to redesign, just paste the features on top. As long as the applications ran on unconnected computers, this wasn't particularly a problem. Then as networking became more important, they still got away with it because a corporate intranet is still a pretty tame environment.
But now Microsoft software is out in the wild and wooly Internet and it isn't pretty. Features that were harmless or even useful in a private corporate intranet became big problems: apps that auto-execute scripts; the "Windows popup" service; remote execution; file sharing; dozens to hundreds of features, little and big, that were pasted on without any worrying about security.
Microsoft employs tens of thousands of smart people. They will improve their software, eventually. They need to start designing security in, and they need to give their developers and testers time to get the security really right, rather than trying to patch all the holes after release.
P.S. I think that another reason the free software is usually better designed falls out from the fact that free software is usually the work of small teams. Microsoft can write big specs and then have large teams go to work on them; if the teams aren't careful, their work can be a tangled mess. The free software projects tend to have clean, modular interfaces; this is partly because so often different pieces are coded up by people who don't even know each other. Also, the free software community values good design and good code, while Microsoft values features developed and shipped on time. (Good design and good code help the features to work and to ship on time, but for Microsoft the shipping is what is important.)
steveha
lf(1): it's like ls(1) but sorts filenames by extension, tersely
"With something that has as many lines of code as Windows and IE, it's impossible not to miss at least one bug."
....a bug in which program, windows or IE?
The absolute insistence on the part of MS on integrating the browser (and shortly, the media player) into the operating system has bred this kind of exploits and vulnerabilities. I expect that it would be much easier to debug them if they were separate, an aspect that helps Firefox perhaps more than being Open Source.
One more thing about the article: his "darwinian" approach, by which the most popular program get the most vulnerabilites because they attract the most attacks, has two fallacies:
1.If it were true, Apache would be the most "vulnerable" server;
2. All programs below a certain circulation would be immune.
I have no insight on point 2, but strangely enough the more attacks are reported the more Apache market share grows. and when people are voting with their feet and money....
"If a boss demands loyalty, give him integrity. But if he demands integrity, give him loyalty." (John Boyd, 1927-1997)
In theory you are right, and better tools already exist. E.g., Java has array bounds checking by language definition. E.g., dunno abound Microsoft Visual C++, but I've used C compilers before which could generate code with array bounds checking. (TopSpeed C, for example.) It didn't even require any IDE macros, it just plain and simple generated them in the code automatically, if told to.
The problem however is that, well, no language or library ever can force you to stop making mistakes.
E.g., Java does throw an Exception if you try to overflow a buffer, but that's not an automatic magic talisman against bugs. You still can't let any ex-burger-flipper loose on the keyboard and say "nah, they can't have bugs or security problems. The language won't let them." What happens in practice is that:
1. People catch the exception and ignore it, on account that "it can't happen." Or even write "catch (Throwable t) {}" blocks. (Catch anything whatsoever and ignore without as much as a line in the log.)
2. Which in turn can make the program malfunction in more subtle ways. Even if you don't ignore exceptions is forgetting that the exception may have skipped some code. E.g., closing files or database handles is the most benign, in that it just causes the program to eventually run out of resources and crash.
A less benign case is when the code skipped was, for example, the login authentication. Carefully malformed data might not execute random code, but allow the user to escallate their rights to super-user.
And while a buffer overflow might have turned your machine into a spam zombie, this will instead give them all your business data on a silver platter. Nicely formatted, indexed and searchable too. And allow them to change it too.
3. In a twisted way, a secure language is the worst language because it causes complacency. Yes, it's a bit of an exaggeration, but bear with me while I make a point. Thinking "nah, we're secure because we use Java" (or SSL, or whatever) is the arch-nemesis of security. That way lies madness and skipping a real security analysis.
E.g., where I work, we had a failed project coded not by us but by a team of uber-expensive consultants from a BIG corporation. Utterly incompetent monkeys, but expensive consultants anyway.
It allowed a user to change their id to another user by merely editting the parameter in the URL. Since user id 0 was the super-admin, there you go, an easy way for everyone to escalate their privileges.
It also allowed anyone to access and _edit_ any data, including other users' data and passwords, again by simply editting the URL. Including, yes, changing the passwords for the admin and then logging in as admin.
It also allowed users to embed HTML text and even JavaScript in their text, which would be faithfully included in the page without quoting. Just in case you wanted to cause a JavaScript exploit or redirect to be displayed in other users' or admins' browser, you know.
What was worse, though, was that it didn't quote text used to build SQL statements either, basically allowing anyone to exploit the program into giving them all the data in the system. (If they didn't already get to it via the previous two exploits. As they say, three's a charm.)
Etc.
Again, personally I'd rate that as _worse_ than a buffer overflow. Attacking a company's own web programs via buffer overflows, and finding your way from there to the data, is something only a die-hard black-hat would do. Even ordinary script kiddies with rootkits won't bother doing much more than installing a spam zombie or warez/porn ftp server there. Whereas this presented an intuitive, menu-driven, user-friendly way to own a company's business data. And _change_ that data as you see fit.
In a nutshell, that's what happens when you start thinking that the language or libraries are a magic talisman. The moment you think "nah, we don't need a security analysis, because the holy Java will protect us"... that's when you are the most vulnerable.
A polar bear is a cartesian bear after a coordinate transform.
Aren't we simplifying things just a leetle bit here? Yes, monoculture is not good, because it creates the basis for a scenario of total failure, and C in the hands of the more witless sort of programmer can certainly be lethal (although, ANY language in the hands of a stupid programmer is a bad idea. Just look at the host of Visual Basic crap).
However, as far as I can see, by far the largest problem on the internet is the way Microsoft has built powerful programming capabilities into a number of their products, and the way things just happen automatically by default. Perhaps it is getting better, but only slowly. To illustrate: I work in an office where most users have Windows on their desktops, but I use Linux. We have had on average something like 3 or 4 major alerts about email worms per month in the last year, and it has affected everybody else except me. Is this because Windows is a monoculture and programmed in C? Or is it because Microsoft stupidly decided to build in functionality that supports these worms?
The truth is that no matter how many buffer overflows there may be in Linux, BSD etc, we are not likely to ever have problems with email worms - unless some idiot puts the necessary functionality in place.
Wrong. You do let arbitrary code download and run all the time.
Each time you go to a web site that uses JavaScript, guess what? You download and run arbitrary code. Interpreted code, yes, but arbitrary code nevertheless.
Each time you download a Java or Flash applet, even if just as an ad on a page, you are downloading and running arbitrary code. In Java's case even downloading and compiling it to binary code for your CPU.
As I've said before it would be possible to sandbox ActiveX to hell and back. Make it run in a virtual environment where it can't touch any files that it didn't create itself (e.g., a chroot jail), open any ports, or even call the OS methods without first going through a sanity checking layer.
Now Microsoft doesn't do that, and it's guilty as charged of bad design there. That much we can aggree upon.
But dismissing it all as "You simply don't allow arbitrary code to download and execute." is simplistic. And in fact it's over-simplified thinking like "Java=good, binary code=bad" is the arch-nemesis of security.
Real security doesn't involve mindlessly pinning magic talismans onto the code, nor repeating fashionable mantras. It involves a real security analysis. Who's going to attack us? How? What _can_ happen? How can we prevent that? Etc.
Again, obviously MS didn't do a real security analysis there. We can aggree on that. But that's no reason to assume that one can't possibly be done by anyone.
A polar bear is a cartesian bear after a coordinate transform.
While I really deeply respect J. D. (he wrote my first Pascal book, that pretty much put me on the structured programming track), I don't agree, and not with nyda either.
The bigger security problems of Microsoft software are three fold:
- indeed bufferoverflows are a C program, but most other OSes have this too.
- Microsoft is under hacker fire. True, but so is e.g. Apache, and that project has a much better trackrecord
- which brings me to the actual point: the main software development problem of Microsoft is the deep integration of systems, and the total unmanagable chaos as a result. Everything is integrated with everything.
P.s. C has a quite small and straightforward runtime, and this IMHO has a mitigating effect on C software development. The runtime is very predicatable, compared to e.g. JVM, CLR, and the various scripting languages
The only 'logical' way to eliminate buffer overflows was already know 30+ years ago: Don't make data areas executable!, that simple!
Now if after 30+ years, computer industry still is unable/uninterested to fix that simple problem, That's the real problem!
Stop blamming the tools (languages/etc) or the people (programmers/admins/etc), is the system stupid.
What's in a sig?
Well, use the unsafe keyword and you are entering buffer overflow land. but they go out of their way to make that hard to do, and mostly unneeded.
I know that Sun like to point to "unsafe" as a recipe for disaster, but every time you see the word "native" in Java, you know that they are binding to a potentially unsafe language, and in the same boat.
IMO, a move to managed languages will stop buffer overflows, and we should do it for all UI stuff and other apps where performance is not #1 priority. Which means most apps. Which particular language platform is another issue - C#, Java, Python, they all have their strengths.
2. Microsoft's Marketing - Yes, Microsoft are now a victim of their own lies as a result of convincing the public at large that their products are easy to use & maintain and that PCs never go wrong.
As an example, I just built a PC for a friend of mine who has never really worried about computers until it became apparent that her son needed Internet access to do some of his school homework. The sheer amount of information overload I had to give her was just frightening - update and run rhe virus checker regularly, update Windows regularly, update spyware programs regularly, don't use insecure passwords, don't duplicate passwords across different applications, etc. I ended up typing out 3 pages of hints and tips for her in the end.
3. User ignorance and greed - This follows on from 2. because far too many people have fallen for the Microsoft hype and have no clear understanding of how to keep themselves secure when on the Internet. Add to this that everyone wants something for nothing and the result is a whole heap of ignoramuses file-sharing all manner of nasty programs purely because they want their free music.
I don't care what anyone says but this will never happen with Linux. Linux will never be a mono-culture because the fact is that installing and using Linux automatically creates a learning curve meaning that anyone who uses it immediately starts becoming a more knowledgeable computer user. Sure, it takes a long time to become an expert but when you do, it is relatively easy to maintain a system to only run the services you need and to keep those updated. That's why viruses will never spread through a Linux user base because no two Linux machines are every entirely alike and because Linux users don't suffer from the same ignorance that plagues the Windows community.
I, for one, welcome it. I do not want inexperienced users flocking to use Linux purely because of the cool factor. The fact is that moving from Windows to Linux is like changing from being a child to an adult - the first step is to accept that you are responsible for your actions, not anyone else.
Gentoo Linux - another day, another USE flag.
How may of you can honestly say "I have never, ever created an interface without possibility to change expected behaviour"?
How may of you can honestly say "I have never, ever made a mistake while coding or designing program logic and flow"?
If you answered "I can" to all three you are lying!
That is the essence of secure software. We all make mistakes, including seasoned, paranoid veterans as myself. Some of us less others more, noone make NO mistakes. The more complex a system is the greater the risk of a fatal mistake...
The only way to make secure software is;
I agree, Raging Guppy. I have worked with C and C++ software in Linux, OS/2, and Windows environments for the longest time. I can appreciate the fact the author is trying to push... that C/C++, by their nature, allow the possibility for memory corruption and overruns that can be potential security breaches. I will remind you that Linux servers are used extensively and just as much as Microsoft servers in many cases, if not more. These servers are not vulnerable to the problsm that exist on the Microsoft platform. Microsoft has had YEARS to straighten out IE, but has failed to... in fact, the software gets worse as time goes on. It seems analogous to an old canoe with holes that keep popping up because of rotting wood... for how long can you keep patching it till all you have are patches keeping it together? While writing this, I got 3 IE popups come out of nowhere! I am not even using IE, nor have I ever, in the past 1 year. I use firefox, exclusively. Why is this firefox program already super-ceding my wildest (albeit lowered) expectations of IE? Why is Microsoft not improving on things that have existed as problems over the course of 3 or more different OS revisions? These are but many of the myriad of unanswered questions that Microsoft executives always avoid answering somehow.
You said:
> could not develop commercial quality software on the system since we were at the mercy of Sun for the language, the runtime, and everything els
And a bit later you said:
> Now a virtual machine architecture which supports JIT compiling to different architectures with a consistent set of class libraries and support for multiple different languages including C#, C++, Java, Visual Basic, Cobol, etc... that is useful.
Now the virtual machine and its tools etc still come from one provider, and oen that has a proven track record of screwing over everyone who develops a succesfull product based on its technology instead of from a company that at least has a track record of caring about its customers.
Pleaase tell me how that is better in any way? The multiple langauge support I guess.....
Oh, and you could of course point at mono... but that would mean you'd first have to accept that you can also get java from others then SUN, ie, try IBM, GNU, Blackdown (http://www.blackdown.org/).
It is possible to write bad code in any computationally-complete language. (Corollary: Any language which makes it actually impossible to write bad code is computationally incomplete).
It's also possible to write good code in a language that lets you write bad code. Perl has a bad {and IMHO undeserved} reputation, but there are two words that will keep you safe: use strict;
There is a reason why C does not implement bounds checking. It is because the creators of C assumed any programmer either would have the sense to do so for themself, or would have a bloody good reason for wanting to do it that way. It's like a cutting tool which will let you start the motor even without all the guards in place. For the odd, freak case where you have to do something the manufacturers never thought of, it might be necessary to do things that way {think, a really unusual shaped workpiece which fouls on the guard no matter which side you try to cut it from, but which is physically big enough that you can hold it with both hands well clear of any moving machinery; two arrays where you know, from reading the compiler source code, that they will be stored one after another in memory where b[0] just happens also to be referenceable as a[200]}. The fact that I can't think of a plausible situation off the top of my head certainly doesn't mean there isn't one.
Bounds checking as a matter of course would serve only to slow things down needlessly. Yes, the ability to exceed bounds can be abused. But you don't always need the check, and UNIX/C philosophy eschews performing any action without an explicit request. Sometimes the check is implicit. For instance, if you do a % or && operation, or are reading from a type such as a char, you already know the limits within which the answer must lie; so why need your programming language re-check them for you? And if you're only reading a value from an array and you don't actually set too much store by what comes out {maybe it's just some text you're presenting to the user}, then you could quite conceivably get away without doing any bounds-checking.
Powerful tools are by definition potentially dangerous, and inherently-safe tools are by definition underpowered. But that isn't the problem. The problem is that programmers today are being brought up on "toy" languages with all the wipe-your-arse-for-you stuff, and never learning to respect what happens when you don't have all the handholding in place.
Of course it's easier to blame the language, and more so when you are trying to sell people an expensive programming language that claims to make it harder to write bad code {and quite probably harder to write code that runs on anything less than 2GHz, but that's not your concern if you don't actually sell hardware}.
PS. It's my bold prediction that before "no execute" becomes a standard feature on every processor, there will be an exploit allowing stuff labelled NX to be executed. It requires just one clueless user somewhere in the world with access to a broadband line, and ultimately will royally screw over any software that depends on NX for correct operation. More in next topic to mention this particular red herring.
Je fume. Tu fumes. Nous fûmes!
he notes that the problem is largely with C/C++ and mostly because of the buffer overflow problems.
Most of the security problems that really turn into a bear with Windows aren't buffer overflows. They're layering problems. Windows doesn't have a strong distinction between different layers, it doesn't really have any internal security boundaries. It's got a complex privilege model that's wide open to privilege boosting, and applications have to be granted far too many privileges to do their normal operations... and because privileges can't be associated with applications that means a user has to be given all the privileges ANY application he uses will ever need. On top of that, "security zones" mean that if you can trick some component (the HTML control, of course) into thinking you're in the right zone it'll grant you full "local user" privileges and let you run any damn executable or script you want.
On the server side, there's all these spooky connections between application services and network services, so that you can't keep the system from leaving listening ports into important services open, and you can't firewall them off unless you want to shut down native network support completely.
THIS is the problem with Windows security. It's not just that it's a monoculture, it's a culture with security flaws baked into the APIs that can't be fixed without breaking applications.
People who build fault-tolerant systems start with the assumption that things will go wrong, and that includes software bugs and malicious injected code. Rather than trying to make faults never happen, an impossible task in practice, the system is designed to survive in the presence of faults, and minimise the damage they do. One of the key lessons from that work is that you create real boundaries around things, and prevent the faults crossing those boundaries. All Unix-like systems tend to have at least some kind of boundaries that are enforced, and it is relatively easy to tighten them up so that when things go bad, the damage does not spread too far or too fast.
These hard boundaries are also interfaces where you have to be explicit about how the pieces fit together, and so it is easy to substitute one implementation for another, and from a different supplier. Well defined boundaries make it hard to tweak the API to dislodge inconvenient competitors. Making everything deeply intertwined makes it hard for anyone to interface to your system without your permission, but those vital barriers to the propagation of faults go away.
We are never going to eliminate all faults, but there is a lot that can be done to reduce the damage they cause by using the right underlying system architecture and attitude to the overall system design. Robust design seems to require a significant degree of openness, and I think that this is where Windows is lacking.
Software problems generally exist because the specification was either nonexistant or poorly written, or the specification wasn't followed. Very rarely is it actual incompetance of a coder. But when a spec for a message handler, for instance, assumes that there will only be a certain length and nothing outside that spec guarantees that length, it's not the person coding that function to check for the length - s/he only has the spec by which to go (because people still haven't figured out how to not throw designs over the wall for implementation).
Complexity of a system does make things difficult, but good design mitigates a lot of problems. (Note I didn't say "eliminates" but "mitigates").
"There are a dozen opinions on a matter until you know the truth. Then there is only one." - CS Lewis (paraprhase)
"No, that's what happens when you employ clueless morons to write code for you."
You are, of course, right. We can aggree on that wholeheartedly.
However, it doesn't invalidate what I've said. You just detailed one effect of what I was basically saying.
The problem is that the moment someone actually believes "nah, we can't have bugs because we're protected by the holy power of Java" (or "we don't need good coders because Java/VB/whatever is easy to program"), they invariably go and hire the cheapest morons they can find.
It's not even a slippery slope argument. It's not a case of A slowly leading to B which leads to C which eventually leads to D. Here it's direct cause and effect. A straight short road from A to D.
Being able to write all their programs with 2 ex-burger-flippers paid $5 per hour is _the_ wet dream of the industry. So anything which promises to make that even remotely viable, _is_ in fact used as a justification to do just that: fire all those high paid nerds and hire the cheapest monkey in a suit.
Unfortunately, it doesn't work that way. No matter how easy the IDE, language or libraries make it to program, they can't force an untrained monkey to understand security, do a security analysis and write secure code. The less skilled people you can use to string together OCX controlls they don't understand in VB.NET (or Java, or whatever other language), the less clue they'll also have about making it secure.
And even if the language prevents them from having straight buffer overflows, they'll find other ways to make the program even more insecure. Because they don't even understand what they're doing.
So in a sick and twisted way, as I've said, the better tools you have, the poorer programs you end up with. Among other ways, yes, because the more clueless morons get hired to use those tools.
A polar bear is a cartesian bear after a coordinate transform.