service worker cache after access token is verified - service-worker

LS,
Via an index.html a new user can request for an access token. This token is sent to his/her email. The token must then be pasted in the token field to get access to the form. When the token is verified the form is shown.
To prevent access to the source of the form before the correct token is inserted I want the cache to occur after the token is verified. I used the standard minimal registration, installing and activation of the service worker.
<?php
if (exists_token($_COOKIE['session_token'], 'sessions')){
readfile('form.html');
}
....
?>
How can I delay the caching until after the token is verified, when the form.html is rendered?

I suppose you have to write some custom logic in the Service Worker script. You can communicate with the SW from the page's JavaScript by using window.postMessage. Using that, you'll be able to not cache this or that by default and then, when your conditions are met, let the SW know caching can happen via postMessage.
However, I'm not sure your approach is wise. What happens in a future time if the token expires and the page is SW cache? You would need to write custom cache-eviction code to handle that.
I don't know your application logic but maybe you could always render the form and hide it from JS or using PHP/CSS based on token verification status or smth.

Related

How to manage `state` nonce auth0 authorization code grant flow?

My application consists of a client side html/javascript, a web server, and an API (a "regular web app", as auth0 calls it). On the Authorization Code Grant doc page on Auth0, it says to create a URL like this:
https://ygctest.auth0.com/authorize?
audience=YOUR_API_AUDIENCE&
scope=YOUR_SCOPE&
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=https://YOUR_APP/callback&
state=YOUR_OPAQUE_VALUE
The doc says the state (apparently a nonce to prevent CSRF) returned from the auth0 server via query parameter to /callback needs to be compared to the originally generated state.
My question is: Where should the "state" variable be generated? And, does the state variable need to be verified on the client, server, or both?
Should I generate it on the server and pass it to the client somehow? If so, is it better to do it as a cookie, or can I just generate the entire URL serverside and stick it in the html?
If the state variable should be generated on the client side, how should the server know what the client thinks the state is? The browser is redirected from the login page to /callback (in the example), so the client doesn't have a chance to check the state. Should the client set a cookie so that the GET to /callback includes the state?
Create the session state on the server-side, store its value in session (encrypted cookie or server-side storage cache (eg. Redis). Then during the code authorization grant flow, check its value as a first action in your callback. Some libraries might handle the check for you, or else you will have to do the ceremony of pulling the state value explicitly out of session storage in your code, and comparing that explicitly against the value of state that was returned to your callback endpoint.
If you are using Auth0 Hosted Login Page, and making a call to authorize endpoint, then you can just do it all server-side - see here. If you need to render a form on UI with state value then your Controller can pass the value of your state to the view layer as a value that gets interpolated. The key takeaway is that it is recommended to generate the value server-side, store it in secured session storage, and do the comparison server-side (in the callback) for code authorization grant flow (regular web app).

Returning a refresh token with the resource owner flow

I have created an authentication server that implements OAuth 2 for authorization and it also provides local password authentication using the resource owner flow.
At the moment I always return a refresh token along with the access token which was an acceptable thing to do when I first implemented the feature. However now I need to implement a remember me feature in the client that uses the server. I could always just save the refresh token in the client when the user ticks the remember me checkbox but the token would still exist on the server and be usable even though the user didn't want it to.
What I want to do is simply pass a parameter along with the request that tells me whether I should create a refresh token or not.
So my question is. Is there some standard or recommended way of doing this using the fields provided in the spec or is it acceptable to simply add a parameter to the request to handle this use case?
AFAIK, there is no standardized way to choose whether to issue a refresh token or not.

Is it normal for my __RequestVerificationToken to be different with every request?

I've Google'd, but haven't been able to determine if ASP.NET MVC's v4 RequestVerificationToken should be different for every request?
I notice this in all environments, even when running on a single server. The user is logged in, but when refreshing the page (F5) a different token is generated every time.
Is this normal or not?
This is completely Normal. No difference when a user is logged in or not.
Note that: Synchronizer token pattern is a technique where a token, secret and unique for each request, is embedded by the web application in all HTML forms and verified on the server side. The token may be generated by any method that ensures unpredictability and uniqueness (e.g. using a hash chain of random seed). The attacker is thus unable to place a correct token in his requests to authenticate them

How to pass the CSRF token between rails applications

Our rails3 application talks to another rails application exposed as REST functions. We get the following warning post migration to rails3 on all POST calls made to the REST services.
WARNING: Can't verify CSRF token authenticity
How should we pass the csrf token on the wire when we make a POST call to the REST services, the ApplicationController has protect_from_forgery method and the call also lands on the handle_unverified_request call. We use HTTP basic auth to authenticate and it seems to work fine. What should we do to resolve this issue.
Ok now I'll give it a shot to answer your question.
CSRF tokens are "session dependent" this means the user must share a session with the application he is communicating with. This means a request must have been made before he submits the actual form which is the case for standard HTML forms where the form is displayed before it is submitted so there's room to generate a CSRF token for this user.
Let's call the Application which serves the UI Button App1 and the one hosting the REST Service App2.
The User shares a session with App1 and gets the UI Button served by App1. Once the user clicks the button a request to App1 is made, and App1 makes a request to the REST Service of App2.
Conclusion: The user doesn't share a session with App2 but your App1 has a session with App2. This concludes in two things:
The User is not vulnerable to Cross-Site-Forgery on App2 because he doesn't have a session on that server. So if I post a something like <img src="http://app2.com/rest-service/destroy> here, App2 wouldn't recognise me because I don't share a session with App2 and nothing happens.
You can implement your own security measures on the REST Service to secure it from the public:
Authentication by HTTP Basic Auth
Authentication by an API Key
....
This means you can drop the CSRF protection on the REST Service and stay on the safe side as long as user's can't make direct calls via AJAX etc.
Addition
CSRF protects your site from submitted forms that do not come from your origin (actually this applies to POSTed forms only since they usually manipulate data.
The big scenario is: I'm the attacker and I'd like to update your users account name to "Mr. Potatoe" the way I'd do that is to place a hidden form on my website which gets POSTed to Yourdomain.com/account with a hidden field like account[name]="Mr. Potatoe". Now what happens without CSRF protection? My browser submits the form, and sends the authentication cookie with it and my name is now "Mr. Potatoe". What happens with CSRF protection? My browsers submits the form and sends the cookie but the form has no CSRF token so the request gets rejected. Now is there a way as attacker to get the CSRF token under these circumstances? The answer is no. Maybe you ask yourself....
What if I place a hidden iframe on my site which points to Yourdomain.com/account/edit and just copy the hidden field containing the token? - Answer: It won't work because of same origin policy, you can't read whats inside an iframe if its content doesn't come from your domain.
What if I make an AJAX call in the background to get the token? Answer: It won't work because using pure AJAX you are bound to the same origin policy as well.
Now let's get to the point: I can't send a hidden AJAX call from my page to yours to harm your user who is on my site.
What does it mean? You can implement a before filter which checks if request.xhr? is true or whether the user agent is something like "My REST Client XY" because this can't be forged by a cross site request in a >>browser<<. So if this is the case you can ignore/disable the CSRF protection.
By the way if you want to make an AJAX request within your site you can get the CSRF token like this:
var token = $('meta[name="csrf-token"]').attr('content');
See the Rails UJS Script: https://github.com/rails/jquery-ujs/blob/master/src/rails.js#L81
NOTE: this only protects you from cross site forgery and nothing else....

Cookies - I may be crazy with ruby/rails

Is it possible to login with net/http or curl, save the cookie response then write that cookie to the users browser so I can "push login" (in a sense)?
Is there another way of doing this, is this even possible, or am I simply crazy?
I'm aware of how I can login with net/http save the cookie and do things serverside.
I just don't want to spend the time saving the cookie to the database and then writing it to a browser and when successful redirect the browser if this isn't possible because of security restrictions.
You can only write cookies for the current domain - so if you're wishing to effectively connect to domainb.com from domaina.com over net/http, read the cookie returned from domainb.com and preset that for the user before redirecting them to domainb.com, then that won't work.
However, if you simply want to read the returned cookies from domainb.com and effectively duplicate them on domaina.com then there is no reason you can't do that. Something like:
# perform your request...
# once the response has been returned, loop through each cookie
response.get_fields('set-cookie').each do |cookie|
# set your local cookie here
end
If you want to implement automatic login between 2 domains, the best way I've found to do it is:
1) domaina.com says "hey I've got user ABC here, can I have an auth token for them?" to domainb.com's API.
2) domainb.com's API creates a token for that user, limiting expiry to say 1 minute, then sends that as a response to domaina.com
3) domaina.com redirects the user to domainb.com with the authentication token passed as a parameter
4) domainb.com receives the user's request (from the redirect), looks up the token in the DB, then automatically logs the user in, if it's found
Of course that does require that you control the systems of both domains... if you don't the likelihood is that oauth will be your best mechanism of cross-site authentication.
This sounds like a good fit for authentication_token based login, where as long as the link is correct (e.g. http://www.example.com/posts/new?auth_token=1asdfj2828728we924834), the user is auto-logged in. Check out Devise: http://www.hyperionreactor.net/blog/token-based-authentication-rails-3-and-rails-2

Resources