Revoke Shared Access Signatures after initial access in Azure Storage - azure-storage

I would like to essentially allow for one-time access to certain blob resources, requiring the user to check back with my server to get a new shared access signature before being able to access the resource again.
I have an implementation of this that I currently use, but I'm curious if there's something more ideal out there (particularly something already implemented in the Azure API that I missed).
Right now, a user can request the resource from the server. It validates their access to it, creates a unique hash in a database, directs the user to a link with that hash and the user loads the page. Once the page loads and they've completely downloaded the resource, I immediately invalidate the hash value in the database so it cannot be used again.
I know that Shared Access Signatures allow for time-based expiration, but do they allow for any sort of retrieval-count-based expiration, in that the user can completely download the resource and then the SAS invalidate itself? Thanks!

One time use is not supported by SAS tokens. If you get a chance it would be great if you could add this request to our Azure Storage User Voice Backlog. I would also encourage other people with the same requirement to vote on that as wel.
Thanks
Jason

Related

Authenticating Cloudant one db per user

I apologies in advance - for this question needs a bit of background, which is likely to be long winded:
I'm trying to build an app which works offline with PouchDb. PouchDb will sync with Cloudant.
Technologies used:
Hapi, SQL, Vue, Cloudant, PouchDb
I have built a little hapi.js service to sign up / authenticate users. When an "account owner" signs up - they are added as a new user to a SQL database.
Using Cloudants API, I provision a new database (with a random name), and set security on the database so the new user has access.
I save the security (DB name, User name, and password) as metadata back to the user in the SQL database.
A very similar approach to here: https://www.bennadel.com/blog/3208-provisioning-cloudant-couchdb-databases-from-auth0-for-a-database-per-user-architecture-in-angular-2-4-1.htm (indeed, I based the above on this).
When the "account owner" logs in, the SQL DB is queried - the MetaData retrieved and sent down to the client side vue app. The PouchDB remote string is then populated with the Cloudant DB name, User name, and password.
eg:
const remoteDB = new PouchDB(`https://${name}:${pass}#0000-0000-bluemix.cloudant.com/${DBname}`);
This all works: PouchDB can talk to Cloudant - and data is going to and from without issue.
The "Account owner" is able to give read/write access to other people ("Staff") to their cloudantDB. When they add a new Staff Member, the Staff Member is added to the SQL DB. Using cloudants API, I create new security credentials for this user so that they can access the DB- (I do NOT create a new DB) and save them to the Staff Member in the SQL db as metadata...
The new staff member is sent an email - they set their username and password on the SQL db, and can log in. The Cloudant meta stuff is picked up... etc etc... PouchDB / Couchdb talks to each other - this also works.
Initially I was a bit concerned about sending this meta / credentials down to the client - I wanted to use a JWT or something... But then I saw this answer to another question:
https://stackoverflow.com/a/30417620/714950
So passing credentials down seems to be how its done in Pouch/Couch/Cloudant etc. I've got to be honest - I find the whole thing works like 'magic' - like its too good to be true, and that worries me a bit as I don't really understand it. I might be doing something terribly wrong.
Now for my question(s):
I'm passing these credentials down - is this safe? How would I reset / time out the username and password.
When they log out, I wipe the data from Pouch?
Can a user be 'logged in' and lose connection? Will pouch sync when they reconnect?
If pouch has NOT synced - and they log out (and I wipe Pouch) that would mean they would lose their data? so I guess I would need to persist the data in Pouch for when they log in again?
But what if they are using a shared computer? This data would be sat in Pouch DB waiting for someone to log in?
I'm also unsure how I validate the data... making sure that which gets saved to the DB is valid etc...
I suppose I'm just trying to get my head around this - I've been googling and reading everything I can, but it doesn't quite answer my questions.
Thanks
[** Just had a thought...
Thinking about it, I don't actually need to create the staff user within the SQL DB.
The Account Owner is set up - the DB is created in Cloudant, and credentials applied.
Not just had a thought: Theoretically, when a staff member is added - I only need to set them up inside Cloudant, and write their ID to the "Account Owner" as meta data so that they can be removed etc.
This way, a staff member could log in directly to the Cloudant DB.
However, I generate the security credentials using Cloudants API - so the staff member won't know what their username and password is. I don't want to send the username and password in an email.
Is there a way I can handle this? Am I able to specify a username and password when creating the security credentials? How do I handle things like password resets on cloudant?]
Thanks
I'm passing these credentials down - is this safe?
If your site is served out over HTTPS, then a bad actor would find it difficult to glean the Cloudant username & password in flight. Your client-side app needs to retain the credentials for your app to be "logged in" (for it to retain the right to sync with the server). I like to retain the data in a PouchDB document (e.g. _local/auth - local documents are not replicated so reside only on the device you create them on). You are right to be concerned, however, about having database credentials floating about on a client-side computer. Some folks decide that that is not acceptable and implement their own middle layer. If you don't need sync (that is data can be altered at both client and server side), you might use PouchDB as a buffer for unsynced data and push it to your own API when you're online. You can then control authentication, timeout and access to the database from your own server-side code.
How would I reset / time out the username and password.
You can "log out" by:
deleting your client-side state e.g. deleting the _local/auth document.
making the key/password have no permissions on the client side. Without _reader/_writer/_replicator rights, a Cloudant api key and password is useless
Alternatively you could transmit the username & password to the client which could use them against the Cloudant POST /_session endpoint which gives the web browser a time-limited cookie. Your app could then "forget" the credentials until it needs them again.
When they log out, I wipe the data from Pouch?
Yes.
Can a user be 'logged in' and lose connection? Will pouch sync when they reconnect?
If you write your client side app correctly, it could function perfectly well with its local PouchDB data, whether it has an internet connection or not. This is known as an Offline First approach. As long as your credentials are still valid, your app can sync when a connection is re-established.
If pouch has NOT synced - and they log out (and I wipe Pouch) that would mean they would lose their data?
Correct. If you have only one copy of some data and delete it, you lose data :)
But what if they are using a shared computer? This data would be sat in Pouch DB waiting for someone to log in?
Correct. On a shared computer, another user's data may be visible to the second user. Just as if I left my Facebook session logged in on a shared computer.

