----- Original Message -----
From: "Vojtech Szocs" <vszocs(a)redhat.com>
To: "engine-devel" <engine-devel(a)ovirt.org>
Sent: Monday, April 15, 2013 2:04:24 PM
Subject: [Engine-devel] Proposal to make REST API more webapp-friendly
Hi guys,
having worked with Engine REST API from web application (JavaScript)
perspective, there are things that could be improved to make REST API more
webapp-friendly.
First of all, webapps are *not* traditional HTTP clients, i.e. they have
*not* full control over HTTP processing. There are some standard conventions
and behaviors built into web browsers that any REST API implementation
should be aware of.
--
(1) Don't force clients to use cookies for transmitting authentication
information! (or don't use cookies at all)
Good explanation can be found at
[
http://www.berenddeboer.net/rest/cookies.html]. Cookies have many
disadvantages:
* cookie parsing/formatting is not trivial
--> extra complexity imposed on REST clients
* in addition to Same-Origin Policy
[
http://en.wikipedia.org/wiki/Same_origin_policy], cookies can be get/set
*only* for the given path
--> JavaScript running at [
http://example.com/webapp] *cannot* get/set
cookies from requests at [
http://example.com/restapi]
* cookies are the primary source of Cross-Site Request Forgery
[
http://en.wikipedia.org/wiki/Cross-site_request_forgery] attacks
--> malicious websites/scripts can forge requests to REST API that will
include the cookie, compromising user session
Alternative: clients could be given the *option* to use regular HTTP header
for transmitting authentication information.
For example, webapp could read such (sensitive information) header, store it
securely via HTML5 Session Storage
[
http://en.wikipedia.org/wiki/Web_storage] and implement related HTTP
processing on its own, e.g. pass this header for all authenticated requests
(instead of pushing this responsibility to browser).
Option #1:
We currently return the JSESSIONID also using HTTP headers. We currently return the
jsession id also as part of the response HTTP headers, but the client still needs to pass
a cookie with the appropriate value in order for the REST session to work. Isn't that
enough to cope with this issue?
If not, then we might be able to do option #2:
Today, we keep the engine session ID on the HTTP session attributes.
So, we can support either passing the cookie with the JSESSIONID (taking the engine
session ID from the http session), or passing the engine session ID as HTTP header
(assuming we would also return the engine session ID upon first REST request).
This approach is problematic, as it might work well now, when the only attribute we use is
the engine session ID, but in the future that might not be the case.
If it is important enough (i.e., you can't really work with option #1) , then we can
make a decision to save the attributes on the engine session, rather than on the HTTP
session.
So, we would start by supporting them both together, adding new attributes only to the
engine session, and in the future deprecating the use of cookies, and only supporting HTTP
headers.
cc-ed Juan and Michael, as they might have some input on that.
--
(2) Straight-forward HTTP Basic Auth has some drawbacks!
HTTP Basic Auth [
http://en.wikipedia.org/wiki/Basic_access_authentication]
over (non-secure) HTTP connection means sending user credentials
(username/password/domain) in easy-to-decode cleartext, i.e. the value is
*not* encrypted or hashed in any way. Using secure lower-level protocol
(SSL) fixes the consequence, rather than the root cause of the
confidentiality issue.
Furthermore, browsers typically remember HTTP Basic Auth information (either
via browser-specific popup, or via XmlHttpRequest) until the browser window
is closed. This means the webapp has no control over HTTP Basic Auth header
after it has been set! This is the reason why it's hard to implement
"logout" functionality in webapps when using HTTP Basic Auth.
Last but not least, HTTP Basic Auth is vulnerable to Replay attacks
[
http://en.wikipedia.org/wiki/Replay_attack]. Someone between client and
server can intercept requests and replay them, compromising user session.
Alternative: clients could be given the *option* to use more advanced
authentication scheme.
I've just read an excellent article at
[
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-aut...]
which describes easy yet secure authentication scheme inspired by Amazon Web
Services REST API authentication
[
http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html].
The idea is simple: collect auth information, hash (sign) it with a private
key, and send everything to server. To guard against Replay attacks, just
provide some timestamp to enforce request expiry after some time (say, 5-15
minutes). Easy and simple!
--
(3) Support JSON for resource representations!
I think this is pretty much obvious. XML has no real advantages over JSON.
JSON, on the other hand, has good support in webapps (JavaScript) and maps
directly to common data structures (i.e. string, number, boolean, and so
on).
From webapp perspective, it's much easier and natural to use JSON than to
parse/format XML documents.
Alternative: clients could be given the *option* to use JSON, in addition to
XML representation.
--
Vojtech
_______________________________________________
Engine-devel mailing list
Engine-devel(a)ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-devel