Chrome Extension + Devise + Rails App - Making authenticated requests from extension? - javascript

I'm building a chrome extension that facilitates the creation of contacts straight from the browser without needing to go to my devise-powered rails app itself. Contacts#Create requires authentication so I'm wondering how I can do send authenticated requests from the extension.
I've enabled devise TokenAuthenticatable and so my users have an authtoken. I've written a method in my extensions js that posts to my rails app's contacts#create action. For testing, I've simply hard coded my own auth token in, which seems to work. But how can the extension access the auth tokens for users? It doesn't seem right/secure to store this token into a cookie.
I think I'm supposed to use chrome.cookies to access and do something with my app's session info somehow. But I only get a sessionID here.
any help appreciated!

Although not from a chrome extension, I was building something similar that would work from terminal. I ended up bypassing devise and creating by own token authentication that would allow users to access just the one controller#action I needed. That way you can minimize the damage if the token gets stolen.
So anyway, I would allow users to generate (and regenerate) tokens within the rails app interface and make it so that the extension asks for the token on the very first launch. I'd store the token itself in localStorage.

You can also check authentifiation_tokenstored in your app cookie.
You can achieve this using the chrome.cookies.getAll() method detailed here - https://developer.chrome.com/extensions/cookies#method-getAll

Related

Are Javascript Instagram applications that authenticate with client_id allowed?

A few web-based applications I maintain have been using JavaScript on the page to fetch posts from Instagram* through their API, only authenticating with a client_id. With the Instagram API changes recently (applications are sandboxed until approved) this no longer works.
Is this kind of application allowed by Instagram? Or is it considered a security risk to expose the client_id in the Javascript that performs the request? If it matters, the application is for internal use by a few employees only.
* Specifically, the 10 last posts from a fixed user.
All instagram API endpoints now require a valid access_token rather than client_id. The search endpoint is an example of one that didn't previously require an access_token. You can find this in the Change logs
All API endpoints require a valid access_token
All API endpoints require a specific permission scope granted by the user
You can authorise your own account and grab the last 20 posts, but for any more than that you will need to submit your app for review
Try to create a new app.. My app was deleted instead of going to sandbox mode.
As you need 10 last posts, this should work on sandbox mode.
Content Display for Personal Website. If you are a developer and you want to showcase Instagram content on a website, then you do not need to submit your app for review. By using a client in sandbox mode, you will still be able to access the last 20 media of any sandbox user that grants you permission.

How to impersonate individual IAM users with AWS SDK in the Browser

I want to create a client-side (server-less) application using the AWS SDK for JavaScript in the Browser. All intended users of the tool have individual IAM users and access to the AWS Web Console.
I want all API calls to be executed in the context of individual IAM users, so they are subject to each user's individual permissions, and so that I can see who did what in CloudTrail.
Since no kind of browser local storage should be trusted with persistent credentials, I cannot simply let the user enter his secret access key once and keep it.
However I guess I could request the user's access key id and secret access key on the beginning of each session, then call STS GetSessionToken with it, and only store the resulting temporary security credentials in the session storage and use that for all following SDK usage.
Of course it would be much nicer for users to be able to log in with their IAM user and password instead of their long and cryptic access key (think of mobile devices...).
Is there any kind of federated login option for IAM users (redirecting them to the AWS IAM login page), or a way to call the STS API with username and password?
Ideally, what you want is login via IAM user/password combination. As far as I am aware (and also see this) there is no standard way of doing this.
In one of my projects, I've simulated online login using HTTP client. If you can get the session token with that, that could work for you. But it does not support MFA, and is relying on the internals of the AWS authentication implementation which might change without warnings.

Firebase in Cordova/Phonegap: Log in using Email/Password from within app?

