Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to protect Rest API key for Parse in html application

I have been learning with Angular.js and used Parse as the back-end service. To post data to the Parse RESTful API, you would pass REST API key and App ID in the header of the request like this:

var config = {headers: {"X-Parse-REST-API-Key":"someapikey", "X-Parse-Application-Id":"someappid"}};

$http.post("https://api.parse.com/1/classes/myobject", obj, config).success (
            function(data) {console.log(data);}
);

While this is great for learning, I am wondering how would the RESTful API for Parse or any other Backend-as-Service vendor work in a real html application. The API key and application Id would be exposed in JavaScript and anyone smart enough to view source could modify data to your account.

The only way I can image this to work would involve a proxy server that adds to Api Key/App Id header. However, this would defeat the purpose of not having to run your own back-end server. Am I missing something here?

like image 732
ltfishie Avatar asked Aug 06 '13 05:08

ltfishie


1 Answers

Here's what you're missing :)

The Parse.com REST/JavaScript keys are designed to be "out-in-the-wild." With these keys it's not possible to get around object access rules or beforeSave validations. Only the master key can do this. Protect the master key. A useful analogy is public-key encryption: you need share your public key but protect the private key.

Can anyone modify your data? Yes, but only if you let them. Can users query data belonging to other users? Yes, but again only if you let them. Parse has a few ways to ensure data integrity and security.

The first is per-object permissions. Use the Parse.com web interface to set a) whether or not classes can be created on the fly and b) CRUD permissions for existing classes. One of the easier steps to securing an app is to disable any class permissions not explicitly required. For example, objects created on the back-end which do not need to be writable (or perhaps readable) by end users.

The second is access control lists (ACLs). ACLs are set on each record. They specify which users or roles can read or write the record. Records without an ACL are public (any user can find it). If Sue creates a record that should be private to her, set an ACL as such. Tom won't be able to find it without the master key.

The third is Cloud Code. You're able to enforce mission critical business rules and data validations using beforeSave/afterSave functions. Determine what is truly important, and make sure it's validated against in these functions. It's also a good idea to set the ACL explicitly in these functions. ACLs can be passed in when creating the object, but it's possible for the end user to tamper with these.

Here is are summary rule of thumbs for security and integrity.

  • Object permissions should only be as open as necessary to support your requirements.

  • Every record should have an ACL, unless you're sure it shouldn't.

  • Most ACLs should be set with before/afterSave functions.

  • Any validations that must be enforced should checked for in before/afterSave functions.

Last thing: it's temping to think of all business logic as "important" and insist on "perfect integrity." This is overkill for many apps. Make sure you have enough server-side protection in place such that one user can never cause harm to you or to your other users. There is not much sense in worrying much beyond this (other than support costs). If someone is experimenting with your app but is prevented from intentionally or unintentionally interfering with others, maybe they'll find a whole new way to use it :).

like image 180
Drew Goodwin Avatar answered Sep 30 '22 15:09

Drew Goodwin