Security Model

Although Web applications have been relatively quick and easy to implement and deploy, several aspects have historically been neglected due to time constraints and a lack of appreciation for their importance. One might argue that testing is the prime victim of this neglect and make a pretty convincing case. However, I do believe that security has suffered most from the short timeframes and rushed projects that have been expected of this new development paradigm.

A false sense of security (no pun intended) has prevailed over Web developers and caused them to neglect the security requirements for their applications. Some developers are all too eager to defer to infrastructure experts to take care of their applications. Although a lot can be done on the network and system level, nothing will prevent a malicious visitor from attacking an application hole left by developers. Essentially, effective security can never be applied externally to a distributed application and must instead come from within.

Security is essential to building successful Web services and making their use widespread. If providers can't feel safe behind Web services, they won't deploy them. If consumers can't trust Web services, they won't use them. It is really that simple, and it is really that critical.

When it comes to security for Web services, there are four areas of concern: authorization for system access, application authentication, transport integrity, and payload validation. These are all areas of concern that Web developers have when designing and deploying applications, but there are some special concerns in each of these areas specific to Web services. Because Web services expose processes over the Internet and do not just share Web pages, it is critical that these four areas be thoroughly addressed to protect the provider, the consumer, and the end users.

The first two, authorization and authentication, you might be familiar with, because they apply to many current Web applications. However, process execution is a new exposure risk that providers of Web services need to guard against. Because the level of exposure is no longer strictly on the presentation layer, there is a slightly higher potential for vulnerabilities in your system.

System Access

It is easy to blur the lines between access and authentication, so for that reason I am clarifying my use of these terms by prefixing system and application, respectively. Fundamentally, access is a different concept, but discussions concerning the distinctions between authentication and access can get somewhat convoluted.

Basically, access is an initial qualification that allows a group or category of users to access a system. System accessibility consists of checks that are performed on a system level before you even reach the applications on your system. This means that you don't know who the user is, but you do know that the user meets the correct criteria. These criteria generally consist of having a valid physical connection on the network and supporting the necessary protocols to establish a connection. (See Figure 5-28.)


Figure 5-28: Typical system access process for Web servers

For many systems, acceptable credentials consist of connecting to the Internet, supporting HTTP, and supporting basic authentication. Once access is established, this same information can be used to help authenticate a user, but these two processes should not be confused as one.

You would approach the security considerations around system access for a Web service in much the same way you would for a Web application. The difference comes from recognizing who your audience is and what you are exposing to that audience.

The audience for your Web services is the consumer. That means access will always be defined on the consumer level and not the user level. Essentially, users piggyback the connections that the consumer establishes with your service. This is both a blessing and a curse, because you have to establish access for a much smaller group, but have no control over access on a user-by-user basis. To help with the latter concern, you simply must have a well-planned and well-designed authentication model.

What you are exposing to that defined audience is much more than just Web pages. Even sensitive Web applications do not have the level of exposure that Web services bring, because Web applications have an additional layer, the presentation, that can be used to restrict access to your data and processes. With Web services, you allow consumers to execute your logic and access data programmatically. This adds to the risk of your implementation, but there are practices you can put in place to mitigate any potential issues.

A few questions need to be answered to help determine the best access model for your Web service. The first is who your target consumers are. If you develop a service for internal use, it probably makes sense to keep the Web service inside your network, on an intranet, to prevent outside access. In contrast, a Web service meant for public consumption likely belongs in your DMZ or at a hosting provider, just as a Web server would.

DMZ stands for demilitarized zone and is really a tongue-in-cheek name for a section of your network that lies between the Internet and an internal, proprietary network. The DMZ is where organizations typically host any systems that are accessible from the Internet. This area is protected by firewalls that make it somewhat secure, but not as secure as the organization's internal network, as we will see in Figure 5-29.

click to expand
Figure 5-29: Direct versus proxied Web services calls to application servers

The next question to answer is whether your Web service is meant for public or proprietary consumption. If your Web service is for the public at large, then nothing more really needs to be done. If it is meant to be proprietary, you may want to restrict access further by specifying the IP addresses of consumer systems or by requiring client certificates. Although these mechanisms start to lead us into authentication, their initial use is for allowing access to the system.

