My favorites | Sign in
Project Logo
             
Search
for
Updated Jul 17, 2008 by b...@google.com
Labels: DesignDoc
FileSystemAPI  
Secure client file access

Introduction

The purpose of this module is to provide secure access to files on the client machine. The FileSystem module has now been merged with the Desktop module. Therefore this document describes the FileSystem functionality in the Desktop module.

NOTE

We should do something API wise that fits as close as possible with

<input type="file">
and the webforms file picker extensions.

See also: http://www.whatwg.org/specs/web-forms/current-work/#upload http://groups.google.com/group/google-gears-eng/browse_thread/thread/f73cb640a1c845/8026291efe8fc8a5

The one remaining issue preventing us from designing this is that we also have some desire to implement file writing. It's unclear how this relates and what the API would look like.

Features

Multiple files can be provided by the user.

Once the files are available, potential processing options are:
  • Compress files.
  • Send files to a server.
  • Capture files to the local resource store.

Security

Access to the user's file system can only be granted by the user.

A malicious application will NOT be able to access arbitrary files on the user's system.
  • Do not allow random access to the user's file system.
    • filesystem.open('/etc/shadow');
  • Do not allow access above the specified location in the user's file system.
    • filesystem.changedir('../../etc/shadow');
Do not allow a malicious application to display a file open dialog in the wrong context.
  • The minimum behavior required is that of alert() in JavaScript. If the tab is inactive when it displays a new window it must switch to be the active tab. Firefox exhibits this behavior but IE7 acts differently. In IE7 the inactive tab flashes and when the tab is selected then the window is displayed.

Trade-offs

Selecting directories

Use cases

Name: input files

Description: a user provides details of files to make available for further processing

Author: Chris De Vries

Date: 11/01/2008

Steps:

  1. The user indicates files they wish to make available to the system.
  2. The files are made available for iteration via the API.

JavaScript Interfaces

interface Desktop {
  //
  // ... other apis ...
  //

  // Displays a file chooser to the user, from which they can select files on the local
  // disk.  The callback is invoked with an array of the files which were selected.
  void openFiles(OpenFilesCallback callback, optional OpenFilesOptions options);
}

void OpenFilesCallback(File[] files);

interface File {
  // The name of the file, excluding the path.
  readonly attribute string name;

  // The contents of the file.
  readonly attribute Blob blob;
}

interface OpenFileOptions {
  // By default, the user may select multiple files.  If true, the user is limited to
  // selecting only one file.
  bool singleFile;

  // By default, all files on the local disk are shown as selectable.  If a filter is
  // provided, only files matching the filter are shown.  The user can turn the filter
  // off, so be aware that selected files may not match the filter.  The filter is an
  // array of Internet content types and file extensions.
  // Example: ['text/html', '.txt', 'image/jpeg']
  string[] filter;
}

C++ Internal Interfaces

// Constructs a file dialog according to mode.
// Caller is responsible for freeing the returned memory.
// Returns: null pointer on failure
// Parameters:
//   mode - in - the type of dialog to construct
FileDialog* NewFileDialog(const FileDialog::Mode mode,
                          const ModuleImplBaseClass& module);

// This interface will be implemented for every supported operating system.
class FileDialog {
  // Used for constructing dialogs.
  // This is intended to allow for different types of file pickers in future.
  // For example, FILES_AND_DIRECTORIES, for a custom dialog that allows the
  // user to select files and directories at the same time.
  enum Mode {
    MULTIPLE_FILES  // one or more files
  };

  struct Filter {
    // The text the user sees. For example "Images".
    std::string16 description;

    // A semi-colon separated list of filters. For example "*.jpg;*.gif;*.png".
    std::string16 filter;
  };

  // Displays a file dialog.
  // Returns: false on invalid input or failure
  // Parameters:
  //   filter - in, optional - An array consisting of pairs of strings.
  //     Every first string is a description of a filter.
  //     Every second string is a semi-colon separated list of filters.
  //     Example "Images" and "*.jpg;*.gif;*.png".
  //
  //   files - out - An array of files selected by the user.
  //     If the user canceled the dialog this will be an empty array.
  //     A new array is constructed and placed here.
  //     Caller is responsible for freeing returned memory.
  //
  //   error - out - The error message if the function returned false.
  //
  virtual bool OpenDialog(const std::vector<Filter>& filters,
                          std::vector<std::string16>* selected_files,
                          std::string16* error) = 0;
}

Code Example

var desktop = google.gears.factory.create('beta.desktop');
var files = desktop.getLocalFiles(['Images (*.jpg, *.gif)', '*.jpg;*.gif', 'All files', '*']);
for (var i = 0; i < files.length; ++i) {
  var img = document.createElement("img");
  img.src = files[i];
  document.body.appendChild(img);
}

Comment by chrisincambo, Aug 22, 2008

It's a real shame that greater access hasn't been given to the file system, especially entire folders. The use case where local file access is most compelling is where the client requires heavy resources which would be too slow over the internet such as high res images which may be numerous and too much of a pain to select one by one with the current API.

Imagine you wanted to take an app 'like' Google Maps off line and wanted have the map tiles pre-cached locally, there is no feasible way to achieve this with Gears, what are you going to do? Add twenty thousand tiles to the manifest? Ask the user to select them all with a file picker?

Comment by chrisincambo, Aug 22, 2008

It would have been interesting if Gears has something like the POW Firefox add-on which creates a web server right within Firefox. As client server communication over http is a security model most people are far more familiar with, just in this case the web server is always local. I'm sure it would have granted you all more freedom to experiment.

Comment by naveedulislam, Oct 07, 2008

Security model presented here is great however I am surprised with the lack of attention that should have been given when browser is running in a local mode i.e. using file:/// protocol. In which case, without breaking security policies, there should be functions available to execute local commands within context. Think of a situation when the browser is running from a DVD/CD to run a trusted HTML and JavaScript? based application that could require access to some executable files.

Comment by evan.leonard, Jan 07, 2009

We have a use case where we need to have to user select a single XML file and then locally on the client side process the XML, discover other imported XML documents, and then process those as well. Currently we're stuck with an Applet to do this, but would like to move away from it because of the multitude of problems getting the applet to load in different browsers and different versions. The limitations on the Gears file api eliminates Gears as an alternative for us.

Comment by cjmason, Feb 09, 2009

I second the comment by evan.leonard. We would love to be able to explore a user selected directory tree to find files specified, for example, by columns in a spreadsheet. I think this could be made reasonably secure by sticking to a single volume, ignoring symlinks, etc.

As it stands, we'll just have to resort to using something like Adobe AIR to do this.

Comment by pauldorn, May 12, 2009

I third opening the API to allow script access to the contents of USER selected files. This is not a security risk as such because nothing is stopping the script from uploading that content to the server and downloading it right back! In fact this is exactly how we are getting around this issue now. It makes much more sense (and is more secure) to just allow it to be done in-browser.

Comment by rdlord, Jul 04, 2009

I fourth the comments by evan.leonard, cjmason & pauldorn. The limitation of the Gears file api eliminates Gears as a solution for our Web app.


Sign in to add a comment
Hosted by Google Code