Remote access to laravel models

Is it possible that a website uses the models of another lavarel website to access the database, without the first website having the sql credentials hardcoded. But with the credentials to log into the second lavarel website hardcoded.
This way the first website doesn't have to have the sql credentials on it's ftp server, but can still access the databases through the other website (with their personal login of that website).
If that is impossible, I am wondering, is there a way to access a databases without having to hardcode the credentials anywhere.
UPDATE (the actual problem)
Only a part of the database should be visible to a particular user, so i can provide different users with different credentials and they all see something different in the database
What you are talking about is an API. So you'd build out the entire infrastructure on the first website, then on the second website, it would make some kind of calls to the first website to get back the information it needs, usually using some kind of credentials or access token.
This way, you can allow anyone in the world to communicate with your website, kind of like how Facebook, or Twitter does.
As far as accessing your database, you would need to tell your app somewhere the credentials to use, so technically, you do need to hardcode them somewhere as they can't just magically make up some credentials somehow to access a database.
if your different users are defined:
use laravel model/db event to replicate the data to a database by
user.
Or sync each database with a cron job..
These have benefits to avoid security transport problems.

secure the code in google chrome extension

I want to write a google chrome extension, that should make a request to my website to send and get some data, so, actually I should do an ajax request like it is written here https://developer.chrome.com/extensions/xhr.html
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
I wanted ask if there is a way to somehow secure the code or prevent others from using my api, because actually the other users can see the source code of the extension when they install it and so use my api without me being aware of it.
EDIT:
If I need to make some sort of authentication, than how can I authenticate the user before making the ajax call ? for authentication I will need to send a request to my server , but for that I should send , e.g. username and password, that should be saved somewhere in the extension's files, which, in fact, can be seen by the users, when they install the extension.
Thanks
Don't trust the browser, take steps to authenticate the user instead. So, in this case, you could require that YOU enter in a password that is used to communicate with your server.
Your Google extension would simple require you to enter in a password before it attempts to use AJAX to communicate with your server.
Be aware that you should build in means of protecting yourself from brute-force attacks. So, do things like lock everything down if there are more than some small number of wrong passwords, etc.
You could also consider using the password to simply decrypt the destination of the XHR, but if you go this route, you should store this very carefully, because this will be brute-forceable offline.
EDIT
Trying to lock down an API so that only a single application can use it is just not practical nor technically possible, so you're only hope of doing this is to authenticate the user using the API, regardless of the accessing software he is using. You could have the user sign an agreement that legally limits them to only your extension, but I suspect this will go largely unenforceable and will consume your time tracking abusers down.
If you don't want unauthorized people even knowing where the API is, you could perform authentication using an out-of-band mechanism: over the telephone, email, SMS, or simply, another API that will grant the user a password or token that requests to your API must be accompanied with.
During this out-of-band process, you could also grant the user, a unique URI (the API access point) that is only valid per authenticated session (https://api.totally-cool-extension.com/api/ijyeDvB5dYvSiWG97OLuTAoNWwbhuZ0/, for example). Any requests to your server on OTHER URIs simply won't work. However, this isn't theoretically much different than using the same API access point, and having a good password. It just changes the number of places in your architecture that will be performing authentication and/or authorization checks.
<aside>My vote would be to reduce the number of authorization/authentication points to as few as possible so that you can spend more time on getting that one place correct rather than having multiple places and possibly multiple logic flaws or other things that could lead to vulnerabilities.</aside>
You could also explore using Public Key Infrastructure and/or one-time passwords schemes or device-based token generators, etc., but in the end, you'll be allowing authenticated and authorized users to use your API. And, thanks to the Internet, this will not remain an undisclosed URI for long.
And, more importantly, it will not prevent someone from using the data on their own. Even with all these measures in place, it would be trivial for an authorized user to collect this data as it is being streamed to your extension. Or, if you employ point-to-point encryption, they could screen-scrap or use some form of JS introspection on your very code or even extract the data from their computer's memory.
I know you were looking for a silver bullet here, but it doesn't exist.
I think you are doing it wrong. You should never trust what's going on on internet users PC's. Never!
Move the line of trust one step inward, make your API public and then design the security where you have perfect control - server side.
I could not get correct aspect of your use case
Few Points:
Your extension code is always traceable( Any one who has installed extension can view the code)
If you are looking for security through complicated or obfuscated coding patterns you end up slow down of understanding process not the whole.
If your target is to ensure users who install your extension should be able to access and inert all other users( Who have gained illegal access or downloaded and edited code) have a session shared key per installation.
Please explain further use case so i can help you better.

Website and Native app user authorization

I wish to create a functionality that is very similar to facebook or pokerstars if you have used them before. Basically the apps require the user to login and their information can be accessed from both browsers and native and web apps.
How can I go about achieving this? Please advice on what services to research on to accomplish this. To my current understanding. I would be creating the website in html and php and creating a webservice using RESTful protocols and hosting them on amazon aws servers. I can then connect to these servers in the native apps? I am not very clear on how the native apps will interact with the servers
If you know of any particular protocol or a better server hosting service please let me know.
If I'm interpreting your question correctly, you are looking for something like this:
The user starts either your browser app or your native app (perhaps a mobile app)
Since the user does not have an account yet, you present them with the appropriate dialog to create said account.
You then ask the "Identity Service" to create a profile for that user
The identity service returns a token for access
This is something we do in the mobile network industry all the time. Technically, we have TAC/ACS or HSS profile services, but in either case, it's the same thing -- a dedicated service and network process that:
Accepts connections from various clients (web, mobile, desktop...)
Has various primitives along the database CRUD (Create, Read, Update, Delete) model
Answers requests the database
If you want a pre-configured solution, you could just use any networked database with a RESTstyle connector for example (MongoDB maybe?) But you could also just through this in a process that talks to a NoSQL or SQLLite database. The end result is the same.
For commercial solutions, I might like at OpenStack as you can run your code on it and they have identity brokers you might be able to CoOpt.
Personally, I'd just have a datastore running on a cloud somewhere like Amazon's EC2 which answers RESTful requests such as:
Create a user with a given profile set, return a unique token
Delete a user given a token
Update elements of the profile for a given token
I'm leaving out the necessary things like security here, but you get the idea.
This also has the advantage that you can have a single identity service for all of your applications/application services. The specifics for a given application element are just sub-fields in the profile. This gives you, not only a common identity broker for web, desktop and mobile, but a single-sign-on for all your applications. The user signs in once and is authenticated for everything you have. Moving from site to site, now just became seamless.
Lastly, you place your identity management, backup, security token management, etc OUTSIDE of your application. If you later want to add Google Authenticator for second-factor authentication, you don't have to add it to every application you have.
I should also add that you don't want to keep the identity database on the direct internet connection point. Someone could make your life difficult and get ahold it later on. Rather, you want your identity server to have a private link to it. Then do something like this:
When the account is created, don't store passwords, store hashes -- much safer
Have your application (web or otherwise) compute a key as the login
In this case, the user might enter a username and password, but the application or website would convert it into a token. THAT is what you send across.
Next, using that token (and suitable security magic), use THAT as the owner key
Send that key to the datastore and retrieve any needed values
Encrypt them back into a blob with the token
Send the block
THe application decrypts the blob to get at values
Why do we do this?
First, if someone were to try to get at your identity database, there's nothing useful. It contains only opaque tokens for logins, and blobs of encrypted data. Go ahead -- take the database. We don't care.
Second, sniffing the transport gets an attacker nothing -- again, it's all encrypted blobs.
This means later on, when you have five applications using the broker, and someone hacks the network and steals the database, you don't care, because your users never gave out logins and passwords in the first place, and even if they did, the data itself is garbage to anyone without the user key.
Does this help?

Secure client-side couchApp / couchDB user authentication

Background research:
User Signup in Couchapp/CouchDB through jquery.couch.js or Otherwise
http://blog.couchbase.com/what%E2%80%99s-new-couchdb-10-%E2%80%94-part-4-security%E2%80%99n-stuff-users-authentication-authorisation-and-permissions
https://issues.apache.org/jira/browse/COUCHDB-1175 - specifically "Ari Najarian" 's posts
Question:
To paraphrase the SO question I posted above:
"Essentially I want to have a signup form for registering an account in couchdb for a couchapp. This would entail creation of a new user in the couchdb _users database, and the creation of a new database, with the new user assigned the role of database admin. All that requires server admin credentials."
The answer to the previous question involved using an external separate server that was logged in to couchdb as admin to monitor couchdb and modify couchdb as desired in response to certain data events coming from a client.
My question is - is that the only way? Doesn't that defeat the whole purpose of couchdb's 2-tier web stack? Is there some way to modify a couchdb database from within a validation function which checks for "type == user" document while "internally"/separately logged in as an admin maybe?
I apologize if there is some straightforward way to do this and I just didn't find the right documentation.
Extra Problem Clarification:
There is the couchdb instance sitting at an internet address.
This couch database serves to a random client an html page and embedded javascript script that contains a signup/login form.
The client enters signup info (name, password) and submits
The JS script uses the XMLHttpRequest object to open a connection to the couchdb instance and sends...PROBLEM!
Problem #1 - If the credentials are stored in the code (to be sent as verification for new user database), then anyone could "view html source" and take over the database.
-OR-
Problem #2 - If credentials are not supplied and the request is sent anonymously, then a new user will be created in the _users database and a success reply message will be sent. But no new database was created for the user (and can't be without admin credentials) which the user can interact with for application-specific purposes (e.g. add/delete data). And - from the above couchbase blog link - if you have secured your database with roles/names against anonymous readers and validation functions to prevent anonymous writes, then an anonymous-made user account (e.g. a client who wants to register database space to use the app) can not do anything because an anonymous user cannot, for obvious security reasons, specify whatever roles they wish to have. Which means that the only way to have -functional- users is to create user accounts + associated databases as admin beforehand and then hand out these user credentials - so like a private invite system, yes?
To reiterate, is there any way, using ONLY couchdb and some combination of couchdb's authentication handlers, design document functions, client-side ajax, etc. for a connecting client to register and get a personal database (and ONLY that database obviously) they have access to and can interact with?
This isn't a PURE couch solution, but it's couch + node, and solves your problem:
Hi I haven't been around in awhile and didn't realize this was edited / link removed (plus policy of links not being answers! sorry...). I have been using couchdb on a project very similar to what you are trying to do, and unfortunately there is no way to do what you want to accomplish without tacking on another service to handle the admin-level access and creation of user database. Syncpoint-API can be used to facilitate this, but it is actually a nodejs service handling the signup/login and dedicated database setup.
So far though, Syncpoint has proven to not be 100% reliable and it does appear to be an abandoned project, due to CouchBase sucking all the r+d resources away from CouchDB dev.
I'm now moving to nodejs + socket.io as a transport layer, using node to handshake and assign a DB, and then further watching the couch _changes api on the server (via yet another node process) to then forward _changes through socket.io to the client. Also I have some "pure" couchapps running that serve public data mixed in with the private data.
My conclusion? CouchDB is a great product and has some great features, but for the more complex login/authorization schemes and other general application needs required in real-world dev, it's just not ready yet.