The final decision you need to make for your security model is on what physical model you want to host your Web services. Access is determined, to a large extent, by the physical connectivity of the outside world to your services. We have already talked about a DMZ, which involves firewalls and routers. That part has already been determined. However, one more option you have is whether you want consumers to hit your application servers directly or proxy the call to an internal application server. In the direct physical model (Figure 5-29, route 2), the Web service call is received by the application server that runs all processes locally and accesses data contained on the internal network. The alternative physical model (Figure 5-29, route 1) requires establishing a middleware proxy server that can accept the Web service calls and route them to the appropriate application server residing on the internal network.

The first benefit to the proxy approach is greater isolation of your services from consumers. Having an additional layer will always provide more security, because it adds one more barrier to potential hackers. Some might argue that ports 80 and 443 are safe enough to allow any traffic through, as many firewalls do today. Although you are limited in your capabilities through these ports, there have been plenty of documented cases in which data and program logic have been compromised through them on various platforms. The bottom line is that, if a system routing Web service requests is compromised, there will be far fewer systems and resources that can be exploited, and it will be easier to repair or replace than the actual application server.

The benefits of a proxy configuration also extend beyond security by allowing you to aggregate value-added services at a single location. For instance, you can aggregate authentication services to a single system instead of having to implement those features on your application server. This is of even greater value if you provide many Web services that actually run on multiple application servers. A proxy configuration can act as an infrastructure platform that serves as a conduit for all Web services. (See Figure 5-30.) Such a configuration not only allows you seamless scalability, but also reduces deployment effort for each Web service launched.

click to expand
Figure 5-30: Proxy Web server as conduit for multiple Web services

Once the decisions around access security have been made, it is time to address authentication security. Some of these decisions are related to the choices made around the access model.

Application Authentication

Authentication for Web services is probably one of the more complex components that has to be addressed in the security model. The reason is that it has several aspects, and it can be a challenge just to identify them, much less address them. As with other applications, you need one mechanism for authenticating users and another one for defining the logic that uses that knowledge to establish rights.

The goal of authentication is to provide the right functionality with the appropriate data to the right users. This process starts by selecting a method for authenticating the users of your service. Even this step is not so simple when you consider the fact that Web services have potentially two users: the consumer and the end user. Furthermore, because the end user has no direct connection to a Web service, you are at the mercy of your consumers to facilitate authentication of the user on a meaningful level.

This might make you feel hesitant about your use of Web services, but there are many cases where that type of business relationship exists. The best example might be credit card companies and the merchants that execute transactions against the credit they provide to shoppers. The credit card company has no guarantee of verification that the actual owner of the card is the one using it. Instead, the credit card company must rely on the merchants to confirm their identity through a signature or photo ID. When fraud does take place, agreements are in place concerning how the situation will be handled. The same approach must apply to Web services. The providers have to trust their consumers, but they must have agreements and policies established for when fraudulent uses occur.

The second component of the security model is the authentication logic. This is how you use the knowledge of who is using your application by providing specific functions and/or showing specific information. You have to determine through your security model what these conditions are and how they will be handled. If you look at the functionality specific to each type of user, you can start to understand what you have to accomplish. This part of the model involves selecting the services and mechanisms you will implement to help manage these defined roles and privileges.

Authentication Mechanisms

When determining which authentication method(s) to implement, you have to consider whose identity you are trying to determine and capture. For some Web services, you will only be concerned with the consumer calling your applications. (See Figure 5-31, top scenario.) For other Web services, you will also be concerned with the user connecting through the consumer's application. (See Figure 5-31, bottom scenario.) There will also be Web services that must support both scenarios. Making this determination is the first step to formulating your authentication model.

click to expand
Figure 5-31: Authentication scenarios

Consumers Authentication

The consumers of your Web services will be establishing direct connections with you over Internet protocols, so a host of established authentication options are available to you. In fact, you may have used some of these options for Web applications that you have previously developed.

The two main criteria for such a solution is that it work over existing Internet protocols and that it be stateless. The first criterion should be obvious to you, but the second one might not be if you haven't analyzed the authentication processes available for Internet applications. Your immediate thought might be that authentication is only needed during the first call. This may be true for some applications, but you cannot depend on this in a Web application.

If an application maintains state with its clients, that state is managed through a logical session, which is an artificial mechanism for streamlining the authentication process. Instead of going through the process of verifying the identity of the client for every interaction, a proprietary method is used to identify the user uniquely and reference the previously associated information. One way of implementing this is through a cookie containing an identification number that is stored in a relational database.

