Chapter 15. The World Wide Web

The existence of the World Wide Web is a major factor behind the explosive growth of the Internet. (In fact, many of the newcomers to the Internet believe that the Internet and the World Wide Web are the same thing.) Since the first graphical user interface to the Web to gain widespread acceptance, NCSA Mosaic, was introduced in 1993, web traffic on the Internet has been growing at an explosive rate, far faster than any other kind of traffic (SMTP email, FTP file transfers, Telnet remote terminal sessions, etc.). You will certainly want to let your users use a browser to access web sites, and you are very likely to want to run a site yourself, if you do anything that might benefit from publicity. This chapter discusses the underlying mechanisms involved, their security implications, and the measures you can take to deal with them.

The very things that make the Web so popular also make it very difficult to secure. The basic protocols are very flexible, and the programs used for web servers and clients are easy to extend. Each extension has its own security implications, but they are difficult to separate and control.

Most web browsers are capable of using protocols other than HTTP, which is the basic protocol of the Web. For example, these browsers are usually also Gopher and FTP clients or are capable of using your existing Telnet and FTP clients transparently (without it being obvious to the user that an external program is starting). Many of them are also NNTP and SMTP clients. They use a single, consistent notation called a Uniform Resource Locator (URL) to specify connections of various types.

In addition, a number of other protocols are used in conjunction with web browsers. Some of these have other client programs, but most of them are used primarily if not exclusively as a seamless part of web sites.

There are three basic sets of security concerns regarding HTTP:

  • What can a malicious client do to your HTTP server?

  • What can a malicious HTTP server do to your clients?

  • What else can come in, tunneled over HTTP?

The following sections describe these concerns.

HTTP Server Security

A server that supports nothing but the bare HTTP protocol poses relatively few security concerns. An HTTP server with no extensions takes requests and returns files; the only thing it writes to the disk are log files. Therefore, no matter how malicious the user and how badly written the server, the vulnerabilities of an HTTP server by itself are pretty much limited to various sorts of denial of service (the HTTP server crashes, crashes the machine, makes the rest of the machine unusable, fills up the disk . . .) and inadvertent release of data (a client requests a file you wanted to keep private, but the server gives it out). If the server is sufficiently badly written, an attacker may be able to execute arbitrary commands with the permissions of the HTTP server via a buffer overflow attack. This is unlikely in a simple server and relatively easy to protect against (run the server as an account with no special privileges, and even if an attacker can execute commands he or she won’t get any interesting results).

Denial of service is always impossible to protect against completely, but a well-written HTTP server will be relatively immune to it. Normal practices for dealing with bastion hosts (see Chapter 10) will also help you avoid and recover from denial of service attacks. Publicly accessible web sites are high-visibility targets and tend to be resource-intensive even when they are not under attack, so it is probably unwise to combine them on the same bastion host with other services.

Inadvertent release of data is a problem that requires more special effort to avoid. You should assume that any file that an HTTP server can read is a file that it will give out. Don’t assume that a file is safe because it’s not in the document tree, because it’s not in HTML, or because you haven’t published a link to it. It’s easy to get caught out; one of the authors sent out email to a bunch of friends about a web page, only to get an answer back 20 minutes later that said “Interesting, but I don’t like the picture of me.” “What picture of you? You’re not on that web page!” “No, but I always look at the whole directory, and when I saw there was a .gif file named after me I had to look at it.” That was a combination of a mistake on the author’s part (transferring an entire working directory into production instead of just the parts intended to be published) and on the site maintainer’s part (it shouldn’t have been giving out directory information anyway).

In this case, the effect was benign, but the same sort of mistake can have much more serious consequences. Public web servers frequently make headlines by containing draft or prerelease information erroneously left with information intended to be published; information intended for a small audience but left unprotected in the hope that nobody will notice it; and information used internally by the web server or other processes on the machine but left where the web server can read it and outsiders can request it. That latter category can include everything from Unix password files to customer data (including credit card numbers!).

In order to minimize these exposures:

  • Carefully configure the security and access control features of your server to restrict its capabilities and what users can access with it.

  • Run the server as an unprivileged user.

  • Use filesystem permissions to be sure that the server cannot read files it is not supposed to provide access to.

  • Under Unix, use the chroot mechanism to restrict the server’s operation to a particular section of your filesystem hierarchy. You can use chroot either within the server or through an external wrapper program.

  • Minimize the amount of sensitive information on the machine.

  • Limit the number of people who can put data on the externally visible web sites; educate those people carefully about the implications of publishing data.

  • Maintain a clear distinction between production and development servers and specify a cleanup stage before data is moved to the production servers.

HTTP Extensions

In the previous section, we discussed the risks of an HTTP server that processes nothing but the base HTTP protocol and pointed out that they’re fairly small. This seems to conflict with the easily observable fact that there are frequent and high-profile break-ins to web sites. The problem is that almost nobody runs an HTTP server without extensions. Almost all HTTP servers make extensive use of external programs or additional protocols. (It used to be that additional protocols were always implemented outside the web server, but for efficiency reasons, it’s become common to build extension languages into the web server itself.)

These extensions provide all sorts of capabilities; authoring extensions allow people to add and change web pages using a browser, form-processing extensions allow people to place orders for products, database extensions check the current status of things, active page extensions change the look of a page depending on who’s asked for it. Anything that a web server does besides returning an unchanging data file requires some addition to the basic capabilities of the server.

These additions radically change the security picture. Instead of providing an extremely limited interaction, they provide the ability to do all sorts of dangerous things (like write data to the server). Furthermore, many extensions are not simple, limited-function modules; they’re general-purpose languages, allowing you to easily add your own insecurity at home. That means that the security of your web server is no longer dependent only on the security of the web server, which you can be relatively confident has been developed by people who know something about security and have a development and debugging process in place, but also on all the add-in programs, which may well have been written in a few minutes by novice programmers with no thoughts about security.

Even if you don’t install locally written programs, commercial web server extensions have a long and dark history of security problems. It’s pretty easy to write a secure program if it never has to write data. It’s hard to write a secure program that actually lets the user change things; it gets harder if the user has to juggle high-value information (for instance, if you’re writing a electronic commerce application that is dealing with data that has real-world effects on goods and money). It can become very difficult to evaluate security if you’re trying to provide complete flexibility.

The list of companies with serious security problems in their web server extensions doesn’t just read like a who’s who of the software industry; it’s effectively the complete list of companies that provide web servers or extensions! For instance, Microsoft, Sun, Netscape, and Oracle have all had problems, often repeatedly. Lest you think this a commercial problem, we should point out that both the Apache server and the Squid cache server have had their problems as well.

You will often see external programs used with web servers called CGI scripts, after the Common Gateway Interface (CGI), which specifies how browsers can pass information to servers. You will also often see Active Server Pages (ASP), which is a Microsoft technology for making dynamic pages. New technologies for extensions appear at a rapid rate, but they all have the same sorts of security implications.

There are two things you need to worry about with these extensions:

  • Can an attacker trick extensions into doing something they shouldn’t?

  • Can an attacker run unexpected external programs?

Tricking extensions

Your average HTTP server runs dozens of external programs; they often come from multiple sources and are written in multiple languages. It’s not unusual for a single page to involve three or four layers of programs. For instance, the web server calls an external program written in Visual Basic, which uses Jet to access a database server. In many cases, the people writing web pages are using libraries and may not even be aware what other programs are getting run. Figure 15.1 shows one configuration where a simple query to a web server involves multiple programs.

Layers of programs running on a web server
Figure 15.1. Layers of programs running on a web server

This situation is a security nightmare. Effectively, each of these external programs is an Internet-attached server, with all the security implications any other server has. If any one of them has security problems, the entire system may be vulnerable; in the previous example, you are vulnerable to problems in the web server, the external program, the Visual Basic interpreter, Jet, and the database server. Both the Visual Basic interpreter and Jet are invisible in normal circumstances, but there have been security problems with Jet.

In the case of a program that accesses a database server, you may not know exactly how it works, but at least you’re probably aware that the program is important to you. But security problems may exist and be important even in programs that you think are too trivial to worry about; for instance, there have been security problems with counter programs (which are used to put up the little signs that say “You are visitor number 437”). These programs appear to be pretty harmless; after all, even if people can manipulate the answer they return, who really cares? The difficulty is that they keep the information in a file somewhere, which means that they are capable of both reading and writing files on the machine. Some counter programs can be manipulated into reading or writing any file they have appropriate permissions for, and overwriting arbitrary files with counter information can do a lot of damage.

In order to minimize the risks created by external programs, treat them as you would any other servers. In particular:

  • Install external programs only after you have considered their security implications and tested them on a protected machine.

  • Run as few external programs as possible.

  • Run external programs with minimal permissions.

  • Don’t assume that programs will be accessed from pages or CGI forms you provide.

  • Develop special bastion host configurations for external programs, going through and removing all unneeded files and double-checking all permissions and placements of files that are read and written.

