 |
posted on Tuesday, February 09, 2010 4:18 AM
The W3C specification now offers the means by which cross-origin AJAX requests can be achieved. Leveraging network and application network services in conjunction with application-specific logic improves security of allowing cross-domain requests and has some hidden efficiency benefits, too. The latest version of the W3C working draft on “Cross-Origin Resource Sharing” lays out the means by which a developer can use XMLHTTPRequest (in Firefox) or XDomainRequest (in IE8) to make cross-site requests. As is often the case, the solution is implemented by extending HTTP headers, which makes the specification completely backwards and cross-platform compatible even if the client-side implementation is not. While this sounds like a good thing, forcing changes to HTTP headers is often thought to require changes to the application. In many cases, that’s absolutely true. But there is another option: network-side scripting. There are several benefits to using network-side scripting to implement this capability, but more importantly the use of a mediating system (proxy) enables the ability to include more granular security than is currently offered by the Cross-Domain Request specification. HOW CROSS-ORIGIN ACCESS CONTROL WORKS The basic premise of the W3C specification is that the server, i.e. the application, controls whether a remote location can send cross-site requests. Even though the request is actually made by the user (and we’ll get to how we might leverage that dynamically a bit later) it is the originating application – more specifically the domain - that must be authorized. In its simplest form, when a cross-origin request is received the application must respond with an Access-Control-Allow-Origin HTTP header containing a URI (or wildcard) that matches the value of the “Origin” HTTP Header. The browser then determines if the values of the two HTTP headers match and, if they do, the request is allowed to continue. If the value of the Access-Control-Allow-Origin does not exactly match the value of the Origin header – or does not contain a wildcard – the browser refuses to honor the response. The wildcard cannot be used in place of the host in a FQDN (Fully Qualified Domain Name), e.g. *.example.com, it can only be used to allow all domains to access the resource. While this is certainly the easiest way to enable cross-domain requests to be successful, it is not recommended because it is essentially the same as providing no security for the invocation of functionality from third-party domains. Other variants of this scenario allow for the use of other HTTP methods (POST, DELETE, PUT) but require a pre-flight request to determine whether the method is allowed or not. The availability of these methods certainly forwards the REST API model as well as SOAP and makes it possible to develop web-based applications that can interact with multiple domains – think cross-cloud deployments – at the same time. USING an INTERMEDIARY Of course the need to (a) determine access control based on the Origin header and (b) add the Access-Control-Allow-Origin header requires that the application must change its behavior, i.e. code to support cross-domain requests. But as is the case with many forms of authentication and web application security, this process can be relatively easily implemented in a network-side scripting capable load balancer or intermediary, such as a mod_headers/mod_rewrite enabled Apache-based proxy. Regardless of whether you use a proxy capable of inspecting and transforming requests and responses or a Load balancer similarly enabled the process should be the same. The advantages of using an intermediary are that you don’t need to change existing applications to support this functionality, and a centralized proxy-based solution can provide the functionality for all applications at the same time. A second benefit of this architecture over tightly-coupling with the application is that the application doesn’t need to process requests that are not allowed. If the proxy-based solution determines the request is not legitimate or authorized, the server never sees the request. This means the application – and by extension the server – don’t waste resources processing requests that are unauthorized, which improves the capacity of the server/application to service legitimate users. A final advantage of this solution is flexibility. While the specification calls for determining authority to access a resource based solely on the origin, this can easily be extended to include other factors if the intermediary platform is capable of doing so. For example, if you’re using a network-side scripting capable application delivery controller that is able to leverage GeoLocation information, you can use that information to determine authorization as well as the origin. You can use cookies, other HTTP headers, network information, time of day, and of course any data that might be submitted with the request – just about any data from the network up to the application can be included in the determination of whether the request should be granted or not. APPLICATION DELIVERY EXTENDS VISILBIITY and REACH of APPLICATIONS What the W3C provides is a framework for enabling the execution of cross-domain requests, but does not specifically detail how to determine whether any given request should be allowed or not. That is completely up to you. It is assumed by many that the only method of determining access rights is to keep a list of domains allowed to access resources via a cross-site request. This is simply not true. The use of additional HTTP headers as a means to allow or deny access makes the process dynamic and it is up to the developer to determine how access rights are derived. While the simplest case certainly uses nothing more than a list of domains, there are plenty of other ways in which access rights can be derived given an HTTP request. A context-aware application delivery controller used as the means by which such determinations are made can dramatically broaden the type of information upon which you can base that decision. You can extend the application’s reach, essentially, into the network. If you still want the application itself to authorize the request, you could still use network-side scripting to simply “screen” requests to determine whether they pass certain checks before being forwarded onto the server. For example, the application delivery controller can inspect a request not only for the existence of the Origin header, but also the User-Agent. Based on the User-Agent the network-side script may be instructed to reject the request outright rather than allow it to be processed by the server. This may be desirable to prevent spiders and scripts – assuming they are capable of sending the Origin header - from accessing resources. It may be desirable to check for capabilities or language support first before forwarding on the request, to ensure the server-side application properly supports the request. This is also the best place to implement request throttling behavior, too, to ensure one client – or domain – does not consume resources at a rate that would degrade availability or performance for other clients – or domains. This is “application delivery” as it applies to application architecture: the ability to leverage “network” and “application network” services to extend the reach and visibility of applications further to provide additional security and options that were heretofore unavailable due to inherent limitations in the application architecture. Related blogs & articles: Technorati Tags: MacVittie, F5, application security, security, web 2.0, network-side scripting, W3C, cross-domain request, HTTP, application delivery, context-aware, development, ajax, XMLHTTPRequest
|
|