However, sessions can and do die, so Web services and their developers should not depend on the existence of sessions for proper execution. Sessions are merely conveniences that can improve performance by limiting the amount of costly authentication attempts. For any given interaction, authentication may be necessary, regardless of the current state. Therefore, the mechanism must be stateless to be consistently available, regardless of whether it is actually needed.

Tip 

Sessions can be great tools for improving performance, so I certainly don't mean to discourage their use. In fact, I very much encourage using them for workflow Web services. When multiple sequential calls are necessary, reducing the amount of overhead can go a long way to helping improve your performance and scalability.

Many Web sites and applications support anonymous use, and that is an option for Web services. However, service providers are likely to be a little more guarded of their logic and data than they are of their content. As a result, the currently available options might seem limited compared to the demand that is likely to be generated. This is likely to change as Web services become more widely adopted.

Fortunately, the available options can meet your two criteria and so are also suitable for Web services. Some of these are standardized, and some are not. Standardized authentication methods are nice because many of the Web servers you will use to deploy your services will support them. This is very convenient because these Web servers often offer additional services around these authentication methods to reduce the amount of logic necessary to perform and maintain the actual authentication. However, these authentication methods can also be a little more complex for consumers to use because their applications need to integrate this client functionality. This will likely be a new challenge because the client side of these mechanisms is readily available in browsers and therefore taken for granted in applications.

Probably the most popular authentication method for Web applications is the account infrastructure. The user enters a user-specific username and password, and that information is verified against a data store of accounts. This can be very convenient to support when it takes advantage of an existing account infrastructure, like a domain or directory service.

Custom account structures are also common and can be effective. They require a little more time to implement, but they do allow maximum customization to meet the necessary requirements. In this case, an ID is usually generated or referenced on authentication to maintain the session to prevent the need for rekeying of the information.

One of the most powerful options available is a public key infrastructure (PKI). This standardized solution uses client certificates and server certificates to allow both the client and server to confirm the identities of each other as well as communicate securely. Although many developers are probably familiar with server certificates because of their use of SSL for HTTPS, some developers might not be experienced with implementing client certificates. This is a good example of the type of functionality that has been taken for granted in the past. It shouldn't be a major barrier to implementation, just a slight adjustment to timeframe expectations. We will look at the specifics of implementing client certificates in Chapter 6.

User Authentication

Whereas some existing mechanisms are available to help with consumer authentication, nothing is really established to handle user authentication. The methods discussed for authenticating the consumer are usually applied to users in Web applications, but Web services have a very unique relationship with their users. Because there is no direct communication with the user, any authentication method has to circumnavigate the consumer's application. This precludes all of the standardized mechanisms available today.

Instead, we have to take the custom approach. In fact, we have to take the custom account structure approach discussed as an option for authenticating the consumer. The user is identified through some mechanism (usually personal data or an arbitrary ID) and tracked through a unique data element. This data element must be communicated through the payloads between the consumer and provider, with the provider entrusting the consumer with its integrity.

Although this may not seem very secure, it actually can be as secure as necessary. There are not too many scenarios to consider for security concerns. One scenario calls sensitive data to be collected by the consumer application on behalf of the Web service. In the case of a browser-based application, the user shares this data with the consumer, and nothing can prevent the consumer from recording the data before passing it on to the service. However, the consumer is a visible player in the process because they share the ownership of the data with the Web service.

If encryption of this data is necessary to prevent the consumer from "seeing" it, a very different solution is called for. Although this is a possibility, it requires custom clients to accommodate this kind of complexity, since standard HTTP protocols are insufficient. This necessitates some form of peer-to-peer architecture, which establishes a three-way communication link in which the user communicates with the Web service provider and consumer application. (See Figure 5-32.) Any detailed discussion of this type of solution falls outside the scope of this book. Here I will focus on the applications and scenarios in which the user establishes only one connection with the interface application and does not connect directly with Web service providers.

click to expand
Figure 5-32: Peer-to-peer communication with Web services

This solution is probably not a realistic option in the immediate future unless you are already distributing a client application. Devices might be the early adopters in implementing this type of solution, because they are more proprietary in nature.

  • The term device refers to wired or wireless equipment that has custom clients, which can be customized to provide certain functionality and features. Although there are many attempts to standardize the communication with these devices, the clients themselves are much more proprietary than the Web browsers that most people are accustomed to.

