buy cheap levitra cheap levitra online cheapest generic levitra levitra versus viagra order generic levitra online viagra cialis levitra online pharmacy levitra levitra for sale discount levitra levitra for women cheap viagra online cheap generic viagra female viagra cream viagra for women herbal viagra non prescription viagra generic viagra lowest prices buying viagra online order cheap viagra purchase viagra online
 

Chapter 6. Server Security

At a Glance

Server security is the security of the computer on which your Internet servers are running. This chapter discusses some of the most common security problems that affect computers being used to offer information services and describes how to build servers that minimizes these problems. This chapter discusses general host security first, and then application security issues for mail servers, file servers, web servers, database servers, and name servers.

Host Security

Many organizations that run servers on the Internet simply do not secure their servers against external attack. People still pick easy-to-guess passwords, and many passwords are simply “sniffed” out of the Internet using a variety of readily available packet sniffers.

Today there are literally thousands of organized and semi-organized groups of attackers—all exchanging information regarding computer vulnerabilities and exploits. Techniques, and in many cases complete programs for penetrating system security, are now widely distributed by e-mail, through newsgroups, on web pages, and over Internet Relay Chat (IRC). Tools for compromising security—password sniffers, denial-of-service exploits, and prepackaged Trojan horses—are distributed as well.

Attackers now use automated tools to search out vulnerable computers and, in some cases, to automatically break in, plant back doors, and hide the damage. High-speed Internet connections have made it possible for attackers to rapidly scan and attack millions of computers within a very short period of time.