The most common errors people make are:

  • Taking a development tool or web server package and installing it on a production machine without removing sample programs or other development features. These are often proof-of-concept or debugging tools that provide very broad access.

  • Running external programs with too many permissions, either by using an overly powerful account (root, under Unix, for instance), or the same account for a number of different external programs, or a default account provided by a software vendor with normal user access to the entire system (such accounts also often have a known name and password).

More conceptually, people are too trusting; they install combinations of commercial, externally and internally produced programs or scripts without considering their implications. Without suitable training, very few programmers are capable of writing secure programs, and all programs run by a web server need to be secure. No external vendor is so large and clever that you can install their software directly onto your production web server and feel sure that you are secure. No web server add-on is so trivial that you can let a novice programmer write it and not worry about its security.

You must treat every single addition to your web server as a new Internet-available server and evaluate its security appropriately. You must also maintain them all, keeping track of any newly discovered vulnerabilities and making appropriate modifications. Allowing people who are not security-aware to put executable programs on your web server is a recipe for disaster.

Running unexpected external programs

The second concern is that attackers might be able to run external programs that you didn’t intend to make available. In the worst case, they upload their own external programs and cause your server to run them. How could attackers do this? Suppose the following:

  • Your HTTP server and your anonymous FTP server both run on the same machine.

  • They can both access the same areas of the filesystem.

  • A writable directory is located somewhere in those areas, so that customers can upload crash dumps from your product via FTP for analysis by your programmers, for example.

In this case, the attacker might be able to upload a script or binary to that writable directory using anonymous FTP and then cause the HTTP server to run it.

What is your defense against things like this? Once again, your best bet is to restrict what filesystem areas each server can access (for instance, using chroot under Unix) and to provide a restricted environment in which each server can run. Note that this sort of vulnerability is by no means limited to FTP but is present any time that files can be uploaded.

HTTP Client Security

The security problems of HTTP clients are just as complex as those of HTTP servers. There are several problems:

  • Inadvertent release of information

  • Vulnerabilities in external viewers

  • Vulnerabilities in extension systems

Inadvertent Release of Information

There are a number of ways in which web browsers may give away information that you didn’t intend to make public. The most common is that they fail to protect passwords and usernames in ways that you might expect. Many web pages pass usernames and passwords around completely unprotected; some of them even embed them into URLs, making it easy to accidentally store them in your bookmarks file or mail them to a friend along with the location of an interesting web page.

The default authentication for web pages is something called basic authentication. This is what’s happening when you ask for a page, and instead of bringing up the page, your web browser brings up a standard dialog box that asks you for your username and password. There’s no encryption protecting that username and password; it’s just sent to the server in cleartext. Furthermore, if you ask for another page from the same server, the username and password will be sent again, without any warning, still unencrypted.

A web site can protect the username and password data by telling the browser to use HTTPS, instead of HTTP, to make the connection. (HTTPS is discussed further later in this chapter.) This will encrypt the entire communication, including the authentication information. Unfortunately, you can’t usually tell whether or not a web site has done this; although there’s a little lock icon to tell you when the page you’re looking at is encrypted, most clients don’t display it, or any other indication that things have been secured, until the page actually loads, which is after you’ve already given out the username and password.

That’s not the only way in which it’s difficult to tell what a web server is going to do with your password. You may be able to tell if the web server is doing something extremely insecure, like embedding the password in cleartext in a URL, but you can’t tell if it’s storing it properly on the other end. Therefore, while you can sometimes be sure that your password isn’t protected, you can never be sure that it is, and you should assume that it isn’t. Don’t use passwords you’ve sent over the Web to protect anything you care about deeply. You should use different passwords on different web sites, and they should not be the same passwords that you use anywhere else.

If you’re going to send a web site important data, you should be sure that the site has made a legally binding commitment to protect that data appropriately. You should also be sure that you have an encrypted connection to the site.

Cookies

Cookies are a way for a site to track information about you. It can be information that lasts a long time (for instance, information about what you want to see when you come to the site) or information about what you’ve just done (for instance, information about what items you want to buy in the current transaction). Cookies are important for web sites because it’s otherwise extremely difficult to keep track of anything about a web browser. Each time a browser requests a page, it’s a new transaction, with no way for the server to know what previous transaction it might be related to. Cookies provide a way for a server to ask a web browser to keep track of and possibly store some data.

A cookie is a fairly simple object; it’s a small amount of information to be stored that is associated with an identifying string, an expiration date, and a URL pattern that indicates when the cookie should be sent with HTTP requests. Whenever you visit a web site, the browser checks to see if any unexpired cookies match the URL pattern, and if so, the browser sends them along with your request.

The information that’s in a cookie isn’t usually of any great interest by itself. Cookies tend to contain customer identifiers or coded lists of preferences—things that make sense only to the site that set the cookie. This is important because cookies are passed across the network unencrypted, and you wouldn’t want them to have anything dangerous in them.

On the other hand, once a web site gets a cookie, it may give back information that you do care about. For instance, it might use the cookie to look up the credit card information you used on your last order (in which case somebody with that cookie could order things on your credit card). For that matter, it might just look up your last order and display it along with your name. Since cookies are passed unencrypted, and can be intercepted at any point, it’s not good practice to use them for anything critical, but some web sites do.

In addition, many people are worried about situations in which cookies can be used to track patterns of usage. When you use a link on a web page, the site you go to gets information about the page the link was on (this is called the referrer). If the site you go to also has a cookie that will identify you, it can build up a history of the places you have come from. This wouldn’t be very interesting for most sites, but sites that put up banner advertisements have links on thousands of web pages and can build up a fairly accurate picture of where you come from. Since referrer information includes the entire URL, this will include information about specific search requests and, in the worst cases, may contain password and username information.

There are some controls on the use of cookies. Some browsers don’t support cookies at all; others will allow you to control the situations where you give out a cookie, by choosing to reject all cookies, asking you before accepting cookies, or accepting only certain cookies. For instance, cookies are intended to be returned only to the site that set them, but the definition of “site” is unclear. The cookie specifies what hostnames it should be returned to and may give a specific hostname or a broad range of hostnames. Some browsers can be configured so that they will accept only cookies that will be returned to the host that originally set the cookie.

External Viewers

HTTP servers can provide data in any number of formats: plain text files, HTML files, PostScript documents, image files (PNG, JPEG, and GIF), movie files (MPEG), audio files, and so on. The servers use MIME, discussed briefly in Chapter 16, to format the data and specify its type. HTTP clients generally don’t attempt to understand and process all of these different data formats. They understand some types (such as HTML, plain text, JPEG, and GIF), and they rely on external programs to deal with the rest. These external programs will display, play, preview, print, or do whatever is appropriate for the format.

For example, web browsers confronted with a PDF file will ordinarily invoke Adobe Acrobat Exchange or Acrobat Reader, and web browsers confronted with a compressed file will ordinarily invoke a decompression program. The user controls (generally via a configuration file) what data types the HTTP client knows about, which programs to invoke for which data types, and what arguments to pass to those programs. If the user hasn’t provided a configuration file, the HTTP client generally uses a built-in default or a systemwide default.

These external programs may be obviously separate from the web browser, or they may be plug-ins, programs that are not part of the web browser but that integrate with it seamlessly. Plug-ins are simply external programs that can be run by the browser and will display information in windows that the browser controls. There is more than one type of plug-in technology; Microsoft’s ActiveX and Netscape’s Plug-Ins can both be used to provide seamless integration with a browser. Despite the fact that they look like parts of the browser, they have the same security implications as other external programs.

All of these external programs present two security concerns:

  • What are the inherent capabilities of the external programs an attacker might take advantage of ?

  • What new programs (or new arguments for existing programs) might an attacker be able to convince the user to add to the local configuration?

Let’s consider, for example, what an HTTP client is going to do with a PostScript file. PostScript is a language for controlling printers. While primarily intended for that purpose, it is a full programming language, complete with data structures, flow of control operators, and file input/output operators. These operators (“read file”, “write file”, “create file”, “delete file”, etc.) are seldom used, except on printers with local disks for font storage, but they’re there as part of the language. PostScript previewers (such as GhostScript) generally implement these operators for completeness.

Suppose that a user uses Internet Explorer to pull down a PostScript document. Internet Explorer invokes GhostScript, and it turns out that the document has PostScript commands in it that say “delete all files in the current directory”. If GhostScript executes the commands, who’s to blame? You can’t really expect Internet Explorer to scan the PostScript on the way through to see if it’s dangerous; that’s an impossible task. You can’t really expect GhostScript not to do what it’s told in valid PostScript code. You can’t really expect your users not to download PostScript code or to scan it themselves.

Current versions of GhostScript have a safer mode they run in by default. This mode disables “dangerous” operators such as those for file input/output. But what about all the other PostScript interpreters or previewers? And what about the applications to handle all the other data types? How safe are they? Who knows?

Even if you have safe versions of these auxiliary applications, how do you keep your users from changing their configuration files to add new applications, run different applications, or pass different arguments (for example, to disable the safer mode of GhostScript) to the existing applications?