Another scenario might involve sending information across various services in an application "chain." In this case, the interface owner can encrypt the data for safe passage through the other service providers for the destination service. (See Figure 5-33.) Only scenarios in which one of those providers has additional information to provide the Web service are really of any value. This is because these "middleware" services cannot touch or work with that data. If they are not adding value, they can possibly be removed from that section of the process altogether.

click to expand
Figure 5-33: Encrypting data between the application provider and the Web service provider

This partner relationship is unique because the Web service provider is establishing a business relationship with its consumer, but yet does not entrust the consumer with the user data collected by the interface owner. In fact, this scenario may seem so ridiculous that you might think it impractical. Consider the following scenario: a travel site establishes a partnership with a credit card company that wants to reduce the amount of risk for its merchants by eliminating them from the payment process. Companies might not want to become some of the latest victims getting burned for compromising the credit card numbers, but obviously they still want to get paid. Even though the reservation goes through the hotel merchant, that merchant needs to see only certain data (the person's identity, travel dates, and so on) and can simply hand off the encrypted credit card data, unencrypted personal data, and the hotel merchant's own information to the service to get paid. The credit card service responds with a confirmation and/or an authorization number for tracking purposes, but at no point does the hotel touch the actual credit card data. This reduces the risk for the merchant and the credit card company.

Once we have determined our methods for authenticating our consumers' and users' identities, we need to use this information to determine how the service should behave. This is where our application's authentication logic takes over.

Authentication Logic

Authentication logic refers to the logic that utilizes the identities of our consumers and users. This logic consists of a series or rules that dictate what can or cannot be done by a user and/or consumer. Many developers think of these rules as permissions, but it is potentially a little more complex than that. Some situations call for some state information to be maintained that is specific to our users and consumers. For this reason, I like to split up these rules into two components: roles and profiles.

Before getting into the specifics of rules, I will discuss the options available for implementing this functionality. At least some of this logic needs to be referenced directly by the Web service. That means it must exist in some object or data source that is compatible with your Web services listener.

One necessary decision is how to encapsulate your authentication logic. It can be another object referenced externally, or it can be a module added internally to your service. Creating an external object allows for maximum reusability, but it also forces the application to depend more on it. This process is basically reduced to a call that says, "This user wants to do such-and-such. Should I let the user do this?" This isn't difficult to implement, but there is also an access question. What if you need to filter data based on the user's identity? You can't answer that question with a simple response. The authentication logic either has to hand the authentication rules over to the object, allowing the object to filter based on the user's identity, or the authentication logic must retrieve the data for you. The first option is somewhat inefficient, and the second probably extends the functionality of the authentication object and expands its scope, thereby compromising the design.

The alternative is to simply have an object that hands the application the necessary information to make its own determinations. For example, once a user is authenticated, the application can ask for a user ID, an access level, and perhaps the roles that the person fills. This is usually a more extensible solution that will best accommodate future needs.

Regardless of how it is designed, this authentication logic allows the Web service to act on the established rules for the service for the identified users. Keep in mind that this logic can become quite complex if the application has very granular access rules that depend upon multiple criteria (like role, geographic location, and access level). It is important that you define the scope of your rules first, and then define the scope and responsibilities of the authentication logic. You then have to be certain you fill in any security gaps between that logic and the Web service.

The rules themselves can be stored through a wide range of solutions, but they will generally be external to the service itself. When establishing the rules for user privileges in your applications, you will benefit from having an isolated location. Some developers tend to embed these rules in the application itself, but this makes maintenance and support very difficult and should be discouraged. This is the equivalent of embedding database query code in an application. At the very least, the definition of who can do what should be kept in an external data store that the application can reference. Even this solution, while very scalable, is not efficient for data that may be accessed frequently.

Many vendors have developed directory service offerings to allow the integration of this information in a central location. This allows developers to avoid duplication of effort for every application developed and deployed. Examples of these solutions include Novell's eDirectory, Microsoft's Active Directory, and the iPlanet Directory Server. You can find a listing of several vendor offerings at http://www.directoryservice.com.

Once data is located in a directory, you need to utilize an interface to retrieve information from it. This is the equivalent to using a data connection string to access a database. LDAP (Lightweight Directory Access Protocol) is probably the most popular standard interface for accessing directory data. It provides a very efficient mechanism for retrieving rules by holding them in memory and referencing the supporting database only when necessary.

Other efforts like DSML (Directory Services Markup Language) are also underway to establish XML-based standards for accessing this information. Most directory services support at least a couple of options for accessing the information, so you should not have to address this issue in your security model.

The tradeoff here is that this solution is not as scalable as the database. Splitting the source into two or more physical parts on separate systems or resources can sometimes mitigate this limitation, but it still ultimately falls short of the capacity of an enterprise-level relational database.

Keep in mind that we have potentially two players interacting with our Web services. When this is the case, you should have two different authentication processes designed that cater to the connection you have with each type of user.

As far as sourcing the authentication data, it is important that you keep these users separated at least logically because the consumer and user roles are fundamentally different. That doesn't necessarily mean that they need to be kept in separate physical sources, however. These two participants can be defined through different roles in the same structure, so don't necessarily plan a two-source implementation by default. There will be scenarios that benefit from each approach, with role volumes and scalability requirements having the most impact.

Figure 5-34 shows a logical view of how the authentication logic components may be deployed in a Web services infrastructure. Here you see a distinct separation of the two user models from each other and the application logic.

click to expand
Figure 5-34: Sourcing consumer and user authentication data

Chapters 6 and 7 look more at specific implementations. It is crucial to have a strategy for storing your rules that meets the needs of your service. These decisions can affect your design, because they may have inherent limitations and/or benefits in how you implement your rules and logic.

Roles

When you identify the user types for a given process or application, you are essentially defining roles. An application may have only a single role, or it may have dozens. A user may belong to only one role or several. These are the things that have to be identified before authentication can be effectively implemented. This is where roles are defined.

Does a consumer have access to a specific function of a Web service? Does the user have the right to reference data submitted by others? Can a consumer reference its users' activity on the Web service? Again, these decisions can be more difficult to answer than in traditional Web applications if you are authenticating two users (the consumer and end user), not just one.

Once roles are defined, the authentication logic section of your security model begs you to complete two steps. The first is to identify your method for associating roles with users. Role association is done in one of two ways: either users are assigned to roles, or roles are assigned to each user. For simplicity's sake, you should consider that in one case the user is a container for the role(s), and in the other the role is a container for the users. (See Figure 5-35.) It can make a big difference which approach you take, because you might find limitations in your designs based on this choice.

click to expand
Figure 5-35: Container representation of user-to-role association

In the case of the user-based approach, roles are treated as properties of the users. Conversely, because users are usually treated as objects (because they almost always have their own profile data like first and last name and so on), the roles that users are assigned to will likely take the form of groups. It is easier for an application to incorporate the logic necessary to find a user's role by referencing the user (for example, looking in the user's container). However, this means that a user might be limited to fill only one role, or at least some finite number of roles if the user properties are unable to grow dynamically. A directory or data service that supports array-based properties can overcome this limitation by growing on demand without affecting the structure of your defined user profile. Otherwise, you will need to associate users to roles, which means that the application must "hunt" through each role container looking for the current user. This searching is much less efficient than the previous solution of looking directly within the scope of a single user. For this reason, I prefer implementing directory services that can accommodate variable attributes that can take the user-based approach for assigning roles.

