Saturday, March 17, 2007

The Quest for JSON-RPC [In]Security

In Web 2.0-land, things really seem to be heating up with the not so interesting (or, in and of itself no more interesting than XML) JSON and the more interesting (as a lightweight replacement for XML-RPC or XMLHttpRequest used in AJAX apps) JSON-RPC to the point hat I've started tracking things on a wiki page.

To break down, here is what is sent on the wire. JSON-RPC is quite similar to XML-RPC except instead of sending and XML message via an HTTP POST you use JSON, such as:

POST http://jsolait.net/services/test.jsonrpc HTTP/1.1
Host: jsolait.net
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Content-Type: text/plain
Referer: http://jsolait.net/wiki/examples/jsonrpc/tester
Content-Length: 99
Pragma: no-cache
Cache-Control: no-cache

{"id":"httpReq", "method":"args2Array", "params":["hello", {"a": 1234, "b": "five"}, [6, 7, 8, 9]]}HTTP/1.0 200 OK


And obviously the server will respond with something like

HTTP/1.0 200 OK
Date: Wed, 28 Feb 2007 22:32:17 GMT
Server: Apache/2.0.55 (Debian) DAV/2 SVN/1.3.2 mod_python/3.2.10 Python/2.4.4
Content-Type: text/plain; charset=UTF-8
Proxy-Connection: close

{"id":"httpReq", "result":["hello", {"a":1234, "b":"five"}, [6, 7, 8, 9]], "error":null}


In terms of security, so far I've only found one presentation at CCC somewhat related to JSON-RPC security and I didn't find it terribly interesting. This article by Metaeye Security Group was a bit better, but had nothing to do with RPC, only JSON. Then there is the August 2006 Working Draft we see the following as a "non-goal:"

JSON-RPC does not address security, correlation, reliability, sessions management, state management and many other features that may be found in other RPC protocols or distributed systems. Developers are instead encouraged to employ features of HTTP and related Internet technologies that can offer some of these features in an equally compelling, robust and satisfying manner. Some features may be defined as extensions by other specifications.

Now it is tempting to mock this sentiment as the normal "security never makes it into 1.0 argument" (or think TCP/IP protocols that say, hey IPSEC will handle all security -- or our web application is secure if it goes over HTTPS) but there is actually some sense to their logic.

In an ideal world, it would definitely be better to rely on the web [application] server, web framework (or whatever) to do session management, authorization, authentication, and definitely encryption. Why reinvent the wheel, badly? However in practice this normally means form based authentication plus a strong session ID (whether Java, PHP, ASP, or whatever) all over SSL. But what if I don't want that or can't have that, for example if I'm not running the client within a browser--and yes I could definitely see some use cases for non-browser based JSON-RPC (as an alternative to SOAP or XML-RPC) and given the number of implementations out there some other folks obviously do as well.

Since HTTP Digest Authentication is not a pervasive or a robust as we would like (a case in point: try to find a Python/Ruby/Java based Web Server to expose XML-RPC web services that supports RFC 2617--actually Ruby seems the best choice) you are stuck with Basic Authentication over HTTPS. What I wish is that there were a lightweight authentication and authorization mechanism comparable to what Amazon does with S3 and its REST APIs.

If you are doing "RPC stuff" over HTTP, you need more granular security mechanisms than can be provided by HTTP[S] or the appserver.

Right now the big boys in web service land (Amazon, Google, Yahoo) don't seem to be exposing their APIs with JSON-RPC yet (although they do expose data in JSON) similar to the way that SOAP and REST are currently used, but it is probably only a matter of time. The other aspect of JSON-RPC that is sort of interesting is that several of the JSON-APIs are borrowing heavily from their XML-RPC counterparts, which have had their share of security issues--at least in PHP, Python, and Ruby.


Update
I just ran across some fresh blogs (last week) on JSON (In)Security that are relevant:
Securing your JSON and JSON is not as safe as people think it is.

I will continue to add stuff like this to my Json Wiki Page as I find it.

2 comments:

Anonymous said...

Any news on that?
If you had to implement json-rpc service today, in Python, how would you secure it?

jagwio said...

Thanks for the links, I hope they prove helpful. I have the feeling that I may have a long road ahead trying to implement security in Jayrock using Windows Authentication. (Fun!)

One thing comes immediately to mind - having your RPC server non-internet accessible and networked to your web server. Or, have the RPC stuff on you web server and only accept calls from localhost. Probably a naive approach (and obviously doesn't provide granularity).

Ah well, off to fill my eyes with RPC security articles!