30-07-2009 09:31Two days ago a vulnerability was found in BIND 9, the latest version of the most commonly used domain name service engine on the Internet. Apparently, an attacker merely has to send a specific crafted nsupdate message to the zone for which a server is a master (the authoritative server), and the server will shut down if a certain type of record is already present on it.
Updates are already available, which is an excellent response, but this is not an isolated event. In August 2007, the previous version (8) of BIND was found to have a readily exploitable flaw in its random number generator - an essential function for ensuring the authenticity of DNS responses - that allowed the introduction of forged relationships between domain names and IP addresses into the caches that speed up address resolution. This was considered so serious that BIND 8 was retired. A month earlier a similar but less exploitable bug was found in BIND 9. In 2006 and 2007, bugs were found in BIND that could be exploited to crash the server.
As software goes, BIND actually seems to be pretty free of critical bugs - most OS and major applications have regular bug fix cycles measured in months or weeks. But the problem is nevertheless huge. The domain name service is the fundamental prerequisite for trust and connectivity on the Internet. Its integrity is the only guarantee that you land where you think you are going, and its availability is the only guarantee that you land anywhere at all. Without the assumption of integrity and availability of the domain name service, the Internet is unworkable - unless you know and choose to supply the IP address of the server you want to connect to on every occasion, which practically no user can be expected to do, particularly in the case of IPV6 addresses.
Given such a critical service supplied by a near-monoculture platform, the scale of the problem should be apparent to us all. Extortionists and phishers are quick to exploit these weaknesses, and there are indications that they are getting quicker and more efficient in doing so. There may come a point where trust in the domain name service becomes illusory.
So what's the way forward? Although a security layer for DNS (DNSSEC)has been around for some time, it only addresses the spoofing angle and does not protect against denial of service, which, in addition to its direct consequences, might hypothetically be used as a component of a spoofing attack - deny service on an authoritative DNS server and fire up a malicious substitute.
Furthermore, most of the identified exploitable vulnerabilities seem not to be in the protocols or mechanisms, but in their implementation - software bugs, i.e. flawed conversion of algorithms into code or, most often, actual coding errors such as failing to intialise variables or constrain buffer operations. Although some of the protocols on the Internet indeed lack robustness, it's the bugs that usually bring things to the floor first. So we need much higher quality code - not just in DNS, but across the board. That means much more attention to detail, and it means attention to detail at several levels of abstraction simultaneously. That's hard. It needs a certain kind of mind, possibly similar to the mind of a good chess player - or indeed a traditional systems engineer of the sort who works on large scale multi-technology projects.
The trouble is, we don't teach potential programmers to be engineers, or even to think like like engineers - we teach them a language and a library, and if they're at university and unlucky they get a module in recursion. But a programmer is not a person who knows a language - it's a person who can take an algorithm and convert it unscathed into a robust executable program. And a software developer is not necessarily a programmer. Equating the two is a big mistake. A software developer is an architect who converts an idea into algorithm or a set of algorithms. He or she may or may not be a programmer (a bricklayer, to continue the analogy). We need both, working together. But neither of these disciplines is taught - practically nobody is actively shown how to [a] convert a concept into a robust algorithm, [b] convert the algorithm into robust code that does not compromise the robustness of the algorithm, or [c] test the code exhaustively against unexpected input. Those are the skills that are needed, but they're so rare I frequently encounter "developers" who don't validate user input to web applications and can't handle the concept of retry lockout in login screens. They "wing it" instead, and if there isn't a method for X in their library, X does not get done.
Of course, the odd bug will always slip through the net because nobody can exercise perfect attention one hundred per cent of the time, but until the general standard of programming rises dramatically, the incidence of these critical vulnerabilities will not be minimised. And until they are, the Internet will continue to teeter on a knife edge as a platform for business and government - ready at any time to fail or misdirect the user. So we'd better get on with improving the quality of developer and programmer training, hadn't we?