Note 

The actual efficiency of these methods varies quite a bit depending on the service selected to contain the authentication rules. As a rule, the user-based approach performs better, but the magnitude of that difference varies among services.

A slight twist to this scenario is when roles are defined on a group level and users are associated with a given group. This situation has the same options available, but the implementation differs slightly, because you are adding an extra layer between the users and their roles. Most directory services allow you to easily reference the group given a user, and from there you can treat the roles as properties of the group or treat roles as containers for the groups.

The second step necessary for completing the authentication logic portion of your security model is identifying your approach to assigning rights. Once your roles are defined, you usually find that a majority of your users have either maximum rights or minimal rights. This leads you to a determination of whether you take the optimistic or pessimistic approach to assigning access rights.

The optimistic approach means that you assume the maximum rights and take away for those users who fall within the exception. The pessimistic approach, conversely, allows the minimum rights and adds as necessary for the exceptions. Each of these can be beneficial from a maintenance standpoint if you are catering to a larger percentage of your user population with a default configuration. However, in the case in which sensitive information can be compromised, it is always best to take the pessimistic approach to mitigate the possibility of human error. Although mistakes are always possible, the optimistic approach tends to overexpose the application, whereas the pessimistic approach underexposes, which is usually safer.

What is important about roles is that they are predetermined for the user by some administrator or superuser. These roles may change, but users certainly don't have the ability to change their own roles automatically. There likely will be information that the user controls. That is where the user profile comes into play.