I'm running a webview from a cordova app and want to authenticate a user, I know they have the OAuth strategies but I need to use the email/password combination.
I'd like to keep things simple but may end up having to generate a token.
Open an InAppBrowser that loads an auth flow for firebase
Listen for that auth flow to be completed using this method: http://blogs.telerik.com/appbuilder/posts/13-12-23/cross-window-communication-with-cordova%27s-inappbrowser
Grab the result from the webview again and insert it into the webview firebase instance
I'm guessing that's not possible due to security.
My app is using Amazon login (required) so my alternative would be:
webview loads InAppBrowser with our external url
that loads Amazon auth, then generates a token for Firebase
webview listens for token and grabs it, stores it in localstorage
Edit:
In the firebase docs on logging in with a username/password, I see it returns a token for the session and more information in the authData object:
https://www.firebase.com/docs/web/guide/user-auth.html
Could I then take all the information from that object and send it back over to the cordova webview and then populate that Firebase ref with the information?
Some answers from the wonderfully helpful support at Firebase:
First:
You’re correct – anyone can make a request to sign up, and we don’t expose any capability to secure the url which people can sign up from for email / password authentication.
The main reason that we require / enable origin whitelisting for OAuth authentication, but not for email / password authentication, tends to revolve around sessioning.
The Firebase login server does not maintain sessions (via cookies or any other method), and so requests to the login server for password auth. requires a user credential (the password) for every request. CSRF is typically a risk when a malicious party can take advantage of a user’s session browser, i.e. make requests on behalf of the user to some page where cookies are automatically sent by the browser.
Furthermore, we don’t have a great way to actually do ideal origin-based whitelisting for these pure HTTP requests. We could use CORS, but would have to fall back to JSONP for older browser environments that don’t support it. To complicate matters further, PhoneGap / Cordova apps don’t have the same notion of an “origin” at all, and from the perspective of a server – the calls are indistinguishable from any malicious party making an HTTP request with the same headers.
The OAuth providers, however, use cookies for sessioning and do not require user invention for each auth. request. If you’ve approved a particular Facebook app, you won’t be shown any UI/UX or be prompted the next time that app requests your data – it will be invisible. When we do OAuth, we never have to send any user credentials to Facebook / Twitter / etc., because those are stored in browser cookies for facebook.com / twitter.com / etc. What we need to protect is a malicious party pretending to be a popular, valid Facebook app. and taking advantage of that short-circuit behavior that would get access to user data without the user’s knowledge.
My response:
So, how is that secured? If anyone can make a request to sign up from a
cordova webview (which comes from no specific url, just the app iteself)
then I can't secure from which url people can sign up from? So any site
could use our url "xxx.com" in their config and start registering
users?
That doesn't seem right to me.
I think I still need to have an external url that is whitelisted by you
guys. That would have the login form and do the auth.
But then my question is, can I transfer that auth back to my cordova app?
Is it somewhere in localStorage I can check? I'll have to run some tests.
And final response:
Sure thing – we’re happy to help. I wrote much of the original client authentication code, and can speak to the design decisions and rationale that went into it. Be sure to let me know if you have further questions there.
While we don’t store user passwords in cookies, of course, we maintain a Firebase auth. token in LocalStorage. Our authentication tokens are signed by your unique Firebase secret (so they cannot be spoofed), and can contain any arbitrary user data that would be useful in your security rules.
By default, and when using the delegated login (email + password) service, these tokens will only contain a user id to uniquely identify your users for use in your security rules. For example, you could restrict all writes or reads to a given path (e.g. write to /users/$uid/name) by the user id present in the token (“.write” = “$uid = auth.uid”). Much more information on that topic available on our website.
Your plan to spin up a server to authenticate users with Amazon and generate tokens sounds correct. This is a common pattern for our users who wish to use authentication methods that we don’t support out-of-the-box (ie Amazon OAuth) or have custom auth requirements. Note: once you’ve created those tokens and sent them down to the client, they’ll be automatically persisted for you once you call ref.authWithCustomToken(…). Subsequent restarts of the app will use the same token, as long as it has not yet expired.
This is a topic of interest to me too as I have implemented something similar , twitter digits (native android) + firebase custom login in webview.
I think, as recommended by firebase, you can use other authentication providers and then the firebase custom login.
Do you use the Amazon login in android native code ? If so after login, then generate a JWT token for firebase and use it to access firebase.
If all code is in Html/js app, then maybe you can use custom login and generate a token on your server after making sure its logged in to the Amazon.
The trouble with Android hybrid apps is the following: the JWT token (for firebase) should be created on secure system (eg. server side) not with android java code, other option for hybrid app is to do a http request to generate the token, but I find that less secure, anyone would be able to get a token by finding the URL, than I resort to generate token within android app code, you can change security key/seed for token when doing new releases.
In summary, I don't think firebase studied the problem of mobile hybrid apps.