The Honeynet Project (http://project.honeynet.org/) is an open Internet research project that is attempting to gauge the scale of the attacker community by setting up vulnerable computers on the Internet and seeing how long it takes before the computers are compromised. The results are not encouraging. In June 2001, for instance, the Honeynet Project announced that it took only 72 hours, on average, before somebody breaks into a newly installed Red Hat 6.2 system using one of the well-known exploits. A typical system on the Internet is scanned dozens of times a day. Windows 98 computers with file sharing enabled—a typical configuration for many home users—are scanned almost once an hour and typically broken into in less than a day. In one case, a server was hacked only 15 minutes after it was put on the network.

It’s tempting to approach host security as a checklist of do’s and don’ts for computers and networks. After all, to damage a computer, an attacker must have access. So in theory, to operate a secure system, all you need to do is to block all of the venues by which an attacker can get access, and the resulting system will be secure.

In practice, however, it has proved nearly impossible to have a computer that offers services over the network and yet still denies all access to attackers. Often access comes through unintended holes, such as a carelessly coded CGI script, or a buffer overflow attack that is known to the attacker but not the computer’s operators.

For more than a decade, there have been nine widespread practices on the Internet that make host security far worse than it needs to be. These practices are:

• Failure to think about security as a fundamental aspect of system setup and design (establishing policy)

• Purchase and configuration of computing systems based on issues of cost or compatibility rather than on the desired functionality and security needs

• Failure to obtain and maintain software that’s free of all known bugs and security holes

• Running unnecessary services

• Transmitting of plaintext, reusable passwords over networks

• Failure to track security developments and take preventative action

• Failure to use security tools properly, if they are used at all

• Lack of adequate auditing and logging (discussed in chapter 5-5)

• Lack of adequate backup procedures (discussed in chapter 5-3)

Security Through Policy

Security is defined by policy. In some environments, every user is allowed to install or modify the organization’s web pages. In others, only a few users are allowed to even read the pages. In some environments, any user can shut down or reboot the system. In others, it requires signed authorization from the CIO to so much as replace a file.

Policy helps users understand what is allowed. Policy guides administrators and managers in making choices about system configuration and use. Policy helps designers create systems that realize the organization’s goals. The most basic security policy is a clear statement of what actions are allowed and disallowed, and by whom. Standards and guidelines should include the answers to these questions:

• Who is allowed access, what is the nature of that access, and who authorizes such access?

• Who is responsible for security, for upgrades, for backups, and for maintenance?

• What kinds of information may be served?

• Which sites and external users are to be allowed access to data served?

• What kinds of testing and evaluation must be performed on software and pages before they are installed?

• How will complaints and requests about the server and content be handled?

• How should the organization react to security incidents?

• Who is allowed to speak to members of the press, law enforcement, and other entities outside the organization in the event of questions or an incident?

• How and when should the policy itself be updated?

Your policy documents should be written and made available to everyone associated with your organization. Care given to the development of the policy can head off lots of potential problems.

One often-overlooked policy issue is how to dispose of storage devices. The hard drives of your servers, your old backup tapes, and even your user workstations, may contain valuable and private data. In addition to protecting them from compromise while they are in operation, be sure you have a policy that provides for their sanitization or thorough destruction when they go out of operation. Sanitizing hard drives, for example, is surprisingly difficult.

Choosing Your Vendor

Today there are many choices for organizations setting up information servers. Should your computer run Windows, Mac OS, Unix, or a “free” Unix-like operating system? Should your computer system use an Intel-compatible microprocessor, or a SPARC, PowerPC, or another processor? Should you purchase the computer with or without support? What level of support is appropriate?

Many purchase decisions are based on factors such as the cost of the system, the reputation of the vendor, and the experience of the person making the purchase. Few organizations base their purchase decisions on the security of the underlying system.

Some vendors and platforms have better security pedigrees than the others, because different manufacturers value code quality and security differently. But the size of the user base also affects the security that a system will provide—even relatively secure systems can become “unsecure” in the face of a large number of well-funded adversaries who widely publicize their findings.

One of the biggest threats to the security of your system is the presence of software faults or bugs. These can cause your system to crash, corrupt your information, or, worst of all, allow outsiders unauthorized access. It is stunning to see how many organizations are willing to operate mission-critical systems on “beta” or “pre-beta” software releases.

As a large number of web sites are based on Windows NT running on Intel-compatible microprocessors, there is an incredibly high incentive for attackers to find vulnerabilities with this configuration.228 For this reason, some organizations have decided to deploy uncommon configurations—such as OpenBSD running on Solaris SPARC computers—simply because fewer attackers have experience with these systems. For example, if security is your primary concern in running a web server, consider running your web server on a Macintosh computer running the OS 7, OS 8, or OS 9 operating systems. Because these versions of the Macintosh operating system were not delivered with a command-line interpreter, it is extremely difficult for attackers to break into the system and run programs of their own choosing. They also don’t come with dozens of network services enabled that can be compromised. And Apple has a very good history of providing carefully written, apparently bug-free code.

While the underlying operating system is important, equally important are the applications and the customized software that are layered on top of this base. A secure underlying system can be made vulnerable by a single vulnerable script that was written by a consultant to provide additional functionality.

Some steps that you should follow before specifying and deploying a new system include:

• Determine which vendors have the best reputation for producing bug-free, well-documented software. Find out what specific measures your vendors use to assure high security—such as the security criteria that they employ, data flow analysis, code audits, and/or penetration testing. Ask the vendors for copies of their metrics and test evaluations from reviews. You might also check the historical trends associated with the discovery and reporting of security flaws in software by that vendor. One source may be found at

http://www.securityfocus.com/vdb/stats.html. (Because of the evolution in generally accepted methods of flaw discovery and reporting, we suggest that you don’t use figures before 1997 or so in your evaluation, as they may not be reliable.)

• Investigate how your proposed vendors respond to reports of security or performance-relevant faults in their products. Is your proposed vendor timely and open in dealing with problems? Some vendors have a history of ignoring users unless there is significant bad press from complaints or incidents. These vendors should be avoided.

• Explore the importance your vendor attributes to good design, with issues of security, safety, and user interfaces. Systems resistant to attacks and user mistakes are much better to use in situations where you need dependable operation.

• Determine whether your organization would be better off using “old-generation” software for which the problems are presumably well-known, or “leading-edge” software that offers new features.

• Choose the system with the least number of features that does what you want well. Hardware is relatively inexpensive: buying a system to devote to a reduced configuration for a web server (for example) may be a better purchase than a clone of one of your standard systems that results in a massive break-in.

Here are some things to request or require when shopping for software and systems:

228 There are other reasons why Microsoft products seem to be a favorite of attackers. These include the large numbers of vulnerabilities that keep being discovered, the complexity of the software which makes the software difficult for administrators to secure, and the simple fact that Microsoft is disliked by many people.

• Proof that good software engineering practices were followed in the design, coding, and testing of the software.

• Documentation showing the results of testing the software and system in environments similar to yours. Ideally, testing should include both operational testing and stress testing.

• A written statement of the vendor’s policy for accepting, documenting, and responding to reports of faults in the product.

• A written statement of how the vendor notifies customers of newly fixed security flaws. (The most responsible vendors release notices through FIRST teams and through customer mailing lists; the least responsible vendors never announce fixes, or bury them in lists of other bug fixes in obscure locations.)

• Examples of previous notifications and bug fixes.

Although the computer industry is beginning to take computer security seriously, no software vendor will warrant its products against losses related to unsecured code—not even the vendors of security products. A few insurance companies are now issuing policies to cover losses from break-ins and defacements of web sites. You should investigate these policies to see if there are different rates for different systems. As time goes on, rates should adjust to reflect the configurations that present less risk (and thus warrant smaller premiums).229

Obtaining and Maintaining Software

Once you have decided upon a vendor, hardware platform, and software, you need to install everything. Installation is an extremely important process. Frequently, mistakes made during installation can come back to haunt you after you have brought your system online and gone on to other projects. So take your time and be certain of what you are doing.

Conducting an inventory

Inventory all of your systems. Write down the serial numbers, the amount of RAM, the kinds of processors, option cards, and other hardware configuration options. Make sure that you have copies of this information in at least two locations—one easy way to do so is to type the information into a spreadsheet and e-mail a copy to yourself at home. This information will be useful for diagnosing performance issues. If you suffer a theft or loss, it will be useful for insurance purposes, too.

You should also inventory your software. For each product, note the vendor, the distribution, and the release. If you have software that comes with activation codes, it may be useful to record these as well. However, if you record the activation codes, you should attempt to secure them, because the distribution of activation codes could be considered software piracy by some vendors.

Be sure that you save all of the original packing material, documentation, blow-in inserts, and other information that comes with your computers and software. This can be critical if you are returning the equipment or need to relocate it. It is also surprising how many companies put vital information on seemingly innocuous printouts. Frequently, last minute inserts can be security or safety warnings, so be sure to at least glance at every piece of paper that you receive with your hardware and software.

Installing software and patches

Before you start to install the software for your computer, check the web site of each vendor to make sure you have all of the security patches and bug fixes for the version of the software that you intend to install. It is a good idea to read the release notes for both the base operating system and the patches. Some vendors distribute patches

229 As of late 2001, at least one insurance company charges higher premiums to customers using Windows and/or IIS as platforms.

that must be installed in a particular order—installing the patches out of order can sometimes result in security vulnerabilities being reintroduced!

If at all possible, you should disconnect your computer from the Internet at the start of the installation procedure and not connect it until you are finished. There are many recorded cases of computers connected to the Internet being compromised between the time that the computer’s base operating system was installed and the time that the patches were going to be installed. Unfortunately, it is increasingly difficult to install updates and register without software being connected to the Internet.

Once you have made sure that your computer is not connected to the Internet, install the computer’s base operating system, any operating system patches, then the application programs and the application patches. Keep a notebook and record every specific action that you take. Such a log can be immensely useful if you are going to be installing several computers and hope to delegate the activity to others.

At this point, before any further work is done, you should make a complete backup of the computer system. This backup will be invaluable if your computer is compromised by an attacker or a hardware failure. After your first backup is finished, you can make any local customizations that are required. You should then make a second backup of your computer system onto a different tape, CD, or disk.

Finally, make sure that all of the distribution software and the backups are stored in a place that is safe and will not be forgotten. Make sure that physical access to the computer is restricted. You may also wish to remove the floppy disk drive or CDs to make it more difficult for a person who has physical access for a brief period of time to compromise your server.

Minimizing Risk by Minimizing Services

An important way to minimize the threats to your server is by minimizing the other services that are offered by the computer on which the server is running. If you don’t need a service, disable it. By eliminating all non-essential services, you eliminate potential avenues through which an attacker could break into your system. One implication of this principle is that, when possible, you should separate services onto different computers: DNS servers, mail servers, web servers, file servers, etc.

Some services, such as finger, netstat, systat, and rwho, should be routinely disabled because they provide sensitive information to outsiders. Others, like chargen and echo can be used for denial of service attacks. Network services that transmit reusable unencrypted passwords, like telnet and (non-anonymous) FTP, or that authenticate users by IP address, like rlogin and rsh, should be disabled in favor of secure alternatives, like ssh or one-time password systems.

On a Unix server, you can easily restrict unneeded services by commenting out appropriate lines in inetd.conf. Another small handful of services that run as standalone daemons (portmapper is an example) can be eliminated in the “rc” files, found in the files /etc/rc and /etc/rc.local, and the subdirectories below /etc/rc.d, /etc/init.d, and /usr/local/etc/rc.d. You can also use TCP wrappers and host-based firewalls to control access to services, as described in chapter 5-6.

Disabling IP services with an NT or Windows 2000 system is a little trickier, because settings are sprinkled throughout the registry, and some services have to be functioning for the sake of NT. Many NT services can be audited and disabled using the Services control panel. The good news is that NT servers come with built-in access list capability. You can use this to prohibit all traffic to certain ports, and thereby achieve the same results as you would by shutting down services. (You can set IP filtering under the Control Panel’s advanced TCP/IP settings.)

Another variation on minimizing services is minimizing privileges. Servers that don’t have to run as the superuser or Administrator shouldn’t; those that must should give up superuser privileges as soon as possible if they can. In many cases, each different kind of server process should run with its own uid and group. Servers that can be restricted to a small area of the filesystem (using the chroot() or jail() system calls) should be.

Keeping Abreast of New Vulnerabilities

In today’s environment, you must stay abreast of newly discovered vulnerabilities if you wish to maintain a secure computer that is connected to the Internet. Vulnerabilities are usually publicized with breathtaking speed once they are discovered. What’s more, once a vulnerability is known, exploits are quickly developed and distributed across the Internet. In many cases, system administrators only have a few hours between the time that a vulnerability is first publicized and the time when they will start to be attacked with it.

Monitor bulletins issued by your vendors and that install security-related patches as soon as they are made available. Most vendors have mailing lists that are specifically for security-related information. Another source of information are FIRST230 teams such as the CERT/CC (Computer Emergency Response Team, Coordination Center) at the Software Engineering Institute. The CERT/CC collects reports of computer crime, provides the information to vendors, and distributes information from vendors regarding vulnerabilities of their systems. Because CERT/CC and many other response teams do not make information available in a timely fashion, however, don’t depend on them as your primary information source.

As a backup, you might also subscribe to one or two of the security-related mailing lists, such as nt-security, bugtraq, and firewalls.

Using Security Tools

A security tool is a special program that you can run to evaluate or enhance the security of your site. Many security tools that are available today were developed at universities or by independent specialists and are freely distributed over the Internet. There are also several good tools that are marketed commercially.

There are five kinds of tools that you should consider using:

• Tools that scan your system for potential weaknesses that a local user could exploit

• Tools that monitor your system over time, looking for unauthorized changes (see Chapter 5, Auditing and Forensics for complete discussion)

• Tools that scan your network, looking for network-based weaknesses

• Tools that monitor your system and network to identify attacks in progress

• Tools that record all network activity for later analysis

Automated tools are (usually) a low-cost, highly effective way to monitor and improve your system’s security. Some of these tools are also routinely employed by attackers to find weaknesses in sites around the Internet. Therefore, it behooves you to obtain your own tools and use them on a regular basis.

Snapshot tools

A snapshot or static audit tool will scan your system for weaknesses and report them to you. For example, on your Unix system a tool might look at the /etc/passwd file to ensure that it is not writeable by anyone other than the superuser. Snapshot tools perform many (perhaps hundreds) of checks in a short amount of time.

230 Forum of Incident Response and Security Teams, the worldwide consortium of major computer incident response groups. Visit http://www.first.org for more information.

An up-to-date Unix snapshot tool is Tiger, from Texas A&M University. Tiger runs on a wider variety of operating systems and is easy to install. Several packages are available in the Windows world. The Kane Security Analyst (KSA) from Intrusion Detection, Inc. (http://www.intrusion.com/) will check passwords and permissions (ACL), and monitor data integrity. NAT is a free tool for assessing NetBIOS and NT password security made available by Security Advisors (http:// www.secnet.com). Two tools for checking NT passwords are ScanNT, written by Andy Baron (http://www.ntsecurity.com/Products/ScanNT/index.htm), and L0pht Crack, by the “computer security researchers” at L0pht Heavy Industries (now part of @Stake).

A snapshot program should be run on a regular basis—no less than once a month and probably at least once a week. Carefully evaluate the output of these programs, and follow up if possible. Don’t leave the output from a snapshot security tool in a place that is accessible to others: by definition, the holes that they can find can easily be exploited by attackers.

Network scanning programs

These tools check for well-known security-related bugs in network programs such as sendmail and ftpd. Your computers are certainly being scanned by crackers interested in breaking into your systems, so you might as well run these programs yourselves. Among the most powerful freely available tools for Unix operating systems is Nessus (http://www.nessus.org). SomarSoft (http://www.somarsoft.com) offers several tools for analyzing information culled from Windows NT logs and databases. KSA, mentioned above, also provides analysis and integrity checking for NT environments. Another powerful scanning program is nmap (http://www.insecure.org/nmap), which scans for open network ports, can map networks, and can often identify the operating system of a computer by its responses to network scans.

Intrusion detection systems

Intrusion detection system (IDS) programs are the operating system equivalent of burglar alarms. As their name implies, these tools scan a computer as it runs, watching for the tell-tale signs of a break-in.

Intrusion detection systems can either be host-based or network-based. A host-based system looks for intrusions on that particular host. Most of these programs rely on secure auditing systems built into the operating system. Network-based systems monitor a network for the tell-tale signs of a break-in on another computer. Most of these systems are essentially sophisticated network monitoring systems that use Ethernet interfaces as packet sniffers. An example of a sophisticated free network IDS is Snort (http://www.snort.org).

Virus scanners

There is a huge market for antivirus tools in the Windows environment. When choosing antivirus software, consider not only the product’s features, but what kind of support it provides for updating the list of viruses that it can recognize. Many commercial virus scanners use a subscription model, in which you can download weekly updates to the virus engine as long as you maintain a subscription.

Antivirus tools are not needed for Unix or Linux systems—there are only three or four reported viruses for these platforms, and they do not spread well. An integrity monitor (such as Tripwire) will also perform any antivirus function needed on these platforms as a side-effect of the way it works. Similarly, older Mac OS systems primarily need antivirus tools to combat macro viruses in Microsoft Office products.

On the other hand, a Unix-based mail server can serve as an antivirus gateway to protect Windows mail clients. Several antivirus engines detect Windows viruses but run on Unix machines for just this purpose.

Network recording and logging tools

Network recording and logging tools record all of the traffic that passes over a network, preserving it for retrospective analysis. These systems are typically run on computers with large disks. (An 80-gigabyte hard disk, for example, can store nearly two weeks of typical traffic sent over a T1 line.) In the event of a break-in or other incident, the recorded traffic can be analyzed.

Securing Mail Servers

Mail servers are often the most important servers in any organization. When mail servers are down, a major communication link between the organization’s clients, vendors, and employees is severed. When mail servers are compromised, private and confidential information is quickly exposed. Although the usual host security measures apply to mail servers, several special considerations arise.

Choosing a Mail Transport Agent

The mail transport agent (MTA) is the software that is responsible for receiving and relaying e-mail. At one end, it communicates with mail user agents that connect to the transport agent to send e-mail. At the other, it communicates with mail delivery agents that perform the final delivery of e-mail to its destination. An MTA must be properly configured so that it will accept mail to and from the proper users and no others.

For Unix-based mail servers, the leading MTAs include sendmail, postfix, qmail, and exim. Sendmail is the oldest, best known, and most widely used MTA; it also has the worst security record, in large part because it was designed at a time when the Internet was young and performance was more important than security. Postfix, qmail, and exim, on the other hand, were designed from the start with security in mind. If you make one security-related decision for your mail servers, it should be to run something other than sendmail; if you must run sendmail, read its extensive documentation carefully, as well as the O’Reilly and Associates Sendmail book, and be paranoid about configuration. Both postfix and exim can replace an existing sendmail-based system fairly painlessly.

Windows-based mail servers may use such MTAs as Imail or Microsoft Exchange Server. Historically, Windows MTAs have not done a good job of complying with Internet standards, and have only a mediocre security record.

Spam

Unsolicited commercial e-mail (commonly referred to as “spam”) has become a pervasive and costly problem. When providing e-mail services, it is imperative to insure that neither outsiders nor authorized users can use your systems to send spam.

Controlling access by outsiders is relatively easy if you use current versions of your MTA software. All major MTAs now come with default configurations that will cause them to refuse to relay e-mail unless it’s destined for a local user or sent by a trusted machine. A “trusted machine” usually means a machine with a given IP address (which is only trustworthy when the machine is inside the perimeter of a firewall that prevents IP spoofing), but can also mean a machine that can authenticate itself to the server cryptographically.

Cryptographic authentication is often used by mail clients on laptops or other machines that receive their IP addresses dynamically. One widely-used approach is the SMTP AUTH protocol, an extension of SMTP that provides for

authentication using one of the mechanisms in the Simple Authentication and Security Layer described in RFC2222. Another is to issue TLS client certificates to clients and use the STARTTLS extension to authenticate them.231

Insiders who send spam can inundate your organization’s network bandwidth and can quickly damage your reputation or even leave you open to legal action.232 A key control on spam by insiders is to insure that they can only send outgoing mail through mail servers that you control and monitor. An effective way to do this is to block outgoing connections to TCP port 25 (the SMTP service’s port) at your firewall, and then only allow your mail servers to make such connections.

Confidentiality and Integrity

Most MTAs can be configured to allow (or require) TLS-encrypted connections. The SMTP protocol has been extended to include a STARTTLS operation that initiates a TLS handshake in the SMTP dialogue. Using TLS is highly recommended, as it protects both the confidentiality and integrity of the messages “on the wire”, as well as offering additional assurance that the client is connecting to the authentic SMTP server it expects.

Similarly, if you provide POP or IMAP mailbox service to your users, most current POP/IMAP clients can make SSL/TLS encrypted connections to your POP/IMAP server, if you configure it to accept (or require) them. Because these protocols, by default, transmit passwords without encryption, requiring SSL/TLS connections provides significant protection for the user as well as their messages.233

Another alternative to unencrypted POP/IMAP service is to provide users with access to their e-mail through their web browser by using a “webmail” system. A major advantage of webmail is that the web server can be secured by SSL/TLS, and all web browsers are capable of taking advantage of the secure connection.

Securing Anonymous FTP Servers

The FTP protocol presents several problems to system administrators – so many, in fact, that the best practice today is not to run an FTP server at all. Instead, allow outsiders to download files through a web server, and require insiders to transfer files using scp or sftp (part of the ssh suite) or SSL-secured Web-DAV.

If you must run an anonymous FTP server to permit outsiders to download or upload files, follow these guidelines:

• Carefully read your FTP server’s documentation for how to properly set up the anonymous file area so that anonymous users can only download from directories you specify and cannot delete files, rename files, or modify directory structures.

• Avoid providing convenience executables like compression or archive programs that might have exploitable vulnerabilities. On Unix systems, if your FTP server provides its own directory display functionality, don’t even provide an ls executable.

• If your FTP server uses a password file to associate the uids of file owners with their login names, don’t use your server’s actual password file. Instead, make a dummy file that lists only the information you must (or don’t use a file at all and let clients see uids).

• If you allow file uploads, allow them in separate directories from the download directories, and be sure that users cannot download the uploaded files. This prevents your FTP site from being used to traffic in illegal software or other files. You should also insure that uploaded files cannot have special characters in their filenames and that the upload area is on a separate disk partition to prevent a denial of service attack through overflowing the disk.

231 Another popular, if less inherently secure, approach is POP-before-SMTP. In this approach, clients must first check their e-mail via POP, which records their IP address. The SMTP server then allows relaying from the recorded IP addresses for a limited time. This approach can be convenient, but is less secure unless the POP connection is itself encrypted.

232 In fact, the huge amount of spam that originates from countries with ineffective legal remedies has significantly damaged the reputation of entire nations to the degree that many mail administrators routinely refuse any e-mail originating from these countries.

233Both POP and IMAP do support authentication mechanisms that don’t transmit unencrypted passwords on the network, but most of these are more tedious to enable than SSL/TLS, and don’t provide the privacy or integrity protection of message encryption.

Don’t provide non-anonymous FTP service at all unless you can protect it with a VPN tunnel or a cryptographic wrapper like SafeTP (http://safetp.cs.berkeley.edu).

Securing Web Servers

When it comes to serving web pages, the general rules of server security apply. Choose an operating system and a web server application with a good security philosophy and a good security record. Carefully read the web server’s documentation, particularly around security issues. Disable any guest logins and limit the number of users with accounts on the web server to those who require them. Disable administrative logins from the network. On a Windows system, if you must administer the server remotely, change the name of the “Administrator” account to something more difficult to guess. On a Unix system, disable root logins and require users to use the su program for administration.

There are, however, several security issues specific to running web servers. Most notable are data confidentiality, server-side scripting and content updating.

Data Confidentiality

If you will be transmitting sensitive information, get an SSL certificate and use an SSL-enabled web server (both Apache and IIS can be configured to use SSL). If you’re designing an intranet application (or an Internet application that’s restricted to your clients or employees), you can use a self-signed SSL certificate or set up your own certificate authority. Otherwise, you’ll probably need to invest in SSL certificates from a well known certificate authority like VeriSign, whose signing certificate is bundled with major web browsers. See chapter 5-4 for more information about SSL certificates.

If you don’t use SSL, the entire HTTP transaction occurs unencrypted, including the usernames and passwords used in “basic” HTTP authentication and any form fields that the client transmits. In most cases, if you plan to authenticate the user you should implement SSL to protect the transaction.

Server-Side Scripting

Web servers are fine programs for displaying static information such as brochures, FAQs, and product catalogs. But applications that are customized for the user or that implement business logic (such as shopping carts) require that servers be extended with specialized code that executes each time the web page is fetched. This code most often takes the form of scripts or programs that are run when a particular URL is accessed. There is no limit to what a good programming team can do with a web server, a programming language, and enough time. Unfortunately, programs that provide additional functionality over the Web can have flaws that allow attackers to compromise the system on which the web server is running. These flaws are rarely evident when the program is run as intended.

There are four primary techniques that web developers can use to create web-based applications:

CGI

The Common Gateway Interface (CGI) was the first means of extending web servers. When a URL referencing a CGI program is requested from the web server, the web server runs the CGI program in a separate process, captures the program’s output, and sends the results to the requesting web browser. Parameters to the CGI programs are encoded as environment variables and also provided to the program on standard input.

CGI programs can perform database queries and display the results, allow people to perform complex financial calculations, and allow web users to “chat” with others on the Internet. Indeed, practically every innovative use of

the World Wide Web, from web search engines to web pages that let you track the status of overnight packages, was originally written using the CGI interface.

Plug-ins, loadable modules, and Application Programmer Interfaces (APIs)

The second technique developed to extend web servers involved modifying the web server with extension modules, usually written in C or C++. The extension module was then loaded into the web server at runtime. Plug-ins, modules, and APIs are a faster way to interface custom programs to web servers because they do not require that a new process be started for each web interaction. Instead, the web server process itself runs application code within its own address space that is invoked through a documented interface. But these techniques have a distinct disadvantage: the plug-in code can be very difficult to write, and a single bug can cause the entire web server to crash.

Embedded scripting languages

Web-based scripting languages were the third technique developed for adding programmatic functionality to web pages. These systems allow developers to place small programs, usually called scripts, directly into the web page. An interpreter embedded in the web server runs the program contained on the web page before the resulting code is sent to the web browser. Embedded scripts tend to be quite fast. Microsoft’s ASP, PHP, server-side JavaScript, and mod_perl are all examples of embedded scripting languages.

Embedded web server

Finally, some systems do away with the web server completely and embed their own HTTP server into the web application itself.

Largely as a result of their power, the extension techniques enumerated here can completely compromise the security of your web server and the host on which it is running. That’s because potentially any program can be run through these interfaces. This includes programs that have security problems, programs that give outsiders access to your computer, and even programs that change or erase critical files on your system.

Two techniques can limit the damage that can be caused by web applications:

• The programs themselves should be designed and inspected to ensure that they can perform only the desired functions.

• The programs should be run in a restricted environment. If these programs can be subverted by an attacker to do something unexpected, the damage that they could do will be limited.

On operating systems that allow for multiple users running at multiple authorization levels, web servers are normally run under a restricted account, usually the nobody or the httpd user. Programs that are spawned from the web server through either CGI or API interfaces are then run as the same restricted user.234

Unfortunately, other operating systems do not have the same notion of restricted users. On Windows 3.1, Windows 95/98/ME, and the Mac OS 7–9 operating systems prior to Mac OS X, there is no easy way for the operating system to restrict the reach of a CGI program.

Programs That Should Not Be CGIs

Interpreters, shells, scripting engines, and other extensible programs should never appear in a CGI scripting directory (e.g. cgi-bin), nor should they be located elsewhere on a computer where they might be invoked by a request to the web server process. Programs that are installed in this way allow attackers to run any program they wish on your computer.

234 In a multiuser environment, such as a web server at an ISP or a university, it is common practice to use the cgiwrap script so that CGI programs are run with the author’s permissions, rather than with the web server’s.

For example, on Windows-based systems the Perl executable PERL.EXE should never appear in the CGI script directory. It is easy to probe a computer to see if it has been improperly configured. To make matters worse, some search engines can be used to find vulnerable machines automatically. Unfortunately, many Windows-based web servers have been configured this way because it makes it easier to set up Perl scripts on these servers. Another source of concern are programs or scripts that are distributed with web servers and later found to have security flaws. Because webmasters rarely delete programs that are part of the default installation—it can be quite difficult to find out if a script is in use or not—these dangerous programs and scripts may persist for months or even years, even if new versions of the web server are installed that do not contain the bug.

To protect yourself from programs, scripts, and CGIs in which security faults may be later discovered, move all of the programs that are installed by default with your web sever into a directory where they cannot be accessed, and only restore the programs when they are specifically needed.

Unintended Side Effects

Security problems in scripts can remain dormant for years before they are exploited. Sometimes, obscure security holes may even be inserted by the programmer who first wrote the scripts—a sort of “back door” that allows the programmer to gain access in the future, should the programmer’s legitimate means of access be lost. In other cases, the security hole is the result of an unintended side effect of the script.

Unintended side effects can often be prevented by distrusting any input that comes from outside of the program – from a user’s entries in a web form, from environment variables, from cookies, or anywhere else. Any outside input should be filtered to extract only legal characters, and then checked to insure that it is sensible.

It’s important to design filters that filter in a list of acceptable characters and reject all others, rather than rejecting a list of bad characters and accepting all others. The former approach is much more secure, as it can be difficult to anticipate all of the possible bad characters (and some characters that aren’t bad now may one day become so!) For example, many older applications did not anticipate the possible of Unicode characters.

See chapter 16 of Garfinkel’s Web Security, Privacy, and Commerce, 2nd Edition for more examples of unintended side effects.

General Principles for Writing Secure Scripts

The principles below represent the current best practices for writing shell scripts:

1. Carefully design the program before you start. Be certain that you understand what you are trying to build. Carefully consider the environment in which it will run, the input and output behavior, files used, arguments recognized, signals caught, and other aspects of behavior. List all of the errors that might occur, and how your program will deal with them. Write a code specification in English (or your native language) before writing the code in the computer language of your choice.

2. Show the specification to another person. Before you start writing code, show the specification that you have written to another programmer. Make sure they can understand the specification and that they think it will work. If you can’t convince another programmer that your paper design will work, you should go back to the design phase and make your specification clearer. The time you spend now will be repaid many times over in the future.

3. Choose a scripting language that provides safety features for CGI scripting and that prevents buffer overflow errors. Perl, python, and Ruby are good choices. C and C++ are generally a poor choice. Never write CGI scripts for a shell interpreter like /bin/sh.

4. Whenever possible, reuse code. Don’t write your own CGI library when you can use one that’s already been debugged. But beware of reusing code that contains Trojan horses.

5. Write and test small sections at a time. As you start to write your program, start small and test frequently. When you test your sections, test them with both expected data and unexpected data. Where practical, functions should validate their arguments and perform reasonable actions (such as exiting with an error message or returning an error code) when presented with unreasonable data. A large number of security-related programs are simply bugs that have exploitable consequences. By writing code that is more reliable, you will also be writing code that is more secure.

6. Check all values provided by the user. An astonishing number of security-related bugs arise because an attacker sends an unexpected value or an unanticipated format to a program or a function within a program. A simple way to avoid these types of problems is by having your scripts always check and validate all of their arguments. Argument checking will not noticeably slow your scripts, but it will make them less susceptible to hostile users. As an added benefit, argument checking and error reporting will make the process of catching nonsecurityrelated bugs easier.

7. Check arguments that you pass to operating system functions. Even though your program is calling the system function, you should check the arguments to be sure that they are what you expect them to be. For example, if you think that your program is opening a file in the current directory, you might want to use the index() function in C or Perl to see if the filename contains a slash character (/). If the file contains a slash, and it shouldn’t, the program shouldn’t open the file.

8. Check all return codes from system calls. The POSIX programming specification (which is followed by both C and Perl) requires that every system call provide a return code. Even system calls that you think cannot fail, such as write(), chdir(), or chown() can fail under exceptional circumstances and return appropriate return codes. When a call fails, check the errno variable to determine why it failed. Have your program log the unexpected value and then cleanly terminate if the system call fails for any unexpected reason. This approach will be a great help in tracking down both programming bugs and security problems later on.

9. Have internal consistency-checking code. If you think that a variable inside your program can only have the values 1, 2, or 3, check to ensure that it does, and generate an error condition if it does not. (You can do this easily using the assert macro if you are programming in C.)

10. Include lots of logging. You are usually better off having too much logging rather than too little. Rather than simply writing the results to standard error, and relying on your web server’s log file, report your log information to a dedicated log file. It will make it easier for you to find the problems. Alternatively, consider using the syslog facility (under Unix), so that logs can be redirected to users or files, piped to programs, and/or sent to other machines.

11. Make the critical portion of your program as small and as simple as possible.

12. Always use full pathnames for any filename argument, for both commands and data files. Rather than depending on the current directory, set it yourself.

13. Be aware of race conditions. These can be manifest as a deadlock or as failure of two calls to execute in close sequence:

Deadlock conditions

Remember that more than one copy of your program may be running at the same time. Use file locking for any files that you modify. Provide a way to recover the locks in the event that the program crashes while a lock is held. Avoid deadlocks or “deadly embraces,” which can occur when one program attempts to lock file A and then file B, while another program already holds a lock for file B and then attempts to lock file A.

Sequence conditions

Be aware that your program does not execute atomically. That is, the program can be interrupted between any two operations to let another program run for a while—including one that is trying to abuse yours. Thus, check your code carefully for any pair of operations that might fail if arbitrary code is executed between them. In particular, when you are performing a series of operations on a file such as changing its owner, stating the file, or changing its mode, first open the file and then use the fchown(), fstat(), or fchmod() system calls. Doing so will prevent the file from being replaced while your program is running (a possible race condition).

Also avoid the use of the access() function to determine your ability to access a file: using the access() function followed by an open() is a race condition, and almost always a bug.

14. Don’t have your program dump core except during your testing. Core files can fill up a filesystem. Core files can contain confidential information. In some cases, an attacker can actually use the fact that a program dumps core to break into a system. Instead of dumping core, have your program log the appropriate problem and exit. Use the setrlimit() function to limit the size of the core file to 0.

15. Do not create files in world-writable directories. If your script needs to run as the nobody user, then have the directory in which it needs to create files owned by the nobody user. Give each script, or at the very least each subsystem, its own namespace for temporary files. (You can do this by giving each script its own directory for temporary files, or else by having each script prepend its temporary files with its own name.) Do not store temporary files in the /tmp directory if the web server is also used as a general host for Unix shell activities.

16. Don’t place undue reliance on the source IP address in the packets of connections you receive. Addresses may be forged, altered, or hijacked with proxy servers.

17. Include some form of load shedding or load limiting in your server to handle cases of excessive load. For example, you can have the script check the load and exit with a polite error message if the load is over 5. This will make it harder for an attacker to launch a denial-of-service attack against your server by repeatedly calling the same script. It will also protect your server from a failure mode if hundreds of users all hit the “reload” button on a slow-running script in an effort to make it run faster.

18. Put reasonable time-outs on the clock time used by your script while it is running. Your program may become blocked for any number of reasons; for example, a read request from a remote server may hang or the user’s web browser may not accept information that you send to it. An easy technique to solve both of these problems is to put hard limits on the amount of real time that your CGI script can use. Once it uses more than its allotted amount of real time, it should clean up and exit. Most modern systems support some call to set such a limit.

19. Put reasonable limits on the CPU time used by your CGI script while it is running. A bug in your CGI script may put it in an infinite loop. To protect your users and your server against this possibility, you should place a hard limit on the total amount of CPU time that the CGI script can consume.

20. Do not require the user to send a reusable password in plaintext over the network connection to authenticate herself. If you use usernames and passwords, use a cryptographically enabled web server so that the password is not sent in plaintext. Alternatively, use client-side certificates to provide authentication. If your users access an Internet Information Server web server through Internet Explorer, then you can use the NT challenge/response (NTLM), a Microsoft proprietary modification to the HTTP protocol. Finally, you can use HTTP Digest Authentication, which has an MD5 MAC to verify a shared password between the web server and the web browser. Apache 2.0 and above support Digest-based authentication with the mod_ auth_digest module; support in many browsers is increasing. The primary disadvantage of digest authentication is that it requires the web server to maintain an essentially unencrypted copy of each user’s password. For details on digest authentication, search for the AuthDigestFile directive in the Apache documentation, or look at

http://www.apache.org/docs-2.0/mod/mod_auth_digest.html.

21. Read through your code. Think of how you might attack it yourself. What happens if the program gets unexpected input? What happens if you are able to delay the program between two system calls?

Remember, most security flaws are actually programming faults. In a way, this is good news for programmers. When you make your program more secure, you’ll simultaneously be making it more reliable.

Securely Using Fields, Hidden Fields, and Cookies

One of the reasons that it can be difficult to develop secure web applications has to do with the very architecture of web applications. When you develop an application, you generally write a body of code that runs locally on the web server and a much smaller body of code that is downloaded and run remotely on the user’s web browser. You

might spend a lot of time making sure that these two code bases work properly together. For example, it’s very important to make sure that the field names downloaded in web forms exactly match the field names that serverside scripts are expecting. And you will probably spend time making sure that the HTML forms, JavaScript, and other codes that are downloaded to the browser work properly on a wide range of different browser programs. Even in the best of times, it can be difficult to get software on the web browser and the web server to properly synchronize and interoperate. What makes this whole process difficult from the security perspective is that attackers, by definition, don’t play by the rules. Sure, they can run your HTML forms and JavaScript in well-behaved browsers, but they can also pick apart the code, analyze it, and send completely made-up responses back to your web server. These sorts of attacks are difficult to detect because they are very hard for normal web developers to test against—after all, most web developers don’t have a stable of CGI-script attack tools.

There is nothing inherently wrong with storing this information on the web browser instead of the web server; indeed, storing this information on the browser eliminates the need for a backend database, user tracking, and a lot of other technology. But if you store information on the user’s web browser, you must validate this information when it is passed back to the web server to make sure that it has not been modified.

Many programmers do not realize the need to validate information returned from the web browser to the server. For example, in December 1999 engineers at Internet Security Systems (ISS) discovered that many e-commerce scripts from different vendors all shared a common vulnerability: they maintained the shopping cart, complete with the price for each item, on the user’s web browser without using any form of validation.235 When an invoice was prepared and a credit card charged, they blindly trusted the prices provided by the shopping carts. Thus, any attacker who wanted to give himself a discount could simply go shopping, save the server’s HTML onto his hard drive, edit the prices, and then click on the “Buy” button.

In a Spring 2001 study,236 four MIT graduate students discovered that many e-commerce sites did not properly validate the information in cookies. As a result, they were able to make subtle modifications in the cookies at e-commerce sites and gain access to unauthorized information.

Using Fields Securely

When checking arguments in your program, pay special attention to the following:

• Filter the contents of every field, selecting the characters that are appropriate for each response. For example, if a field is supposed to be a credit card number, select out the characters 0–9 and leave all other characters behind. This will also allow people to enter their credit card numbers with spaces or dashes.

• After you filter, check the length of every argument. If the length is incorrect, do not proceed, but instead generate an error.

• If you use a selection list, make certain that the value provided by the user was one of the legal values. Attackers can provide any value that they wish: they are not constrained by the allowable values in the selection list.

• Even if your forms use JavaScript to validate the contents of a form before it is submitted, be sure that you revalidate the contents on the server. An attacker can easily turn off JavaScript or bypass it entirely.

Hidden Fields and Compound URLs

A hidden field is a field that the web server sends to the web browser that is not displayed on the user’s web page. Instead, the field merely sits in the browser’s memory. When the form on the page is sent back to the server, the field and its contents are sent back.

235 ISS reported the security problem to the 11 vendors in December 1999, then released the information about the vulnerability to the press in February 2000. For further information, see http://www.cnn.com/2000/TECH/ computing/02/04/shop.glitch.idg/.

236 See “Dos and Don’ts of Client Authentication on the Web,” USENIX and MIT Technical Report 818, by Kevin Fu, Emil Sit, Kendra Smith, and Nick Feamster.

Some web developers use hidden fields to store information that is used for session tracking on e-commerce systems. For example, instead of using HTTP Basic Authentication, developers sometimes embed the username and password provided by the user as hidden fields in all future form entries:

<INPUT TYPE=”hidden” NAME=”username” VALUE=”simsong”> <INPUT TYPE=”hidden” NAME=”password” VALUE=”myauth11”>

Hidden fields can also be used to implement a shopping cart: <INPUT TYPE=”hidden” NAME=”items” VALUE=”3”>

<INPUT TYPE=”hidden” NAME=”item1” VALUE=”Book of Secrets:$4.99”> <INPUT TYPE=”hidden” NAME=”item2” VALUE=”Nasty Software:$45.32”> <INPUT TYPE=”hidden” NAME=”item3” VALUE=”Helping Hand:$32.23”>

Instead of embedding this information in hidden fields, it can be placed directly in the URL. These URLs will then be interpreted as if they were forms that were posted using the HTTP GET protocol. For example, this URL embeds a username and password:

http://www.vineyard.net/cgi-bin/password_tester?username=simsong&password=myauth11

It’s quite easy to use hidden fields. Little or no information needs to be stored on the server. And unlike cookies, which are limited to 4096 bytes, hidden fields can be practically any length whatsoever.

There are problems with using hidden fields in this way, however:

• If the user presses the “Back” button, items may be removed from the shopping cart. Sometimes this is the desired behavior, but usually it is not.

• HTML pages used by one person might be viewed by other people, possibly because the computer is shared. In this circumstance, the first user’s username, password, or shopping cart contents might be disclosed.

• If you use URLs to embed information, the complete URL—including the embedded information—will be stored in the web server’s log files. The full URL may also be passed by the user’s browser in the referrer [sic] header when the user accesses another web server. This may compromise the user’s privacy and/or security.

• In the vast majority of cases, the contents of the hidden field received by the web server are identical to what was originally provided. But there is no guarantee. An attacker can save your HTML to a file, analyze the form, and issue his own HTTP GET or POST command with whatever contents he desires. An attacker can also submit the same web page over and over, with slight modifications, probing for vulnerabilities. There is no way to stop this sort of behavior, so you must defend against it.

• If the HTTP connection is not SSL-encrypted, an attacker who can intercept the data may gain access to authentication credentials or other sensitive information.

Using Cookies

One attractive alternative to using hidden fields or URLs is to store information such as usernames, passwords, shopping cart contents, and so on, in HTTP cookies.

Users can modify their cookies, so cookies used for user tracking, shopping carts, and other types of e-commerce applications have all of the same problems described for hidden fields or compound URLs. But cookies also have problems all their own, including:

• Old cookies may continue to be used, even after they have “expired.”

• Users may make long-term copies of cookies that are supposed to remain ephemeral and not ever be copied onto a hard drive.

• Some users are suspicious of cookies and simply turn off the feature.

Using Cryptography to Strengthen Hidden Fields, Compound URLs, and Cookies

Many of the problems discussed above can be solved by using cryptography to protect the information in hidden fields, compound URLs, and cookies. Cryptography can:

• Prevent users from understanding the information stored on their computer.

• Allow web server applications to detect unauthorized or accidental changes to this information.

Here are examples from the previous sections, recoded to use cryptography.

Username and password authentication: <INPUT TYPE=”hidden” NAME=”auth”

VALUE=”p6e6J6FwQOk0tqLFTFYq5EXR03GQ1wYWG0ZsVnk09yv7ItIHG17ymls4UM%2F1bwHyg Rhp7ECawzUm%0AKl3Q%2BKRYhlmGILFtbde8%0A:”>

A secure shopping cart:

<INPUT TYPE=”hidden” NAME=”cart”

VALUE=”fLkrNxpQ9GKv9%2FrAvnLhuLnNDAV50KhNPjPhqG6fMJoJ5kCQ5u1gh0ij8JBqphBxdGV NOdja41XJ%0APLsT%2Bt1kydWN4Q%2BO9pW0yR9eIPLrzaDsZxauNPEe7cymPmXwd%2B6c1L49u TwdNTKoS0XAThDzow%3D%3D%0A:”>

A compound URL:

http://www.vineyard.net/cgi-bin/password_tester?p6e6J6FwQOk0tqLFTFYq5EXR03GQ1wYWG0ZsVnk09yv7ItIHG17ymls4UM%2F1bwHygRhp7 ECawzUm%0AKl3Q%2BKRYhlmGILFtbde8%0A:

In each of these cases, the individual human-readable variables have been replaced with a cryptographic block of information. This block is created with the following procedure:

1. Take the individual variables that need to be preserved and encode them as a string. This is called marshalling.

2. Prepend a 4-byte timestamp to these variables. The timestamp protects against replay attacks.

3. Compress the data. This saves space.

4. Prepend the length of the string to the data. This is required for decryption with block cipher.

5. Encrypt the string using a symmetric encryption function with a secret key.

6. Calculate an HMAC function of this encrypted string and prepend it to the encrypted string. The HMAC protects all encrypted, compressed, and marshaled data.

7. Encode the resulting string with Base64, then escape the non-URL characters and return the resulting string.

8. Use this escaped, Base64-encoded, encrypted, compressed string for hidden fields, compound URLs, and cookies.

To decode and validate this encrypted string, simply follow these steps in reverse:

1. Isolate the escaped, Base64-encoded, encrypted, compressed string from the hidden field, compound URL, or cookie.

2. Unescape the Base64 representation.

3. Remove the Base64 coding.

4. Verify the HMAC. If it doesn’t verify, then the string has been tampered with. Report an error and return.

5. Unencrypt the data.

6. Recover the length and use this to truncate the unencrypted data to the original length. This step is needed because block encryption functions will append null bytes to data to pad it out to an even block.

7. Decompress the compressed data.

8. Recover the timestamp from the beginning of the uncompressed data. If the timestamp is too old, disregard.

9. Return the remaining data to the caller, which will decode all of the original variables from the string.

This looks tremendously complicated and computationally intensive, but in fact, it is quite easy to code up and can run very quickly, as MD5 and symmetric encryption functions are quite fast. There are also ready-made libraries for doing this, such as CGI::EncryptForm for perl.

Connecting to Databases

It is common for a CGI program or script to connect to databases that are external to the web server. External databases can be used for many purposes, such as storing user preferences, implementing shopping carts, and even order processing. When the script runs, it opens a connection to the database, issues a query, gets the result, and then uses the result to formulate a response to the user. On some systems, a new database connection is created each time a new script is run. Other systems maintain a small number of persistent connections that are cached.

Database-backed web sites give a tremendous amount of power and flexibility to the web designer. Unfortunately, this approach can also reduce the overall security of the system: many security breaches have happened because an attacker was able to execute arbitrary SQL commands on the database server and view the results. If you deploy a database server to supplement your web site, it is important to be sure that the server is deployed and used securely.

Protect Account Information

Before the database server provides results to the script running on the web server, the server needs to authenticate the script to make sure it is authorized to access the information. Most databases use a simple username/password for account authentication, which means the script needs to have a valid username/password and present this information to the database server each time a request is issued.

Among many developers it is common practice to simply code the username and password into the scripts that require access to the database server. Unfortunately, this practice has several problems:

• If an attacker is able to view the script, the attacker will learn the username and password.

• If many scripts require access to the username and password, then it must be stored in several scripts.

• Changing the username and password requires modifying the script. When the script is modified, other changes may be made inadvertently.

Instead of storing the database username and password in the script, a better approach is to store this information in a file on the web server. This approach isolates the authentication information from the script that is performing the database request, which improves both maintainability and security. The server script then opens this file and reads the username and password prior to issuing a database request.

Remember that if the database server is not on the same host as the web server, those usernames and passwords will be transmitted over the network between the hosts. Be sure to use a database that allows for encrypted remote connections or another form of authentication that does not transmit cleartext passwords.

Use Filtering and Quoting to Screen Out Raw SQL

As we mentioned earlier, it is extremely important to filter all data from the user to make sure that it contains only allowable characters. When working with SQL servers, it is further important to properly quote data provided by the user before sending the data to the server. These procedures are used to prevent users from constructing their own SQL commands and sending that data to the SQL server.

For example, if you have a web form that asks a person for his name and then stores this information into a database, it might be tempting to simply take the person’s name from a field, put that field into a variable called $name, and then construct a SQL command using this variable. Consider this perl snippet:

$name = param('name');

sql_send(“insert into names (name) value ('$name');”);

Unfortunately, this is not safe: an attacker who has knowledge of your application can provide a specially crafted name that results in arbitrary SQL commands being executed. Consider this name:

John Smith’)”; delete from names;

When this name is used to build the SQL command, the resultant string will actually be interpreted as three commands—one that makes an insertion into the database, a second that deletes all of the data in the names table, and a third that contains a syntax error:

insert into names (name) value (‘John Smith’)”; delete from names; ');

Given this text, most SQL servers will insert a record into the names table, delete all of the data, and then report a SQL error.

The way to protect scripts from these kinds of attacks is to make sure that you first carefully filter incoming data, and that you next quote all of the remaining data properly before sending it to the SQL server.

Quoting is best done with a separate function that is always called whenever any string is sent to the SQL server. If you are using the Perl language and the DBI package, most of the database drivers provide a quote method on the database handle that performs such quoting. You use it like this:

# $dbh is a DBI object that represents a handle to an open database connection $qname = $dbh->quote(param(‘name’));

$dbh->do(“insert into name (name) value($qname)”);

Another approach is to precompile your SQL queries using variable binding. Variable binding allows you to precompile SQL queries with placeholders instead of actual variables. To return to our original example, you might compile the query using a hypothetical SQL interface that uses the @ sign as a placeholder for variables: $func = sql_compile(“insert into name (name) value (@)”);

You might then execute this query with some other hypothetical function: $name = param('name');

sql_bind($func,1,$name);

# bind the variable name to the first variable

sql_exec($func);

# execute the bound function

Using the DBI package, you often write it like this: # Insertion example

$name = param('name');

$dbh->do(“insert into name (name) value (?)”, undef, $name);

# Selection example

$sth = $dbh->prepare(“select * from name where id = ?”); $sth->execute($name);

Different systems will have different syntaxes and APIs for compiling, binding, and executing SQL queries.

Content Updating

How will your users update the web server’s content? In the early days of the World Wide Web, most content was created live on web servers by programmers and developers using text (or HTML) editors. These days most content is created on desktop PCs and Macs and then uploaded to the web server. This upload is fundamentally a file transfer operation, and thus subject to eavesdropping. As discussed above, you should require users to use a secure file transfer system, such as scp, Web-DAV over SSL, or insecure file transfer programs running over a virtual private network. In some cases, physical transfer by means of floppy disks or CD-ROMs may be preferable to any form of network transfer.

Securing Database Servers

If you use a database back-end, it is important that you protect the database server itself. If the database server runs on the same host as the web server, insure that it does not allow network access. If the database server runs on a separate host, consider these protections:

• Configure your firewall or network topology so that it is impossible for people out-side your organization to access your database server. For example, you may wish to set up your web server with two Ethernet adapters— one that connects to the Internet, and one that connects to a small firewall appliance that, in turn, connects to your database server. The firewall should be set up so that only database queries can pass between the web server and the database server.

• Make sure logins on the database server are limited. The individuals with login capabilities should be the system administrator and the database administrator.

• Make sure that the database server is backed up, physically protected, and maintained in the same way as your other secure servers.

Protection of the database is also necessary. When defining database users and access privileges, follow the principle of least privilege. If a CGI script only needs read access to a single table in a database, define a user with privileges restricted to only allow the necessary access and have the script connect with that user. Some database software allows you to define very fine-grained permissions for users – in some cases, you can grant or restrict access to individual columns or rows in a given table, or provide different access to users based on where or how they connect. Take advantage of these protections.

Securing DNS Name Servers

Organizations rely on their DNS servers to provide accurate hostname-to-ip address (and ip address-to-hostname and hostname-to-hostname) translations for other systems on the Internet. Because every domain on the Internet must have an authoritative name server, and because the addresses of these name servers must be public to be useful, DNS servers are a natural point of attack for an intruder. Because many applications use hostnames as the basis for access control lists, an attacker who can gain control of your DNS nameserver or corrupt its contents often leverage that to break into your systems.

Besides individual hostname resolutions, DNS also provides a system for downloading a copy of the entire database from a nameserver. This process is called a zone transfer, and this is the process that secondary servers use to obtain a copy of the primary server’s database.

DNS communicates over both UDP and TCP. Because UDP is a quick, packet-based protocol that allows for limited data transfer, it is typically used for the actual process of hostname resolution. TCP, meanwhile, is most commonly used for transactions that require large, reliable, and sustained data transfer—that is, zone transfers. However, individual queries can be made over TCP as well.

DNS zone transfers

Zone transfers can be a security risk, as they potentially give outsiders a complete list of all of an organization’s computers connected to the internal network. Many sites choose to allow UDP DNS packets through their firewalls and routers, but explicitly block DNS zone transfers originating at external sites. This design is a compromise between safety and usability: it allows outsiders to determine the IP addresses of each internal computer, but only if the computer’s name is already known.

You can block zone transfers with a router that can screen packets by blocking incoming TCP connections on port 53.237 Modern versions of the BIND nameserver implement an allow-transfers directive that allows you to specify the IP addresses of hosts that are allowed to perform zone transfers. This option is useful if you wish to allow zone transfers to a secondary nameserver that is not within your organization, but you don’t want to allow zone transfers to anyone else.

DNS nameserver attacks

There are three fundamental ways that an attacker can cause a nameserver to serve incorrect information:

Loading erroneous information

Incorrect information can be fraudulently loaded into your nameserver’s cache over the network, as a false reply to a query. This is often referred to as cache poisoning.

If your nameserver has contact with the outside network, there is a possibility that attackers can exploit a programming bug or a configuration error to load your nameserver with erroneous information. The best way to protect your nameserver from these kinds of attacks is to isolate it from the outside network, so that no contact is made. If you have a firewall, you can achieve this isolation by running two nameservers: one in front of the firewall, and one behind it. The nameserver in front of the firewall contains only the names and IP addresses of your gateway computer; the nameserver behind the firewall contains the names and IP addresses of all of your internal hosts. If you couple these nameservers with static routing tables, damaging information will not likely find its way into your nameservers. (Of course, depending on how you have built your firewall and what you allow your users to do on the network, this may not be a workable solution!)

Changing the configuration files

An attacker can change the nameserver’s configuration files on the computer where your nameserver resides. To change your configuration files, an attacker must have access to the filesystem of the computer on which the nameserver is running and be able to modify the files. After the files are modified, the nameserver must be restarted. As the nameserver must typically be started as the superuser, an attacker would need to have superuser access on the server machine to carry out this attack. Unfortunately, by having control of your nameserver, a skillful attacker could use that control as a stepping stone to control of your entire network. Furthermore, if the attacker does not have superuser access but can modify the nameserver files, then he can simply wait until the nameserver is restarted by somebody else, or until the system crashes and every program is restarted.

Using dynamic DNS

Modern DNS servers have facilities for dynamically updating DNS tables. This feature is very useful when IP addresses are dynamically assigned or shared among large numbers of people. Dynamic DNS allows a running DNS server to have its DNS tables updated without manually uploading a domain text file and asking the server to restart. However, an attacker can use the DNS dynamic update facility to provide your DNS server with a fraudulent update.

To be secure, dynamic DNS updates must be properly authenticated — otherwise, an attacker could attack your system by simply changing the mapping between your domain names and IP addresses. Most dynamic DNS servers

237 In rare cases, this may also block DNS queries, which are also permitted to use TCP.

make provisions for authentication by IP address (only certain IP addresses are allowed to provide updates), through the use of a shared key, or through the use of updates that are signed with a public key algorithm. In general, combining IP source address with one of the two cryptographic techniques provides for the highest level of security.

If you enable dynamic DNS and it is not correctly implemented, an attacker may use it to update your server without your permission. Many domain name servers suffer a constant stream of fraudulent dynamic DNS update attacks.

DNSSEC

DNSSEC (RFC 2535 and 3130) is an extension to DNS that provides for the creation of a DNS-based Public Key Infrastructure (PKI) and the use of this infrastructure in the signing of DNS responses. DNSSEC is an interesting protocol. Proponents have argued convincingly that the use of DNSSEC provides an easy way to bootstrap a global PKI that is not dependent upon certificates sold at high prices by centralized certificate authorities. Unfortunately, because of its populist nature and the fact that nobody really makes money when DNS-SEC servers are deployed, there has been very little move to deploy DNSSEC on a widespread scale. You can minimize the possibility of an attacker’s modifying or subverting your nameserver by following these recommendations:

• Run your nameserver on a special computer that does not have user accounts.

• If you must run the nameserver on a computer that is used by ordinary users, make sure that the nameserver’s files and directories are protected from other users. If your nameserver can be configured to run as a nonprivileged user (as modern versions of BIND can), you should take advantage of this option and keep the nameserver’s files accessible only to that user.

• If your nameserver can be configured to run in a chroot jail area of the filesystem (as modern versions of BIND can), you can use this option to limit its access to other files on your host.

• Configure your nameserver to ignore requests from bogus IP ranges (such as 10.0.0.0/8 if your subnet doesn’t use these addresses). In BIND, the blackhole directive in named.conf can be used to do this.

• Configure your nameserver not to perform recursive DNS queries for outsiders. In a recursive query, if your DNS server can’t find the information for the client, it issues its own queries to try to resolve it. When recursive queries are not allowed, it is up to the client to do the followup work. Recursive queries consume nameserver resources, and should not be performed for outsiders. In BIND, the allow-recursion directive controls which client hosts may request a recursive query.

• If you know of a specific site that is attempting to attack your nameserver, you can use BIND’s bogusns directive to prevent the program from sending nameserver queries to that host, or add the site to your firewall.

• If you use dynamic DNS updating facilities, require that updates be appropriately encrypted or cryptographically signed. Do not rely on IP addresses for appropriate authentication.

 
 


Copyright © 2003 The International Bank for Reconstruction and Development / The World Bank

Buy ativan Online Buy diazepam Online Buy effexor Online buy Cephalexin buy norvasc online Buy Vicodin Online order zyrtec 10mg order zyban 150mg Order cheap Zyban discount Zyban buy meridia without prescription meridia for depression purchase meridia buy meridia medication meridia no prescription usa pharmacy phentermine 37 5mg online phentermine no prescription phentermine very cheap difference between adipex and phentermine discount phentermine cheap Zyban no rx buy cheap zocor buy generic lisinopril order zocor 20mg Buy Ephedra Online order cheap Ephedra Online buy singulair order cheap Synthroid buy Synthroid online buy desyrel online Buy Atenolol Online Buy Atarax Online Buy Amoxicillin Online Buy Baclofen Online Buy Amitriptyline Online Buy Neurontin Online Buy Pravachol Online buy cheap tramadol 50 mg buy cheap tramadol overnight Order Phentermine 37.5 online Buy Phentermine Adipex 37.5mg Phentermine 37.5 Mg 90 Tablets original phentermine 90 Tablets Buy Zithromax 250mg Buy Generic Zithromax Order Zithromax 100 mg order discount zithromax Order lipitor 60 pills buy lipitor 40 mg Generic Lipitor 20 mg Purchase Lorazepam 2.5mg order Soma 350mg Soma Discount Prices order generic Soma Buy Provigil 30 pills order discount Provigil Buy paxil Online
phentermine no prescription phentermine 37 5mg online buy meridia without prescription buy cheap tramadol overnight order phentermine online no prescription buy cialis no prescription buy xanax online buy ambien no prescription cheap generic viagra viagra cialis levitra Phentermine 37.5 Mg 90 Tablets Buy Phentermine (Adipex) 37.5mg discount phentermine purchase meridia online buy tramadol online non prescription viagra original phentermine 90 tablets buy cheap tramadol overnight phentermine no prescription phentermine 37 5mg online tramadol cod online tramadol hcl very cheap tramadol buy tramadol at a cheap price online cheap tramadol without prescription order tramadol cod tramadol 180 next day tramadol tramadol hydrochloride order tramadol online cheap phentermine phentermine without prescription generic phentermine strongest phentermine cheap 37 5 phentermine long term phentermine use phentermine on sale phentermine 6 pm order where to buy phentermine phentermine hcl