Profiles

On an individual level, some data or information usually falls within a user's control. This might be personal information, preference information, or both. The idea behind profiles for Web services is very much a personalization of the process, especially when presentation services are provided. One example of utilizing profiles in the CD search service is not showing any polka music because prior feedback collected from the user told us he or she doesn't like polka music. It is easy to confuse this concept with that of roles, but essentially we are catering the service based on user preferences, and not their affiliation with a group.

Profiles can be so broad in their scope that it is very likely that they cross multiple data sources. In the case of low-level state information (like preferences), it may be stored in a cache system for maximum performance. In the case of sensitive personal information, an enterprise-level database should likely be utilized for maximum security.

In the case of Web services, both consumers and users are likely to have profiles. However, the type and use of this information will likely vary between the two. In fact, by nature of the design, the consumers are likely to have more profile data than role information. Even though the profile data is stored under the consumer, it is still most likely to manifest itself through the consumer's use of the service. For instance, in our earlier example of the music search service, we eliminated polka music based on the user's profile. If we have a country music site that wants to be a consumer of our service, they may want to restrict all searches to country music.

Profile data is most suitable to reference from some sort of cache system. The user profile is likely to contain more sensitive information and thus be maintained in a database. (See Figure 5-36.) This is also justified from a performance standpoint because a consumer always has more frequent connections to a service than any given user. After all, many users will be utilizing the service through a single consumer. This means the greater performance gain is had if state information is more readily available for the consumers than for the users. Also, the consumer's portion of the payload is likely to be less sensitive because the consumer will have a previously established relationship and the user may be using the service for the very first time. A new user might have to pass the information necessary to establish identification and perhaps even an account with the Web services provider.

click to expand
Figure 5-36: Profile storage for the consumer and user

The exception to a heavy cache-based consumer data solution might be in a fee-based Web service. If the provider wants to make certain that it is capturing the activity for a given consumer, or especially any payment data, it will likely store that information in a more robust and secure system. In general, though, the storage ratio for profile information between cache and relational data will probably trend toward 80:20 for the consumer and 20:80 for the user.

Because we now have our players identified and know our options for handling the security issues around that process, we need to turn our attention to the communication between them. We need to make sure that no one can intercept the transmissions between these two participants, thus compromising the data.

Transport Integrity

Like any information sent via the Internet, Web services payloads sometimes require discretion. In many cases, this data is not actually sensitive in nature, but the perception of the Web service by the consumer and/or provider might be better served by implementing a security solution to ensure the integrity of the transport.

By ensuring the security of our transmissions, we are trying to avoid basically two risks. First is the vulnerability of any of our communication over the Internet being intercepted and the data in the payload becoming compromised. This does not affect the application directly, but it can affect the reputation of the parties involved, especially when they are sharing user information.

The second potential vulnerability during transmission is for someone to not only intercept but to modify the payload before passing it on. This takes quite a bit of ingenuity on the part of a hacker, but it is a possibility. Payload validation (discussed in the next section) can sometimes mitigate this risk. However, something else that can mitigate both of these risks is encryption.

Encryption is the process of encoding a transmission based on some key or code that allows only the involved parties to correctly decode, or interpret, the information. As a Web developer, you use encryption whenever you deploy a site requiring SSL (Secure Sockets Layer). It just so happens that this same technology can also help the client to verify the identity of the provider. Many solutions in this area include authentication necessarily because the identification of the sender and/or receiver needs to be verified as part of the key acceptance process.

  • MD5 is a compression and encryption algorithm that allows data to be securely sent between participants. It uses a private key to generate a 128-bit string, similar to a hash process.

Other solutions that take advantage of this type of methodology include MD5, Smart Cards, and Kerberos. Each of these solutions can be effective when implemented properly. Therein lies the risk, however, because you depend on the consumer of your services to implement its side of the solution correctly. In some cases, this may require your involvement, so you should consider this carefully when a solution is defined.

  • Kerberos is a network authentication protocol that allows clients and servers to prove their identity securely through encrypted data. Once authentication has occurred, all communication can utilize this same encryption method.

