Wednesday, June 6, 2012

More secure file uploads

Image by John Trainor
Orbeon Forms does pretty well with file uploads: in particular, it supports uploads in the background, repeated uploads, and allows you to process uploads with other controls and submissions.

But file uploads are tricky business, with security implications. For example, you don't want a web application to have indiscriminate access to a user's files. (This is why, with web browsers, uploads always require a user action via a file selector or drag and drop.)

It's interesting to notice that XForms uploads go a bit further than HTML uploads: once a file has been selected by the xf:upload control, the application can do a number of things with it. For example, say you are uploading an image, and want to display it to the user immediately:
<xf:upload ref="."/>
<xf:output mediatype="image/*" ref="."/>
Yup, that's it. Pretty easy, right? All the magic is handled by the XForms engine. And that's exactly how the Orbeon Forms image attachment control work.

This works because there is a local URL representing the uploaded file. In Orbeon Forms, this does not directly point to the user's file. First, that would be impossible, as the browser doesn't give you access to that. Second, the file is transferred to the server first. So it is available on the server as  a temporary file: URL, until the form does something with it, such as showing it to the user or saving it to a database.

But what if somehow the file: URL was exposed to the user of the form (for example, say the form author by mistake used xf:input instead of xf:output)? The user might be able to tamper with the URL and gain access to other files on the server. That is unlikely to happen, and only if the form author makes a mistake, and only if the app server or server configuration authorizes the file access, but that would be bad.

So in the upcoming Orbeon Forms 4, we have made this process more secure. Every file stored by xf:upload now comes with an authentication code (MAC). So a URL now looks like this:
file:/foo/bar.tmp?
 filename=bar.png&
 mediatype=image%2Fpng&
 size=1234&
 mac=2db6140c988970391e8cd1513af3cc3a3dbcf6ff"
This allows internal consumers of the file URL to check the signature first. For example, xf:output only dereferences the URL if the MAC is correct. Any tampering of the URL done by an entity which is not xf:upload is rejected.

As a reminder, it is crucial, when deploying Orbeon Forms, to always setup a new Orbeon Forms password with the oxf.xforms.password property! Don't miss this easy step!

5 comments:

  1. As a side issue you talked about better support for mobile devices, would this include file upload?

    Mobile browsers don't support file upload but there are javascript workarounds but I've no idea if this is possible from a web app

    Also it would be great to specify a max file size and file types directly from the control.

    ReplyDelete
  2. If this StackOverflow question holds, we probably won't do it until there is native support:

    http://stackoverflow.com/questions/3891831/a-html5-web-app-for-mobile-safari-to-upload-images-from-the-photos-app

    But let's see what's in store for iOS 6. Maybe we'll know more today after the WWDC keynote ;)

    ReplyDelete
  3. So it seems that iOS 6 will support image and video uploads. That's a start!

    ReplyDelete
  4. Good news Erik, what about Android? I know you are focussed on Apple but Android is a sizeable market. I'm thinking of tables used as data entry platforms in emerging markets where the price of an Apple tablet is prohibitive.

    ReplyDelete
  5. As far as file uploads are concerned, it's really something which must be a browser-supported feature, and mobile browsers must just get there act together here. Now as far as mobile support in general, yes that's something we definitely want to work on more (via HTML 5 / JavaScript in the foreseeable future).

    ReplyDelete