Why would a user do this? Suppose that the user found something on the web that claimed to be something really neat — a game demo, a graphics file, a copy of the hottest new song, whatever. And suppose that this desirable something came with a note that said “Hey, before you can access this Really Cool Thing, you need to modify your browser configuration, because the standard configuration doesn’t know how to deal with this thing; here’s what you do. . . .” And suppose that the instructions were something like “remove the `-dSAFER’ flag from the configuration for files of type PostScript”?

Would your users recognize that they were being instructed to do something dangerous? Even if they recognized it, would they do it anyway (nice, trusting people that they are)?

Extension Systems

Using external viewers is not the only way to extend the capabilities of a web browser. Most browsers also support at least one system that allows web pages to download programs that will be executed by the browser. A variety of different extension systems are supported by different browsers, and they have very different security models and implications. The details of the different systems are discussed in Section 15.4, later in this chapter. Even though the systems differ, they have a certain number of goals and security implications in common.

These extension systems are very convenient; it is often much more efficient to have the browser do some calculations itself than to have to send data to an HTTP server, have it do some calculations, and get the answer back. In addition, extension languages allow for a much more powerful and flexible interface between the browser and the full capabilities of the computer than you can get by using external viewers.

For instance, if you are filling out a form, it’s annoying to have to submit the form to the server and wait for it to come back and tell you that you’ve omitted a required piece of information. It’s preferable for your browser to be able to tell you that immediately. Similarly, if your happiness depends on having penguins dance across the screen, the most efficient way to get that effect is going to be to tell your browser how to draw a dancing penguin and where to move it.

On the other hand, filling out forms and drawing dancing penguins are not all that interesting. In order for extension languages to actually do interesting and useful tasks, they have to have more capabilities, but the more capabilities that are available, the more dangerous a language is.

Of course, normal programming languages have lots of capabilities and therefore lots of dangers, but people don’t usually find this worrisome. This is because when you get a program written in a normal programming language, you generally decide that you want the program, you go out looking for it, you have some information about where it comes from, and you explicitly choose to run it. When you get a program as part of a web page, it just shows up and runs; you may be happily watching the dancing penguins and not knowing that anything else is happening.

We discuss the different approaches taken by extension languages in the following sections, as we discuss the specific languages. All of them do attempt to provide security, but none of them is problem free.

What Can You Do?

There is no simple, foolproof defense against the types of problems we’ve described. At this point in time, you have to rely on a combination of carefully installed and configured client and auxiliary programs, and a healthy dose of user education and awareness training. This is an area of active research and development, and both the safeguards and the attacks will probably develop significantly over the next couple of years.

Content-aware firewalls, whether they are packet filters or proxies, can be of considerable help in reducing client vulnerability. A firewall that pays attention to content can control which extension languages and which types of files are passed through; it is even possible for it to do virus scanning on executables. Unfortunately, it’s not possible to do a truly satisfactory job of protection even with a content-aware firewall.

Using content-based filtering, you have two options; you can filter out everything that might be dangerous, or you can filter out only those things you know for certain are dangerous. In the first case, you simply filter out all scripting languages; in the second case, you filter out known attacks. Be cautious of products that claim to filter out all hostile code and only hostile code. Accurately determining what code is hostile by simply looking at the code is impossible in the most specific, logical, and mathematical sense of the term. For useful scripting languages, it is equivalent to solving the Turing halting problem (determining whether an arbitrary piece of code ever stops executing), and the proof that it is impossible is one of the most famous and fundamental results in theoretical computer science.

It is possible to recognize particular pieces of hostile code, and sometimes even to recognize patterns that are common to many pieces of hostile code. Most content-based filtering systems rely on recognizing known attacks. Any time somebody comes up with a new attack, you will be vulnerable to it until the filter is updated, which may of course be after you have been attacked. Many content-based filters are easily fooled by trivial changes to the attack. Content filters that try to remove only hostile code fundamentally use the same technology as virus detectors. This has the advantage that it’s a well-understood problem for vendors, who know about creating and distributing signatures. It has the disadvantage that it’s a well-understood problem for attackers, as well, who have a variety of programs at their disposal for permuting programs to change their signatures.

Using content filtering to remove all scripting languages is safer. Unfortunately, you really do need to remove all scripting languages, since otherwise, it is possible to pass through JavaScript or VBScript programs that create Java code or ActiveX controls. Many web pages are difficult or impossible to use if you filter out all scripting languages (and a significant percentage of them don’t detect the problem and are just mysteriously blank or nonfunctional). In addition, using content filtering to remove scripting can interfere with some of the methods that servers use to try to deal with clients that don’t support scripting languages. For instance, some servers attempt to determine capabilities of the client by the information the client provides about the browser version, which doesn’t provide any information about the filter in the middle. Some pages may also try to use JavaScript to determine if Java is available. This means that pages that work fine if scripting languages are turned off at the browser may still fail miserably when a filter removes the scripts.

As we mention later, content filtering is impossible on some web pages; connections made with HTTPS instead of with HTTP are encrypted, and the firewall cannot tell what is in them to do content filtering.

Internet Explorer and Security Zones

One way for a browser to improve its security is to treat different sites differently. It’s reasonable to allow an internal web site to do more risky things than an external one, for instance.

Starting with Internet Explorer 4.0, Microsoft introduced the concept of security zones to allow you to configure your browser to do this. Explorer defines multiple security zones and sets different default security policies for them. For instance, there is a security zone for the intranet, which by default accepts all signed ActiveX controls and asks you if you want to allow each unsigned control, and one for the Internet, which by default asks you if you want to accept each signed control and rejects all unsigned controls. (ActiveX controls and signatures are discussed later in this chapter.) There is also a security zone that applies only to data originating on the local machine (this is not supposed to include cached data that was originally loaded from the Internet). The local machine zone is the most trusted zone.

In most cases, Internet Explorer uses the host portion of the URL to determine what zone a page is in. Because the different zones have different security policies, it’s important that Internet Explorer get this right. However, there have been several problems with the way that Internet Explorer does this, some of which Microsoft has fixed and some of which are not fixable. In particular, any hostname that does not contain a period is assumed to be in the intranet zone. Originally, there were various ways of referring to Internet hosts by IP address that could force any Internet host to be treated as an intranet host. These problems have been removed, and there is now no known way to write a link that will force Internet Explorer to consider it part of the intranet zone.

However, there are numerous ways for people to set themselves up so that external hosts are considered intranet hosts, and the security implications are unlikely to be clear to them. For instance, adding a domain name to the Domain Suffix Search Order in DNS properties will make all hosts in that domain parts of the intranet zone; for a less sweeping effect, any host that’s present in LMHOSTS or HOSTS with a short name is also part of the intranet zone. An internal web server that will act as an intermediary and retrieve external pages will make all those pages parts of the intranet zone. The most notable class of programs that do this sort of thing are translators, like AltaVista’s Babelfish (http://babelfish.altavista.com), which will translate English to French, among other options, or RinkWorks’ Dialectizer (http://www.rinkworks.com/dialect), which will show you the page as if it were spoken by the cartoon character Elmer Fudd, among other options.

HTTP

HyperText Transfer Protocol (HTTP) is the protocol that the web is based on. The HTTP protocol itself is a relatively secure protocol and a straightforward one to allow through firewalls.

HTTP Tunneling

HTTP itself is a simple protocol, but it can carry quite complex data. Because HTTP is simple and popular, most people let it through their firewalls. Because it can carry complex data, it’s easy to use it to carry other protocols, which can be useful. For instance, as a firewall maintainer, you may prefer having audio data come in over HTTP to having to configure more open ports for audio data (your users may not, since the quality may not be very good).

On the other hand, tunneling can also allow inherently insecure protocols to cross your firewall. For this reason, it may be advantageous to use a firewall solution that does content-based checking of HTTP connections, so that you can disallow connections that are actually tunneling other protocols. This can be quite difficult to do.

Different programs use different methods of “tunneling”. These range from simply running their normal protocol on port 80, to including support for HTTP proxying using the “CONNECT” method (discussed later in the section about HTTP proxying), to actually using HTTP with a data type that the client handles specially.

Some of these are much easier to filter out than others. For instance, almost any content checking, whether it’s an intelligent packet filter or an HTTP-aware proxy, will get rid of people running protocols other than HTTP on port 80. Similarly, most HTTP proxies will let you control what destinations can be used with CONNECT, and you should restrict them carefully to just the destinations that you need.

Tunneling that actually uses HTTP, on the other hand, is very difficult to filter out successfully. In order to get rid of it, you need to do content filtering on the HTTP stream and remove the relevant data types. Relatively few firewalls support this functionality, and it’s very difficult to do successfully in any case. The problem is that if you remove only the data types that you know are being used for tunneling, you are setting up a policy that allows connections by default, which is guaranteed to leave you with a continuous stream of new problems. On the other hand, if you accept only data types that you believe to be safe, you are going to have a continuous stream of new complaints from users, because many data types are in use on the web, and they change rapidly.

Fortunately, the uses for tunneling that actually uses HTTP are fairly limited. The HTTP protocol is set up to support interactions that look like normal web browsing; the client sends a query, and the server sends an answer. The client can’t send any information except the initial query, which is of limited size. This model works well for tunneling some other protocols (for instance, it’s fine for tunneling RealAudio) but poorly for tunneling protocols that need prolonged interaction between the client and the server. This doesn’t prevent people from tunneling any protocol they like over HTTP, but it does at least make it more difficult and less efficient.

There is unfortunately no good solution to the general problem of tunneled protocols. Using proxying to make sure that connections are using HTTP, and controlling the use of CONNECT, will at least limit your exposure.

Special HTTP Servers

We have been discussing web servers, programs that exist purely to provide content via HTTP and related protocols. But HTTP is a straightforward and widely implemented protocol, so a number of things speak HTTP not to provide random content, but for some specialized purpose. The classic example is the administrative interface to normal HTTP servers. If you’re administering a web server, you probably have a browser handy, so what’s more natural than using the browser to do the administration? For a number of reasons, you don’t want the administrative interface built in to the standard server (among other things, common administrative tasks involve stopping and starting the server—stopping it while you’re talking to it is one thing, but starting it again is a neat trick if it’s not there to talk to). Therefore, there is often a second server that speaks the HTTP protocol but doesn’t behave exactly like a normal web server reading information out of files.

These days, other programs and even hardware devices may provide HTTP interfaces. For instance, you can buy a power strip with a built-in web server, allowing you to turn its outlets on and off from a web browser. These servers do not behave like the servers we have been discussing, and the fact that they speak the HTTP protocol doesn’t give you any particularly good idea of what their security vulnerabilities may be.

You will have to assess the security of each of these servers separately. Some of the questions you should ask are:

  • What information can the web server read? Are there any files that it might unexpectedly reveal?

  • How are users authenticated?

  • What can be done to the device via the server?

In general, you do not want to allow connections to these servers to cross a firewall.

Packet Filtering Characteristics of HTTP

HTTP is a TCP-based service. Clients use random ports above 1023. Most servers use port 80, but some don’t. To understand why, you need some history.

Many information access services (notably HTTP, WAIS, and Gopher) were designed so that the servers don’t have to run on a fixed well-known port on all machines. A standard well-known port was established for each of these services, but the clients and servers are all capable of using alternate ports as well. When you reference one of these servers, you can include the port number it’s running on (assuming that it’s not the standard port for that service) in addition to the name of the machine it’s running on. For example, an HTTP URL of the form http://host.domain.example/file.html is assumed to refer to a server on the standard HTTP port (port 80); if the server were on an alternate port (port 8000, for example), the URL would be written http://host.domain.example:8000/file.html.

The protocol designers had two valid reasons for designing these services this way:

  • Doing so allows a single machine to run multiple servers for multiple data sets. You could, for example, run one HTTP server that’s accessible to the world with data that you wish to make available to the public, and another that has other, nonpublic data on a different port that’s restricted (via packet filtering or the authentication available in the HTTP server, for example).

  • Doing so allows users to run their own servers (which may be a blessing or a curse, depending on your particular security policy). Because the standard well-known ports are all in the range below 1024 that’s reserved for use only by root on Unix machines, unprivileged users can’t run their servers on the standard port numbers.

The ability to provide these services on nonstandard ports has its uses, but it complicates things considerably from a packet filtering point of view. If your users wish to access a server running on a nonstandard port, you have several choices:

  • You can tell the users they can’t do it; this may or may not be acceptable, depending on your environment.

  • You can add a special exception for that service to your packet filtering setup. This is bad for your users because it means that they first have to recognize the problem and then wait until you’ve fixed it, and it’s bad for you because you’ll constantly have to be adding exceptions to the filter list.

  • You can try to convince the server’s owner to move the server to the standard port. While encouraging folks to use the standard ports as much as possible is a good long-term solution, it’s not likely to yield immediate results.

  • You can use some kind of proxied version of the client. This requires setup on your end and may restrict your choice of clients. On the other hand, both Internet Explorer and Netscape Navigator support proxying, and they are by far the most popular clients.

  • If you can filter on the ACK bit, you can allow all outbound connections, regardless of destination port. This opens up a wide variety of services, including passive-mode FTP. It also is a noticeable increase in your vulnerability.

The good news is that the vast majority of these servers (probably more than 90 percent of them) use the standard port, and the more widely used and important the server is, the more likely it is to use the standard port. Many servers that use nonstandard ports use one of a few easily recognizable substitutes (800 or 8000, for instance).

Some servers also use nonstandard ports to run secondary servers. Traditionally, HTTP proxies use port 8080, and administrative servers use a port number one higher than the server they’re controlling (81 for administering a standard web server and 8081 for administering a proxy server).

Your firewall will probably prevent people on your internal network from setting up their own servers at nonstandard ports (you’re not going to want to allow inbound connections to arbitrary ports above 1023). You could set up such servers on a bastion host, but wherever possible, it’s kinder to other sites to leave your servers on the standard port.

Direction

Source Addr.

Dest. Addr.

Protocol

Source Port

Dest. Port

ACK Set

Notes

In

Ext

Int

TCP

>1023

80[1]

[2]

Request, external client to internal server

Out

Int

Ext

TCP

80[1]

>1023

Yes

Response, internal server to external client

Out

Int

Ext

TCP

>1023

80[1]

[2]

Request, internal client to external server

In

Ext

Int

TCP

80[1]

>1023

Yes

Response, external server to internal client

[1] 80 is the standard port number for HTTP servers, but some servers run on different port numbers.

[2] ACK is not set on the first packet of this type (establishing connection) but will be set on the rest.

Proxying Characteristics of HTTP

Various HTTP clients (such as Internet Explorer and Netscape Navigator) transparently support various proxying schemes. Some clients support SOCKS; others support user-transparent proxying via special HTTP servers, and some support both. (See the discussion of SOCKS and proxying in general in Chapter 9.)

HTTP proxies of various kinds are extremely common, and many incorporate caching, which can provide significant performance advantages for most sites. (A caching proxy is one that makes a copy of the requested data, so that if somebody else requests the same data, the proxy can fulfill the request with the copy instead of going back to the original server to request the data again.) In addition, many sites are worried about the content that people access via HTTP and use proxies to control accessibility (for instance, to prevent access to sites containing pornography, stock prices, or sports scores, all of which are common nonbusiness uses of the web by employees).

Clients that are speaking to HTTP proxy servers use HTTP, but they use slightly different commands from the ones they’d normally use. A client that wants to get the document known as “http://amusinginformation.example/foodle” without using a proxy will connect to the host amusinginformation.example and send a command much like “GET /foodle HTTP/1.1”. In order to use an HTTP proxy, the client will connect to the proxy instead and issue the command as “GET http://amusinginformation.example/foodle HTTP/1.1”. The proxy will then connect to amusinginformation.example and send “GET /foodle HTTP/1.1” and return the resulting page to the client.

Some HTTP proxy servers support commands that normal HTTP servers don’t support. For instance, they may allow a client to issue commands like “FTP ftp://amusinginformation.example/foodle” (to have the proxy server transfer the named file via FTP and return it to the client) or “CONNECT amusinginformation.example:873” (to have the proxy server make a TCP connection to the named port and relay information between it and the client). There is no standard for these additional commands, although FTP and CONNECT are two of the most common. Most web browsers will support using an HTTP proxy server for FTP and Gopher connections, and common web proxies (for instance, Microsoft Proxy Server) will support FTP and Gopher.

Some clients that are not web browsers will allow you to use an HTTP proxy server for protocols other than HTTP, and most of them depend on using CONNECT, which makes the HTTP proxy server into a generic proxy. For instance, Lotus Notes and rsync clients both are able to use HTTP proxies to get to their servers via CONNECT.

Using an HTTP proxy server as a generic proxy in this way is convenient but not particularly secure. Few HTTP proxy servers provide any interesting control or logging on the protocols used with CONNECT. You will want to be very restrictive about what protocols you allow this way.

It’s extremely important to prevent external users from connecting to your HTTP proxy servers. If your HTTP proxy server can make inbound connections, external users can use it as a platform to attack internal servers they would not otherwise be able to get to (this is particularly dangerous if they can use CONNECT to get to arbitrary services). Even if the proxy server can’t be used this way, it can be used to attack third parties.

People often search actively for open HTTP proxy servers. Some of these people are hostile and want to use the proxy servers as attack platforms, but some of them just want to use the proxy servers to access web sites that would otherwise be unavailable to them because of filtering rules at their site (or in a few cases, filtering imposed by national governments). Either way, it’s probably not to your advantage to let them use your site. Being nice to people behind restrictive filters is tempting, but in the long run, it will merely use up your bandwidth and get you added to the list of filtered sites.

Network Address Translation Characteristics of HTTP

HTTP does not use embedded IP addresses as a functional part of the protocol, so network address translation will not interfere with HTTP. Web pages may contain URLs written with IP addresses instead of hostnames, and those embedded IP addresses will not be translated. You should therefore be careful about the content of web pages on servers behind network address translators.

In addition, HTTP clients may provide name and/or IP address information to servers, leaking information about your internal numbering and naming schemes. HTTP clients may provide “From:” headers, telling the server the user’s email address (as the user told it to the browser), and proxies may add “Via:” headers indicating the IP addresses of proxies that a request (or response) has passed through.

Securing HTTP

You may hear discussions about secure versions of HTTP and wonder how they relate to firewalls and the configuring of services. Such discussions are mainly focused on the privacy issues of passing information around via HTTP. They don’t really help solve the kinds of problems we’ve been discussing in previous sections.

Two defined protocols actually provide privacy using encryption and strong authentication for HTTP. The one that everyone knows is usually called HTTPS and is denoted by using https in the URL. The other, almost unknown protocol, is called Secure HTTP and is denoted by using shttp in the URL.

The goal of HTTPS is to protect your communication channel when retrieving or sending data. HTTPS currently uses TLS and SSL to achieve this. Chapter 14, contains more technical information on TLS and SSL.

The goal of Secure HTTP is to protect individual objects rather than the communications channel. This allows, for example, individual pages on a web server to be digitally signed—a web client can check the signature when the page is downloaded. If someone replaces the page without re-signing, then the signature check will fail, causing an alert to be displayed. Similarly, a secure form that is submitted to a web server can be a self-contained digitally signed object. This means that the object can be stored and used later to prove or dispute the transaction.

The use of Secure HTTP could have significant advantages for the consumer in the world of electronic commerce. If a company claims that it has a digitally signed object indicating your desire to purchase 2,000 rubber chickens but the digital signature doesn’t match, then you can argue that you did not make the request. If the signature does match, then it can only mean one of two things; either you requested the chickens, or your private key has been stolen. In contrast, when you use HTTPS, your identity is not bound to the transaction but to the communication channel. This means that HTTPS cannot protect you from someone switching your order for rubber chickens to live ones, once it has been made, or just ordering chickens on your behalf.

Packet filtering characteristics of HTTPS and Secure HTTP

HTTPS uses a single TCP connection at port 443. Secure HTTP is designed to operate over port 80 (see the section on HTTP).

Direction

Source Addr.

Dest. Addr.

Protocol

Source Port

Dest. Port

ACK Set

Notes

In

Ext

Int

TCP

>1023

443

[7]

Request, external client to internal server

Out

Int

Ext

TCP

443

>1023

Yes

Response, internal server to external client

Out

Int

Ext

TCP

>1023

443

[7]

Request, internal client to external server

In

Ext

Int

TCP

443

>1023

Yes

Response, external server to internal client

[7] ACK is not set on the first packet of this type (establishing connection) but will be set on the rest.

Proxying characteristics of HTTPS and Secure HTTP

Because HTTPS and Secure HTTP use straightforward TCP connections, they are quite easy to proxy. Most programs that provide HTTP proxying also provide HTTPS and Secure HTTP proxying. However, both HTTPS and Secure HTTP use end-to-end encryption between the client and the server. This means that the data stream is entirely opaque to the proxy system, which cannot do any of the filtering or caching functions it does on normal HTTP connections.

Proxying for HTTPS is normally done using the CONNECT primitive (discussed earlier in the section on proxying HTTP). This allows the real client to exchange certificate information with the server, but it also serves as a generic proxy for any protocol running on the ports that the proxy allows for HTTPS. Since HTTPS is encrypted, the proxy can’t do any verification on the contents of the connection. You should be cautious about the ports that you allow for HTTPS.

Network address translation characteristics of HTTPS and Secure HTTP

Like HTTP, HTTPS and Secure HTTP have no embedded IP addresses and will work without problems through a network address translation system. Because of the end-to-end encryption, it will not be possible to correct any IP addresses that occur in the body of secured pages, so you should make sure that such pages use hostnames and not IP addresses.

Summary of Recommendations for HTTP

  • If you’re going to run an HTTP server, use a dedicated bastion host if possible.

  • If you’re going to run an HTTP server, carefully configure the HTTP server to control what it has access to; in particular, watch out for ways that someone could upload a program to the system somehow (via mail or FTP, for example) and then trick the HTTP server into executing it.

  • Carefully control the external programs your HTTP server can access.

  • You can’t allow internal hosts to access all HTTP servers without allowing them to access all TCP ports because some HTTP servers use nonstandard port numbers. If you don’t mind allowing your users access to all TCP ports, you can use packet filtering to examine the ACK bit to allow outgoing connections to those ports (but not incoming connections from those ports). If you do mind, then either restrict your users to servers on the standard port (80), or use some form of proxying.

  • Proxying HTTP is easy, and a caching proxy server offers network bandwidth benefits as well as security benefits.

  • Do not allow external connections to HTTP proxy servers.

  • Configure your HTTP clients carefully and warn your users not to reconfigure them based on external advice.

Mobile Code and Web-Related Languages

As we mentioned earlier, most web browsers support one or more ways of accepting arbitrary programs from servers. In general, systems that move programs from one machine to another are called mobile code systems. Although these systems are commonly implemented in web browsers, they may also be used other places. For instance, some web servers also support running them on the server itself; Java and ActiveX are used entirely independently of the Web for application development; and many web browsers that support using JavaScript and VBScript in web pages also interpret them when included in email or news messages.

Mobile code systems take two fundamental approaches to the security problem. Most of them attempt to keep programs from doing anything dangerous, or at least from doing anything dangerous without asking you about it first. For instance, JavaScript isn’t allowed to write files to your disk without your consent; Java isn’t allowed to open network connections to any server other than the one that your original connection was to. This approach results in web pages that can’t quite do what you want but can still do some things that you don’t want.

To avoid this problem, ActiveX takes the second approach and uses digital signatures to attempt to give you some idea where a program comes from, in the hope that this will tell you whether or not to trust it. There are no restrictions on what an ActiveX control can do. This approach results in web pages that you’re not certain whether or not to trust. Who is the person who signed it? Do you trust that person to be both well intentioned and competent to write security-critical programs? If a program is not signed, is it because the author is evil, or because the author is lazy, uneducated about digital signatures, or arguing with the signature authority?

These two approaches are being combined, allowing you to decide exactly what a program can do based on what you know about who wrote it. This is still imperfect, but it’s the most promising approach, and both Java and ActiveX are moving in this direction.

JavaScript

JavaScript is a scripting language that is completely unrelated to Java and is used as an extension language for web browsers. Microsoft’s implementation of JavaScript is called JScript; you may also see Microsoft refer to the language as ECMAScript because it has been standardized by the European Community Manufacturer’s Association (ECMA).

JavaScript attempts to provide security by limiting what it’s possible to do. For instance, JavaScript does not have commands for reading and writing files. Furthermore, programs written in JavaScript are supposed to be able to access only limited amounts of data: information about user preferences, available plug-ins and capabilities of the browser, and links and forms in the document that contains the script and in windows created by that web page. JavaScript programs can communicate to the outside world only by submitting forms.

A web page with a JavaScript program can contain something that is technically a form without being visible, and JavaScript can fill in that form with any information it can get to and submit it automatically. If your web browser is configured to ask for confirmation before submitting forms, you will see a warning; if not, the entire transaction will be silent. Furthermore, submitting a form simply consists of sending information in a predefined format to a URL, which can specify any IP address and port number. This means that submitting forms effectively lets JavaScript send any information it has to anybody it thinks should have it, possibly without notifying you. This is one of the reasons that web browsers warn you about form submissions, and it is a good reason for leaving these warnings in place.

Most JavaScript security problems fall into one of two categories: denial of service attacks that hang or crash the browser (or, if you’re really unlucky, the entire computer), and bugs in the data access limitations that allow JavaScript programs to read arbitrary files and return the data to the site that the page came from. In addition, there have been occasional buffer overflow problems with JavaScript implementations.

The denial of service attacks are, as usual, unavoidable, but they’re no worse than annoying. Ones that actually crash the browser or manage to affect the machine are straightforward implementation bugs, and fixes are usually rapidly available. The standard way to hang the browser is to code an infinite loop.

While JavaScript programs cannot directly open files, these programs can cause the web browser to open them by giving the browser local URLs to open (for instance, file:/etc/passwd). When the JavaScript security is correctly implemented, this is not a problem, since JavaScript still can’t get the data out of the newly opened URLs. However, there have been a series of bugs with the handling of this particular limitation, where the browser becomes confused about the correct context for scripts or data embedded in odd places. For instance, scripts in the titles of pages may be executed in the process of reading bookmarks, and scripts can manage to execute in windows that are supposed to be displaying source code. There have been dozens of bugs in context handling, all of which have roughly similar effects; the script returns data it shouldn’t have to the server it was on. That data ranges from information about sites that have been visited recently to the contents of arbitrary files on the disk.

The buffer overflow problems are, strictly speaking, not JavaScript vulnerabilities at all. They occur when the interpreter gets invalid JavaScript and the interpreter itself fails to enforce buffer limitations. There is a known problem with buffer overflows on some JavaScript calls in some versions of Internet Explorer 4.0.

JavaScript can use ActiveX or Java, if they are enabled, to get access to capabilities that JavaScript alone would not have. If ActiveX or Java is enabled in the browser, JavaScript can use them without containing any visible ActiveX or Java objects. This means that filtering out ActiveX and Java is not sufficient to protect a site. You must also filter out scripting languages or disable ActiveX and Java in all browsers.

VBScript

VBScript is a subset of Visual Basic provided by Microsoft as an extension language for web browsers and servers. VBScript provides much the same functionality that JavaScript does—in fact, Microsoft tries to maintain it at the same level. Like JavaScript, VBScript is designed to provide security by avoiding unsafe operations. VBScript is often used in conjunction with ActiveX, and VBScript security is often confused with ActiveX security, but there’s no need to enable ActiveX in order to use VBScript (nor do you need VBScript in order to use ActiveX; you can use ActiveX controls from JavaScript just as well).

There don’t appear to be any reported VBScript security problems; this does not indicate that VBScript is secure. What it does indicate is that JavaScript is implemented by more browsers than VBScript, while ActiveX is more powerful than VBScript. Therefore, attackers are going to concentrate on JavaScript and ActiveX until they’ve exhausted their obvious possibilities. Because VBScript provides the same capabilities that JavaScript does, VBScript vulnerabilities are likely to fall into the same sort of categories as JavaScript vulnerabilities, involving mostly denial of service attacks and ways to read data.

Java

Java is a full-fledged programming language that is commonly used as an extension language for web browsers. Java uses what is called a sandbox security model, which tries to provide security by limiting the functionality available to a program.

In general, programming languages are divided into interpreted languages and compiled languages. An interpreted language, like Perl or Visual Basic, is one where you write a program, and when you want to run it, you give it to an interpreter in the same form that you wrote it. The interpreter, which is run every time you run a program in the language, is responsible for turning human-readable commands into instructions the computer can execute. A compiled language, like C, is one where you write a program and run it through a compiler once to get an executable. You can then run the executable all by itself; you don’t need another program to make it run.

Interpreted languages are machine independent. You have a different interpreter for each kind of machine but run the same programs. Compiled languages, on the other hand, are machine dependent; once you compile a program, the result will run on only one kind of machine. On the other hand, a program that is running through an interpreter is slower than one that has been compiled. In addition, when you give somebody a program in an interpreted language, it’s easy for them to modify it and reuse it, while a compiled program is much more difficult to alter.

Java uses an intermediate option, sometimes called byte compiling. A program written in Java is compiled into machine-independent Java byte code, which is then turned into computer instructions by an interpreter usually called the Java Virtual Machine. This gives some of the advantages of compiled code (it’s faster to run than an interpreted language, and the code is not in an easily modifiable form) and some of the advantages of interpreted code (it’s machine independent). It also gives it many of the disadvantages of both; it’s slower than compiled code, you have to have an interpreter to do anything with it, and you can have problems with bugs in either the compiler or the interpreter. Just as it is possible for a determined person to write a program directly in machine language, without using a traditional compiler, it’s possible for a determined person to write a program directly in Java byte code, without using a Java compiler, and the result may be acceptable to the interpreter even if it couldn’t be generated from any program the compiler would accept.

There are security features in both the Java byte-code compiler and the Java runtime interpreter. In general, you should think of the Java compiler as providing security to Java programmers; it helps people write Java programs that cannot be attacked by hostile users. (For instance, Java programs are not susceptible to buffer overflow problems.) The Java interpreter provides security to Java users; it is supposed to keep hostile Java programs from damaging machines. Because people can write Java byte code directly, you can’t rely on the compiler to protect you from malicious programs.

Instead, what you’re relying on is something called the security manager, which is part of the runtime interpreter. The security manager is responsible for determining what a program is allowed to do. It does this by looking at each separate action the program attempts to take and comparing that to the security policy that’s in force. Normally, there are two possible security policies: one that covers normal programs, which doesn’t put any limitations in place, and one that covers programs that have been downloaded from the network, which restricts what files can be read and written, how much memory and disk space a program can use, and what network connections it can make.

The security manager doesn’t directly control the operations that the program performs. Instead, it controls what functions the program can call. For instance, insecure programs are not normally allowed to write to disk, but if there is a library that is supposed to be safe for use by insecure programs, an insecure program can call that library and have the library write to disk. Effectively, this is the same sort of restriction as allowing a child to eat cookies, but only if an adult gets the cookies; you are requiring transactions to go through a theoretically trustworthy intermediary that will impose limits on them.

There are two main risks to this model. First, there is the risk that the security manager will permit something that it should have denied. Second, there is the risk that a theoretically secure library will contain insecure operations. Java has had problems with both of these, but mostly with the security manager. The security manager has a very complex task, and it is extremely difficult to implement correctly. Since the original release of Java, people have found both implementation and design flaws with some regularity. Although these have been rapidly fixed for the most part, and the rate has considerably slowed down, it is reasonable to expect that there will be continuing problems.

ActiveX

ActiveX is not actually a programming language but a way of distributing objects that can then be used by multiple other languages. Unlike the other systems we have discussed, it distributes machine-specific code. A Java, JavaScript, or VBScript program will run on any machine that supports the language; an ActiveX control is an executable program targeted to a specific kind of processor, and you will not be able to run an ActiveX control built for an Intel processor on an Alpha processor, for instance.

ActiveX is an extension and update of Microsoft’s Object Linking and Embedding system (OLE). ActiveX controls can be written in any of a number of languages, including C and Visual Basic, and can be accessed from an even wider variety of languages. In the context of the Web, they are usually used from HTML, JavaScript, or VBScript, but they can be used from Java as well. No matter what language is used to access an ActiveX control, it is the ActiveX security model that applies to the control, not the calling language’s; this is important because it means that an ActiveX control used in a Java program will not be constrained by the Java sandbox.

ActiveX security is provided in two ways. First, there are limitations on when an ActiveX control can be read in; second, there are limitations on when an existing ActiveX control can be executed. These limitations are part of the implementation of the current ActiveX interpreters, not part of the language design, so there is no guarantee that future ActiveX implementations will have the same characteristics.

The most famous aspect of ActiveX security is its use of digital signatures, which is part of the security system for reading in ActiveX controls. An ActiveX control may be signed with a digital signature, which theoretically allows you to identify the author of the control and make a decision as to whether or not to allow the control to be loaded. ActiveX controls do not have to be signed, but unsigned controls are normally treated differently from signed controls. (See Appendix C, for further discussion of digital signatures and what they mean to you.) By default, unsigned controls from external web pages are rejected, and signed controls request confirmation.

Digital signatures are checked when a control is loaded, but once the control has been loaded, it has to be used in order for anything to happen. The ActiveX model also provides controls over when a control can be run. You can choose to allow controls to run, forbid them from running, or be asked every time something attempts to run a control. By default, controls are allowed to run without confirmation.

In addition, a control can claim to be safe for use with untrusted data and/or safe for use from scripts. By default, a control cannot be run by an external web page unless it claims both these properties. A control that claims both these properties is supposed to be one that will never do anything bad, even if used hostilely. Programs like Internet Explorer that use ActiveX objects look at these properties to decide whether or not to allow a control to be run. Aside from these restrictions, once a control has been loaded for any purpose, it is available from any program.

Note that this means that if a control is present on your local disk, and it claims to be safe for use with untrusted data and safe for use from scripts, any web page can run it, and no request for confirmation will be made before it is run. This can lead to unpleasant surprises. Many vendors have preinstalled ActiveX controls that will allow arbitrary commands to be run and have incorrectly marked them as safe for scripting. Not only have third-party vendors like Compaq shipped machines with dangerous ActiveX controls, but even Microsoft, in Windows 98, provided a control marked as safe for scripting that could be used to run arbitrary programs.

Obviously, the same sort of thing can be done with controls downloaded from web pages. You may download a control from one web site, which is then activated by another. Less obviously, if you go to a page and download a control once, when you revisit the page, it will attempt to download the control again. If you do not let it download the control, you will still have the original copy of the control installed, and the page will happily continue to run that copy, which is presumably not what you had in mind (if you wanted it to run the control, you would have let it download the control). People who have just clicked No on a download dialog box are usually surprised and outraged when the control runs, since the distinction between downloading and running is not normally user-visible.

Cache Communication Protocols

When we discussed proxying and HTTP, we also discussed caching, which is one of the primary uses of web proxies. Caching is very important as a way of speeding up transfers and reducing the amount of data transferred across crowded links. Once cache servers are set up, the next logical step is to use multiple cache servers and have them coordinate operations. A lot of active development is going on, and it’s not at all clear what protocol is going to win out in the long run.

Internet Cache Protocol (ICP)

ICP is the oldest of the cache management protocols in current use and is supported by the largest number of caches, including Netscape Proxy, Harvest, and Squid. The principle behind ICP is that cache servers operate independently, but when a cache server gets a request for a document that it does not have cached, it asks other cache servers for the document, and retrieves the document from its source only if no other cache server has the document. ICP has a number of drawbacks; it requires a considerable amount of communication between caches, it slows down document retrieval, it provides no security or authentication, and it searches the cache based only on URL, not on document header information, which may cause it to return incorrect document versions. On the other hand, it has the noticeable advantage of being both standardized (it is documented in IETF RFCs 2186 and 2187) and in widespread use.

Packet filtering characteristics of ICP

ICP normally uses UDP; the port number is configurable but defaults to 3130. ICP can also be run over TCP, once again at any port. Caches exchange documents via HTTP. Once again, the port used for HTTP is configurable, but it defaults to 3128.

Direction

Source Addr.

Dest. Addr.

Protocol

Source Port

Dest. Port

ACK Set

Notes

In

Ext

Int

UDP

>1023

3130[9]

[10]

ICP request or response, external cache to internal cache

Out

Int

Ext

UDP

3130[9]

>1023

[10]

ICP request or response, internal cache to external cache

In

Ext

Int

TCP

>1023

3128[13]

[14]

HTTP request, external cache to internal cache

Out

Int

Ext

TCP

3128[13]

>1023

Yes

HTTP response, internal cache to external cache

Out

Int

Ext

TCP

>1023

3128[13]

[14]

HTTP request, internal cache to external cache

In

Ext

Int

TCP

3128[13]

>1023

Yes

HTTP response, external cache to internal cache

[9] 3130 is the standard port number for ICP, but some servers run on different port numbers.

[10] UDP has no ACK equivalent.

[13] 3128 is the standard port number for intercache HTTP servers, but some servers run on different port numbers.

[14] ACK is not set on the first packet of this type (establishing connection) but will be set on the rest.

Proxying characteristics of ICP

ICP, like SMTP and NNTP, is a self-proxying protocol, one that allows for queries to be passed from server to server. In general, if you are configuring ICP in a firewall environment, you will use this facility and set all internal cache servers to peer with a cache server that’s part of the firewall and serves as a proxy.

Since ICP is a straightforward TCP-based protocol, it would also be possible to proxy it through a proxy system like SOCKS; the only difficulty is that you would end up with a one-way relationship, since the external cache would not be able to send queries to the internal cache. This would slow down performance without providing any more security than doing self-proxying, and no current implementations support it.

Network address translation characteristics of ICP

ICP does contain embedded IP addresses, but they aren’t actually used for anything. It will work without problems through network address translation systems, as long as you configure a static translation (to allow for requests from other peers) and don’t mind the fact that the internal address will be visible to anybody watching traffic.

Cache Array Routing Protocol (CARP)

CARP uses a completely different approach. Rather than having caches communicate with each other, CARP does load balancing between multiple cache servers by having a client or a proxy server use different caches for different requests, depending on the URL being requested and published information about the cache server. The information about available cache servers is distributed through HTTP, so CARP adds no extra protocol complexity. For both packet filtering and proxying, CARP is identical to other uses of HTTP. However, CARP does have difficulties with network address translation, since the documents it uses are guaranteed to have IP addresses in them (the addresses of the cache servers). Netscape and Microsoft both support CARP as well as ICP.

Web Cache Coordination Protocol (WCCP)

WCCP is a protocol developed by Cisco, which takes a third completely different approach. In order to use WCCP, you need a router that is placed so that it can intercept all HTTP traffic that should be handled by your cache servers. The router will detect any packet addressed to TCP port 80 at any destination and redirect the packet to a cache server. The cache server then replies directly to the requestor as if the request had been received normally. WCCP is used for communication between the router and the cache servers, so that the router knows what cache servers are currently running, what load each one is running under, and which URLs should be directed to which servers, and can appropriately balance traffic.

Packet filtering characteristics of WCCP

WCCP uses UDP at port 2048. In addition, routers that use WCCP redirect HTTP traffic to cache servers by encapsulating it in GRE packets (GRE is a form of IP over IP, discussed in Chapter 4). WCCP uses GRE protocol type hexadecimal 883E. Note that neither UDP nor GRE uses ACK bits.

Direction

Source Addr.

Dest. Addr.

Protocol

Source Port

Dest. Port

Notes

In

Ext

Int

UDP

[19]

2048

WCCP update, external participant to internal participant

Out

Int

Ext

UDP

[19]

2048

WCCP update, internal participant to external participant

In

Ext

Int

GRE

[21]

[21]

HTTP query redirected by external router to internal cache server

Out

Int

Ext

GRE

[21][21]

HTTP query redirected by internal router to external cache server

[19] The WCCP protocol does not define a source port; it is likely to be 2048.

[21] GRE does not have source or destination ports, only protocol types. WCCP uses protocol type hexadecimal 883E.

Proxying characteristics of WCCP

Because WCCP uses both UDP and GRE, it is going to be difficult to proxy. Although UDP proxies have become relatively common, GRE is still unknown territory for proxy servers.

Network address translation characteristics of WCCP

WCCP communications include embedded IP addresses and will not work through network address translation. The architecture of WCCP assumes that your router and your cache servers are near each other (in network terms) in any case.

Summary of Recommendations for Cache Communication Protocols

  • Cache management should either be private (between internal cache servers) or public (between a bastion host used to access the external world and external caches). Cache management protocols may cross parts of a firewall to reach a bastion host but should not go completely across the firewall between external and internal networks.

Push Technologies

HTTP is a system in which clients ask for the information that they want (this is referred to as a pull technology, where the client pulls the information). In some situations, it is desirable for the server to send the information without being asked (this is a push technology, where the server pushes the information). For instance, if you want to be informed of some event (a change in a stock price, the outcome of a baseball game, a news item about an area of interest), it’s most effective for you to inform the server about your interests once, and then have it send you the information when it becomes available. With standard HTTP, you would have to ask for the information repeatedly to see if it had arrived.

Around 1997, push technologies were predicted as the next big thing on the Web, the most exciting thing to happen since the introduction of TV. They have yet to get much acceptance, for a combination of reasons. First, users have a strong and well-founded suspicion that the main reason that vendors want push technologies is so that they can push advertisements and other information that the user wouldn’t have requested. Second, security and network bandwidth considerations cause site administrators to dislike the idea of having incoming unrequested information streams. At this moment, the magic application that would drive people to accept push technologies has not shown up, although there is a significant population that think the existing programs are really cool.

A number of competing programs still claim to be push technologies, although the number has been reduced in recent years. Currently, the popular programs (notably Pointcast and BackWeb) don’t actually have to be push-based. Instead, they give an illusion of being push-based by using special HTTP clients that make regular requests for updates to specialized HTTP servers that inform them of changes in the information the user is watching. This polling process is transparent to the user, who sees something that looks like it’s push-based.

This approach removes many of the difficulties with true push-based technologies. It doesn’t require a new protocol or inbound connections, for instance. On the other hand, it does use bandwidth as the clients check for updates. The specialized clients are generally aware of proxies but may not support all the same features that normal web browsers support (for instance, they don’t generally have support for auto-configuration of proxies or for proxy authentication schemes).

The specialized clients don’t tend to have the same security implications that traditional web browsers do (they don’t support extension languages or external viewers, for instance; they call normal web browsers to deal with complex pages). They do have their own security implications (for instance, the clients are providing information to the server as part of the queries they make and are accepting data from the server).

Some of the traditional web browsers also support things that look like push technology (for instance, Explorer has Active Channels and Netscape has Netcaster). These are in fact based on polling over normal HTTP, sometimes with additional information to optimize the polling. In general, their security implications are identical to those of normal web browsing. Note that if you are pulling web pages that require authentication information, either you will have to provide that information at the start of the download (so much for having it automatically updated while you sleep), or you will have to trust the program to safely store the authentication information. In addition, these services make local copies of the web pages, and you should be sure that those are appropriately protected.

There are also genuine push technologies in use, and both BackWeb and PointCast will run as genuine push technologies when they can, using their own protocols. It’s not clear what security implications these protocols have, since they’re proprietary. However, they accept inbound connections, often return data, and usually have little or no authentication. While there have not been many security problems with them so far, that may simply be because they are not popular enough to attract many attackers. Certainly there seems to be good reason to worry about their security. It is also possible to combine a traditional web browser with a specialized push client using plug-ins, and PointCast provides such a plug-in. The plug-in has the same security implications as the normal PointCast service.

Summary of Recommendations for Push Technologies

  • Do not pass push technologies through your firewall.

  • Discourage users from using the specialized clients that imitate push technologies using HTTP.

RealAudio and RealVideo

RealAudio and RealVideo are proprietary protocols developed by RealNetworks to provide real-time streaming of audio and video data across the Internet. Although the players for these protocols can run as independent applications, they are most frequently used as plug-ins to web browsers. At this writing, these are the most popular protocols for distributing relatively large amounts of audio or video.

The advantage of using them instead of simply distributing audio or video files is twofold. First, if a web browser encounters an audio or video file, it needs to download the entire file before playing it. This can mean a long and extremely boring wait if the file is eventually going to play for more than a few seconds. Few people are willing to hang around watching a transfer progress meter move for 20 minutes in order to watch a 10-second movie. Second, because the files are downloaded, users are not only able to make their own copies, they’re encouraged to do so; once they’ve waited the 20 minutes, they’re certainly not going to delete the local copy of the file! If you want to keep track of who’s watching the file when, and you don’t want copies of it floating around, this is extremely undesirable.

Protocols for distributing audio and video tend to based on UDP because people are more tolerant of having small amounts of data lost than of having pauses. With TCP, if a packet is lost, there will be a wait for retransmission, which is much more annoying than just going on to the next packet. Audio and video protocols also tend to use multiple ports in order to maximize efficiency. Because of these characteristics, these protocols tend to be difficult to support through firewalls.

Risks of RealServer

Running a server for RealAudio or RealVideo is not inherently dangerous; the protocol is a relatively safe one for the server. On the other hand, RealNetworks has had some problems with security, and both the Windows NT and the Unix server have been distributed with extremely risky installations. Be sure that configuration files are not world-writable, that created accounts have appropriate privileges and passwords, and that programs are not running with more privileges than they need. Since the servers represent a considerable load in any case, you may want to dedicate a bastion host to them; that will also help to contain any security problems.

Risks of RealAudio and RealVideo Clients

The RealAudio and RealVideo clients have relatively limited capabilities and have not had any known security problems. Because of the way the protocols work, it can be difficult to allow the clients to run effectively without opening large holes in your firewall, which is of course risky. However, the clients themselves are relatively low risk if you are able to safely get the data to them.

Packet Filtering Characteristics of RealAudio and RealVideo

RealAudio and RealVideo by default use a system where a TCP connection, initiated by the client, is used for session control, while the actual data is transferred using UDP. Multiple UDP ports may be used for the same session. Because this system is extremely difficult to permit through packet filters without creating significant extra vulnerabilities, it is possible to configure RealVideo and RealAudio clients to use TCP only (on port 7070) or to use TCP accompanied by UDP packets from a single port in the range 6970-7170, specified by the client.

Direction

Source Addr.

Dest. Addr.

Protocol

Source Port

Dest. Port

ACK Set

Notes

In

Ext

Int

TCP

>1023

7070

[25]

Request, external client to internal server

Out

Int

Ext

TCP

7070

>1023

Yes

Response session control, internal server to external client

Out

Int

Ext

UDP

6970-7170[26]

>1023

[27]

Response data, internal server to external client

Out

Int

Ext

TCP

>1023

7070

[25]

Request, internal client to external server

In

Ext

Int

TCP

7070

>1023

Yes

Response session control, external server to internal client

In

Ext

Int

UDP

6970-7170[26]

>1023

[27]

Response data, external server to internal client

[25] ACK is not set on the first packet of this type (establishing connection) but will be set on the rest.

[26] The client may select a specific port number in this range or may allow the server to choose any port in the range; if the latter, multiple ports may be used for the same session.

[27] UDP has no ACK equivalent.

Proxying Characteristics of RealAudio and RealVideo

RealNetworks provides sample code for RealAudio and RealVideo proxies for use if you would like to have your own. They also have worked with a number of firewall vendors to incorporate the proxy code into products. Using a proxy is the best solution to get reasonable performance of RealAudio and RealVideo through a firewall, since the tricks used to make it allowable through packet filters significantly decrease performance. However, the RealAudio and RealVideo proxies can put a fairly considerable load on a machine.

Network Address Translation Characteristics of RealAudio and RealVideo

RealAudio and RealVideo will work with network translation if they are configured to use TCP only; the UDP-based modes use embedded IP addresses. You will need a network address translation system that understands RealAudio and RealVideo to use UDP, but an appropriate module is available for Linux IP masquerading.

Summary Recommendations for RealAudio and RealVideo

  • Unless you need high performance, run RealAudio and RealVideo clients configured to use TCP only, and permit outbound TCP connections on port 7070.

  • If you need high performance on RealAudio and RealVideo clients, use RealNetworks’ proxies.

  • Run RealServer on a dedicated bastion host and configure it carefully.

Gopher and WAIS

Gopher is a menu-driven text-based tool for browsing through files and directories across the Internet. When a user selects a Gopher menu item, Gopher retrieves the specified file and displays it appropriately. This means that if a file is compressed, Gopher automatically uncompresses it; if it’s a GIF image, Gopher automatically runs a GIF viewer. Standalone Gopher clients are now rare, but many web browsers support the Gopher protocol, and Gopher servers can be an efficient way of providing access to non-HTML documents for users of web browsers. A Gopher server is provided as part of Microsoft’s Internet Information Server (IIS).

WAIS indexes large text databases so that they can be searched efficiently by simple keywords or more complicated Boolean expressions. For example, you can ask for all the documents that mention “firewalls” or all the documents that mention “firewalls” but don’t mention “fire marshals”. (You might do this to make sure you don’t get documents about literal firewalls.) WAIS was originally developed at Thinking Machines as a prototype information service and, for a while, was widely used on the Internet for things like mailing list archives and catalogs of various text-based information (library card catalogs, for example). It is now much more common for people to provide search engines on web pages using CGI, instead of using WAIS directly as an access protocol. Some web browsers will speak the WAIS protocol, but WAIS servers are quite rare these days.

It is unlikely that you will ever want to run a standalone Gopher or WAIS client. Using the support for these protocols that is built in to a web browser adds no additional risk to the risks already posed by HTTP.

You are also unlikely to run a WAIS server, but you might run a Gopher server. Gopher servers present the same basic security concerns as the servers for all of the other common Internet services, such as FTP and HTTP: Can attackers use this server to access something they shouldn’t? This is a particularly pressing problem on the Gopher server included as part of IIS, since many sites do not pay much attention to it, and may accidentally leave data where the Gopher server can read it. If you do not intend to run Gopher, turn it off; if you do intend to run it, be sure that it can read only information that you intend to make public.

For servers, you have to worry about what a malicious client can trick you into running. Like HTTP servers, some Gopher servers use auxiliary programs to generate Gopher pages on the fly. Gopher servers are therefore susceptible to the same kinds of problems as HTTP servers:

  • Can an attacker trick the auxiliary program?

  • Can the attacker upload a new auxiliary program and cause it to be run?

Like HTTP servers, Gopher servers also sometimes live on nonstandard ports, so those concerns are similar to HTTP as well. Some Gopher clients support transparent proxying (via SOCKS or other mechanisms), but many don’t.

Packet Filtering Characteristics of Gopher and WAIS

Gopher is a TCP-based service. Gopher clients use ports above 1023. Most Gopher servers use port 70, but some don’t; see the discussion of nonstandard server ports in Section 15.3.3, earlier in this chapter.

Direction

Source Addr.

Dest. Addr.

Protocol

Source Port

Dest. Port

ACK Set

Notes

In

Ext

Int

TCP

>1023

70[31]

[32]

Request, external client to internal server

Out

Int

Ext

TCP

70[31]

>1023

Yes

Response, internal server to external client

Out

Int

Ext

TCP

>1023

70[31]

[32]

Request, internal client to external server

In

Ext

Int

TCP

70[31]

>1023

Yes

Response, external server to internal client

[31] 70 is the standard port number for Gopher servers, but some servers run on different port numbers.

[32] ACK is not set on the first packet of this type (establishing connection) but will be set on the rest.

WAIS is a TCP-based service. WAIS clients use random ports above 1023. WAIS servers usually use port 210, but sometimes don’t; see the discussion of nonstandard server ports earlier, in the section on HTTP.

Direction

Source Addr.

Dest. Addr.

Protocol

Source Port

Dest. Port

ACK Set

Notes

In

Ext

Int

TCP

>1023

210[37]

[38]

Request, external client to internal server

Out

Int

Ext

TCP

210[37]

>1023

Yes

Response, internal server to external client

Out

Int

Ext

TCP

>1023

210[37]

[38]

Request, internal client to external server

In

Ext

Int

TCP

210[37]

>1023

Yes

Response, external server to internal client

[37] 210 is the standard port number for WAIS servers, but some servers run on different port numbers.

[38] ACK is not set on the first packet of this type (establishing connection) but will be set on the rest.

Proxying Characteristics of Gopher and WAIS

If you use a proxying Web browser like Netscape Navigator or Internet Explorer to access WAIS or Gopher, you automatically get proxy support using SOCKS and/or HTTP proxying.

In the unlikely event that you wish to use some other Gopher client, the TIS FWTK http-gw proxy server can serve Gopher as well as HTTP. SOCKS does not include a modified Gopher client, but Gopher clients are, in general, not difficult to modify to use SOCKS; many of the Gopher clients freely available on the Internet support SOCKS as either a compile-time or runtime option.

As a straightforward single-connection protocol with plenty of user-specified information, WAIS lends itself to both modified-client and modified-procedure proxying. SOCKS support is commonly available in standalone WAIS clients.

Network Address Translation Characteristics of Gopher and WAIS

Gopher and WAIS do not use embedded IP addresses and will work with network address translation without problems.

Summary of Recommendations for Gopher and WAIS

  • If you’re going to run a Gopher server, carefully configure the Gopher server to control what it has access to; in particular, watch out for ways that someone could upload a program to a Gopher system somehow (via mail or FTP, for example) and then execute it via the Gopher server.

  • Carefully control the external programs your Gopher server can access.

  • Don’t run a WAIS server.

  • Use a web browser such as Internet Explorer or Netscape Navigator for your Gopher and WAIS clients, rather than using dedicated clients.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.86.155