Even when you encrypt the payload and verify the consumer's identity, your application still has a vulnerability exposed through your Web services. If a consumer makes a request of a Web service with an invalid payload, what are the consequences for the provider?

Payload Validation

Payload validation is something that most developers likely take for granted because they are used to working with languages, tools, and/or models that have built-in controls for handling these issues. In the case of Web services, we are exposed to this problem because there are no mechanisms to catch it for us.

The main concern with corrupt payloads is in protecting the provider from wasted cycles and, even worse, downtime. The interface for Web services is not as rigid as it is for RPC models, so getting a service to accept and attempt to process an illegal request is not as difficult.

  • RPC stands for remote procedure call. This is the process of calling external entities to an application to execute a given process. Any object or component call would be an RPC.

Because we are dealing with XML, which is often not strictly data typed, there is no mechanism for immediately rejecting a request based on data type mismatches. If you allow this to go unchecked, you are asking for problems once you start working with the data.

Tip 

Because even a Web service request that is rejected wastes precious cycles on your system as a provider, it is always beneficial to offer some client-side validation code as value-added content for your Web services. The consumer may not be motivated enough (or possibly even knowledgeable enough) to provide this valuable functionality on its own. Although you don't want to rely on it for the success of your process, it is always better to catch issues earlier on in the process (before taxing your systems).

You can take two approaches to handling invalid data: reactive and proactive. The first is to allow the data to go unchecked by the application up front and build extremely graceful error handling to protect the involved service and its processes. This can be very difficult depending on the platform, language, and parser you are developing your Web services on.

The proactive approach means that you are performing extensive payload checking before processing it to ensure that the entire process runs smoothly. Although this provides better protection for the process and user experience, it can also be very demanding of your application resources. We will look at some of the best practices for making the most efficient use of your systems.

When performing payload validation, you will want to inspect two aspects: payload structure and payload data. Each offers its own challenges in securing your Web service offerings.

Payload Structure

The payload structure refers to the actual composition of the payload, not the data in it. Because a Web service's interface consists of an XML document, this basically boils down to the well-formedness of the call. The consumer needs to make sure it sends a well-formed XML document out to the provider, and the provider needs to ensure that it receives a well-formed XML document.

If you use a standard mechanism for parsing XML, like the DOM or SAX, you perform this check whether you want to or not. The trick is to handle this check gracefully so that you can provide some meaningful level of information back to the consumer and/or user. The difficulty with this is that your selected parser, and even the version of the parser you are using, dictates how you should handle an inappropriate call.

Conversely, if you write your own custom routine for parsing the XML, you have to also build the logic for checking well-formedness. This can be quite a bit of effort, so I recommend getting familiar with one of the existing parsers and using it. Although you can possibly get by without performing this check, you are setting a bad precedent and getting away from the concept of sharing your processes by not requiring proper XML data.

It is very important that you get familiar with how your parser handles inconsistencies and problems it discovers with the XML data when it is loaded. Some of the original parsers actually crashed when referencing invalid XML documents. Others either produce an error and stop or produce an error and then continue. It is important to know which approach your parser takes.

Once the application has validated the structure, we need to turn our attention to the data itself.

Payload Data

Validating the data in a payload can be a very intensive process. Again, we are interested in protecting the service itself. Although less harm can come from simply invalid data, it can still potentially kill a process if it is not handled correctly.

As discussed in Chapter 3's section on defining XML, the provider should always have a schema or DTD available to define the interfaces for its Web services. This is key to equipping your consumers with the right information to communicate properly with your Web services. By referencing that information, it is relatively easy to build a payload through either a manual or programmatic process. This definition will also serve you well, as the provider, by helping to programmatically validate the data once it is received.

Depending on your preference, you can also opt to build an XSL stylesheet that can validate the data. This affords you the opportunity to get more specifics on the errors, as well as an avenue for providing detailed messages back to the consumer concerning the error(s).

To use either the schema validation or the XSL approach, you need to use an XML processor. Again, knowing how your selected processor behaves is crucial to providing a reliable application.




Architecting Web Services
Architecting Web Services
ISBN: 1893115585
EAN: 2147483647
Year: 2001
Pages: 77

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net