I'm setting up parse framework in javascript. I notice that I need to call
Parse.initialize("app", "secret")
Since this is in the page source, couldn't anyone take this and make calls against my account?
Is there a more secure way to store this info?
As per Parse Security Guide your JavaScript key is NOT secret:
When an app first connects to Parse, it identifies itself with an Application ID and a Client key (or REST Key, or .NET Key, or JavaScript Key, depending on which platform you're using). These are not secret and by themselves they do not secure an app. These keys are shipped as a part of your app, and anyone can decompile your app or proxy network traffic from their device to find your client key. This exploit is even easier with JavaScript — one can simply "view source" in the browser and immediately find your client key.
So yes, anyone who found your key can make calls.
But you can (and should) restrict what such anyone can do.
Using Class-Level Permissions you restrict what can be done with individual classes.
Using Object-Level Permissions you restrict what can be done with selected objects.
See also Roles and Roles Hierarchy for simultaneously setting permissions for a group of several users.
For instance, you can restrict access to only specific users. Only if one of those users is logged in, the access is granted. Any other "hacker" can try to use your keys but the request will be rejected by Parse.
Related
I don't have any idea how to implement this. After a bit of search I found out that medium keeps track of the browser and not the user, what is mean is you can access three free articles from each new browser on the same machine (if I am wrong do point it out). I am using React and Firebase for my website.
Edit: I was thinking along the lines of getting some kind of id which is unique to a browser. As cookies and local storage can always be bypassed.
I don't know if it's a clean way to do it but you can associate an IP to an unique counter. Or with a cookie but he can bypass that by cleaning the cookies
The answer would tightly depend on your application setup and especially on the service backing your front store.
If you are using a self-backed backend, for example a nodejs - express based server, within your route middleware you can access the remote address from the req.connection.remoteAddress request property along with the user-agent req.header('User-Agent') and forward these to your datastore being Firebase in this case.
If you are deploying your application to Google Cloud Function, you can then access the remote peer address using the fastly-client-ip request header and still forward this to your storage system.
Use javascript and implement a system that uses a cookie or local-storage to verify how many articles are read on your website.
On most of these websites however you are still able to bypass this limit by clearing the cache or using a incognito window.
To also limit these scenarios you can use a cookie in combination with an IP address, which has its own drawbacks, especially in corporate environments, and mobile connections where IP addresses are heavily shared or changed. Depending on your situation this may matter or not.
I'm developing an app, which should connect to an external DocumentDB database (not mine). The app is build with Cordova/Ionic.
I founda JavaScript library from Microsoft Azure in order to ensure a DocumentDB database connection, but it is asking for some weird stuff like collection_rid and tokens.
I've got the following from the guys of the external DocumentDB database:
Endpoint: https://uiuiui.documents.azure.com:443/
Live DocumentDB API ReadOnly Key: P8riQBgFUH...VqFRaRA==
.Net Connection String: AccountEndpoint=https://uiuiui.documents.azure.com:443/;AccountKey=jl23...lk23==;
But how am I supposed to retrieve the collection_rid and token from this information?
Without row-level authorization, DocumentDB is designed to be accessed from a server-side app, not directly from javascript in the browser. When you give it the master token, you get full access which is generally not what you want for your end-user clients. Even the read-only key is usually not what you want to hand out to your clients. The Azure-provided javascript library is designed to be run from node.js as your server-side app.
That said, if you really want to access it from the browser without a proxy app running on a server, you can definitely do so using normal REST calls directly hitting the DocumentDB REST API. I do not think the Azure-provided SDK will run directly in the browser, but with help from Browserify and some manual tweaking (it's open source) you may be able to get it to run.
You can get the collection name from the same folks who provided you the connection string information and use name-based routing to access the collection. I'm not sure exactly what you mean by token but I'm guessing that you are referring to the session token (needed for session-level consistency). Look at the REST API specs if you want to know the details about how that token gets passed back and forth (in HTTP headers) but it's automatically taken care of by the SDKs if you go that route.
Please note that DocumentDB also provides support equivalent to row-level authorization by enabling you to create specific permissions on the desired entities. Once you have such a permission, you can retrieve the corresponding token, which is scoped to be valid for a certain time period. You would need to set up a mid-tier that can fetch these tokens and distribute to your user application. The user application can then use these tokens as bearer-tokens instead of using the master key.
You can find more details at https://msdn.microsoft.com/en-us/library/azure/dn783368.aspx
https://msdn.microsoft.com/en-us/library/azure/7298025b-bcf1-4fc7-9b54-6e7ca8c64f49
I need a primer web/javascript security.
According to How to use an HTML/JavaScript client for Windows Azure Mobile Services, in javascript on the client side, after including a link to MobileServices.Web-1.0.0.min.js you're supposed to create a client like this:
var MobileServiceClient = WindowsAzure.MobileServiceClient;
var client = new MobileServiceClient('AppUrl', 'AppKey');
which means including my AppKey in the javascript on the page. Should I be worried about the AppKey being public?
Also, it seems easy enough for someone to put an XHR breakpoint in to read the X-ZUMO-APPLICATION and X-ZUMO-AUTH headers while making a REST call when logged in. The usefulness of this is somewhat reduced with a cross-origin resource sharing whitelist, but what's to stop someone with this information from adding javascript to the page and executing arbitrary operations on my backend database? Restricting table permissions to authenticated users wouldn't help in this scenario.
Do I need to be concerned? What do banking apps do about this sort of thing?
In the same link which you shared, application key is defined as a not safe mechanism to authenticate users - A unique value that is generated by Mobile Services, distributed with your app, and presented in client-generated requests. While useful for limiting access to your mobile service from random clients, this key is not secure and should not be used to authenticate users of your app.
More over when you enable some authentication on all the endpoints either using ACS or through Open Authentication, if you main ASP.Net/PHP etc page got authorized, then browser is going to handle federation of identity through cookies for next on-going calls till your session ends.
In most of the applications having HTTPS would protect from Man in middle attacks. Also strong encryption logic on cookies along with very specific expiry times would increase the bar of security. Also IP address based checks would definitely help in improving security.
ramiramilu's answer covers most of the question. There's one more thing which I'll add:
Also, it seems easy enough for someone to put an XHR breakpoint in to read the X-ZUMO-APPLICATION and X-ZUMO-AUTH headers while making a REST call when logged in
Yes, someone can add a breakpoint and find out the value of the X-ZUMO-AUTH header which they're sending. But the value of that header is specific for the logged in user (in this case it would be the "attacker" [him/her]self) - it wouldn't be able to get information from other people out of that header. And there are even easier ways to get the value of that header (just browse to https://<mobileservicename>.azure-mobile.net/login/<authProvider> and after entering your credentials you'll see the header encoded in the URI).
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?
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 :).
Parse provides several access keys that can be used via different APIs:
Client key (for use from iOS and Android applications)
Javascript key
Windows key
REST key
Master key (to be used for REST API access, but not conforming to object ACL permissions)
When accessing Parse from client-side javascript, you should use the javascript API with the Javascript access key.
In terms of security, you will not be able to prevent users from using an access key that is used by client side javascript. Parse provides powerful access control via ACLs attached to each object, allowing you to restrict read/write access to each class to specified users. You can also prevent clients from creating new classes in the settings of your app. Take a look at the security guide here.
I'm trying to write a javascript single-page-app that allows users to login and then, once logged in, create/modify records in a database. I'd like to avoid having my own server side scripts if possible, instead using something like Parse.com, Kinvey.com, or Cloudmine.me.
My issue is that these services have user login capacity but use API keys to determine whether your app has write access. They don't seem to let you have write access once your user is logged in. The only way I can think of to accomplish this is to store a write-access API key in the user's user data, so I'd have the user login, fetch the hidden API key, then change the API key of the app to use that one, so they'll have write access. Obviously this isn't very secure because once that API key is sent over the network, that user will have write-access even if we delete their account or they change their password.
Perhaps I'm going about this the wrong way, so feel free to let me know. Hopefully this made sense. Thanks!
You should be able to restrict access to a group of users using Parse.ACL: http://www.parse.com/docs/js/symbols/Parse.ACL.html
If you want to control access on a per user basis then you will have to maintain a custom property on the user object. Then you can check the custom property in the BeforeSaveRequest() function and decide whether the user has write access: http://www.parse.com/docs/js/symbols/Parse.Cloud.BeforeSaveRequest.html
By default, most BaaS providers should provide collection level security and some even offer per entry security via ACL's (Access Control Lists).
Kinvey for instance has several variations on collection level security:
http://devcenter.kinvey.com/html5/guides/security#Collectionlevelpermissions
The default security level of Shared make it so the user has access to read everything in the collection but can only write to their own items. You may also want to use the Private security level to make it so you can only read and write to your own items.
If you want to have more fine-grained control over security you can utilize entry level permissions:
http://devcenter.kinvey.com/html5/guides/security#Entitylevelpermissions
With entry level permissions you can give fine grained access to a specific user or groups of users that you manage. You can even determine what level of security a user has to your entry, read or write. If you have a need to go even finer with control you have full access to write your own security utilizing Business Logic.
Full Disclosure - I am an engineer at Kinvey.