One of the hurdles that Web applications face when attempting to take advantage of web services in general (regardless of whether they're SOAP-based, XML-RPC-based or REST-based) is that as long as your web applications is running inside a web browser that cares about your security, the application is not allowed to gain access to any content that resides in a domain other than its own.

This is called cross-site scripting prevention which basically disallows scripts from gaining access to the content originating from another host which could lead to malicious hackers manipulating other Web sites' content. This is certainly a good security measure. However, when a Web site, in the name of data exchange, openly wishes to allow the other Web site to gain access to some of the contents residing on their web server, they're still not allowed to do so without requiring the user to manually go through several steps to set custom security settings for specific Web sites. =(

To get around this situation, people have been authoring proxy code that reside on the same web server that the web application is served from. Once the proxy code is set up, the client can make requests to service providers residing in other domains through the proxy. This is relatively painless if you're dealing with standard interfaces such as SOAP or XML-RPC, but not if you're dealing with non-standard APIs. Moreover, what if you just plain can't or don't want to deal with server-side proxy code? Finally, the minute you bind your JavaScript with some server-side proxy, your codebase becomes less portable. In other words, if you had written the server-side proxy in ASP.NET and had to move it to be hosted on Apache, you'd have to get/write another proxy code.

So I had an idea, and I'm calling it "HTTP Response Bouncing" (so that nobody can name if after another flavor of detergent). The acronym comes out to be HRB: pronounced the same way as "herb". It's basically trying to say that it wishes to be a sprinkle of medicine/seasoning used to help interoperation on the Web. ;)

The idea is very simple. The goal is to allow seamless data exchange between a client and a willing server through the standard HTTP protocol without requring a lot of effort. The implementation is also very simple, and it requires very little effort on the service provider and the consumer to get up and running. Once you're up and running, it's likely that you'll never even have to think about it again. *fingers crossed*

Ok, so here's what the sequence of events look like:

  1. The Web application served from http://www.server1.com uses remote scripting to issue a GET/POST request to http://www.server2.com/getIt/ and indicates that it wishes the response be bounced to http://www.server1.com/translate/ *.
    GET http://www.server2.com/getIt/?__bounce_to=http://www.server1.com/translate/ HTTP/1.0
  2. http://www.server2.com/getIt/ executes the request as it normally would.
  3. http://www.server2.com/getIt/ notices that the request wishes to have the response bounced to http://www.server1.com/translate/, so it packages up the response as a querystring and sends back a 303 staus with the Location header set to the packaged URL**.
    HTTP/1.0 303 See Other
    Location: http://www.server1.com/translate/?content=Hello%20World&type=text/plain&status=200
  4. The browser receives the 303 response code and internally issues a GET request to the URL specified in the Location header.
    GET http://www.server1.com/translate/?content=Hello%20World&type=plain/text&status=200 HTTP/1.0
  5. http://www.server1.com/translate/ receives the GET request issued by the browser and generates the HTTP payload content based on the response field in the querystring***.
    HTTP/1.0 200 OK
    Content-Length: 11
    Content-Type: plain/text

    Hello World
  6. The browser receives the content generated by http://www.server1.com/translate/, and now the Web page that issued the original request can access the content via script since it is being served from the same domain.

* The destination to which the response should be bounced to is specified by either the __bounce_to field in the querystring:

http://www.server2.com/getIt/?__bounce_to=http%3A//server1/translate/
or the Bounce-To header in the HTTP header
GET http://www.server2.com/getIt/ HTTP1.0
Bounce-To: http://www.server1.com/translate/

** status and type fields are optional for 200 and text/plain as they can be assumed as default values.

*** notice that it is completely up to the translator to decide what the format of the payload should look like. In the pure-HTML/JavaScript example I have, you'll see that the translator actually creates a more elaborate HTML document to transfer extra meta information about the content.

Security:

You must realize that this assumes that you can completey trust http://www.server2.com. Buyers beware. If you're unsure, you might want to smarten up the translator that the response gets bounced to by building some defense mechanisms into it.

Benefits:

  • No special proxy implementation is required for the consumer of the service, as a general-purpose translator can be used for all.
  • If desired, server-side scripting can be avoided on the consumer side. (i.e. translator can be plain HTML and JavaScript).
  • The consumer has the option of specifying a different translator for different requests
  • Increases Web-based application portability. (i.e. you can take the set of HTML files plop it on a completely different server on a different host, and the functionality will continue to work with no change)

Features:

  • The translator has the option of applying arbitrary transformation to the bounced response before it reaches the consumer.
  • The translator can become arbitrarily smarter to enforce security measures without effecting the consumer

Drawbacks:

  • The service will have to support bouncing.
  • The content size is bound by the length limitation of the request line ( 8K by default on apache, and browsers may enforce their own restrictions )
  • Since XMLHTTP doesn't allow opening a URL from another domain, only Iframe-based remote scripting can be used to do bouncing. (any workarounds?)

The drawbacks kinda suck, but I thought it was better than nothing... So here I am putting it out for everyone to see and critique...

I'm putting up all the demo source code on my geek projects page, and here is a direct link.

I'm really interested in you guys' feedback!! If you can think of ways to mitigate the drawbacks or a have a better way of acheiving the same set of goals, please lemme know. Also, if this is just plain bad idea, lemme know as well. I just kinda went on an impulse to try this concept out, so I really haven't thought it through...

UPDATE: I'm starting to wonder that this could be bad if people used it as a routing bed for spamming other hosts... You can imagine a case where malicious consumers request respones be bounced to hosts other than their own. This can also be used to manipulate Web site statistics... This is not really a problem caused by this concept, rather one that it inherently allowed by HTTP, but still... Thoughts?


2 comment(s) | link to this entry | edit this entry

Want some more? Dig in to the archive for past entries.