oAuth2 authentication on a JavaScript app

I'm planning to refactor a legacy Rails 2 app by splitting the logic into a RESTful API, and the view into a separate Javascript client. The API itself will be protected by oAuth2. This is basically the second option explained on this question:
Separate REST JSON API server and client?
There's a lot of questions out there concerning the security of using oAuth with a JS app, the main concern seems to be that storing the access token on the client is a bad idea since it acts as a password and someone that has physical access to the computer can hijack the user's identity. A possible solution I've read is to expire the access token every 1h or so and use the refresh token stored on Yahoo's YQL to request a new token when necessary. This doesn't looks to me like a good solution since at the end you'll need again a token to access the YQL service.
But at the end, aren't we facing the same problem as when using persistent sessions? I mean, AFAIK, the common method to keep the session alive across browser opening/closing (when you tick "remember me") is to generate a token associated to a user and store it both on the DB and on a long-living cookie. So again, anyone with access to this cookie has the "key" to your session. AFAIK this is the method all the "big guys" use.
I am right? And if I am, aren't we worrying too much about something that we cannot control at all? Of course I'm talking about those applications where an intrusion is not too harmful for the user like social networks, blogs, forums, etc.

Chrome extension / web app session control

I am creating a chrome extension, rather a chrome webapp. This application just contains the html, js, image and css files. The application connects to a server to fetch data. I chose to do this as it would reduce the amount of files downloaded by the user. Using Backbone.js I have an MVC architecture in my application. Thus the application just sends json.
Now having said this, I need a session management. I plan to use Google authentication as the organization has Google Apps. I need a method that once the user has logged in using google auth the server get the user name every time the application makes a request.
Is it a good idea to add the user name in request header, if possible. Or should I use cookies? Can any one tell me how I could go about using cookies in this case?
This might be a late response but I want to present a more elegant solution to you given that the user has cookies enabled in their browser.
First read my answer on another question.
Now that you can send cross origin xhr from your content scripts all you need to do is store all your authentication and session management at server only. That is right, you just need to display whether the user is logged in or not and a logout button at client based on server response.
Just follow these steps.
At client Whenever user accesses your chrome web app, blindly make XmlHttpRequests to your server without worrying about authentication, just keep a tab on response from server which I describe below.
At server whenever you receive a request check for valid sessions or session cookie. If session is valid send proper response, if not send error, 401 or any other response to communicate to your client that session is not valid. It is better if you send an error code like 401 since then you can put a generic script at client to inform them that they are not logged in.
At Client If response from server is proper, display it, else display login link to your website.
IMPORTANT: Display logout button if user is logged in.
Check out my implementation of this in my extension
For help using Google authentication in your app take a look at Google's OAuth tutorial which comes with all you need (took me no time to set it up using this).
As for session management. The implementation of OAuth used by Google stores the tokens in localStorage. Also, as briefly mentioned in the extensions overview we are expected to use localStorage to store data. Thus, I suggest you store the users name here as it will be accessible throughout the app's lifetime (until it is uninstalled). However, you may need to manage the name stored here and consider what should happen when users log in and out. That said; I'm not sure if sessionStorage would be a better option as I've never used it before, let alone in an extension.
Note
localStorage and its counterparts only store strings so I suggest using a wrapper which uses JSON to parse and stringify to get and set your values respectively.

Categories

Resources