|Image by John Trainor|
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="."/>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.
<xf:output mediatype="image/*" ref="."/>
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?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!