ResponseCache & AntiForgery conflict (VaryByHeader "Cookie") - c#

Ok, so I had this ResponseCache implemented in my project, with VaryByHeader = "Cookie"
because in the Cookie header there's a cookie specific to each authenticated user - so when I change the user, the cache is busted.
Recently I've implemented an Anti-Forgery mechanism and I sent the token via the cookie, so it can be sent to all ajax requests as a header.
But my problem now is, you've guessed it, that this breaks my responsecache varying by the "Cookie" header - which contains all cookies.
What possible solutions do I have? I am thinking about putting the userID hashed in a new header and varying by that header? or some other than cookie method to send the XSRF-TOKEN?

Related

JWT Authentication: Bearer token + Cookie

I know this topic has been discussed many times, but there are so many articles around (and answers here in SO) that I'm a bit lost.
My scenario is the following: I have a WebApi written in ASP.NET Core 6 and I want to authenticate a mobile PWA app written in VueJS, using JWT authentication.
Reading through some articles and looking at the CheatSheet recommendations here and here, this is what I have come up with:
When I try to authenticate my user in the PWA, if the user credentials match, the server generates a token which contains also a claim with a "fingerprint", a SHA256 encrypted random generated string. The same generated string is added in a dedicated cookie that is returned with the response to the client: the cookie has the HttpOnly, Secure and SameSite options enabled
Once authenticated, I store the authToken and the refreshToken in my IndexedDb. First question here: why would I need to use a sessionStorage in my case when the user will never create a different session of my PWA anyway? NOTE: my token does NOT contain any user sensitive data
Whenever I do a request from the PWA, with axios, I use the withCredentials: true option and I send to the server not only my token as a Bearer in the Authorization header, but also my fingerprint cookie
For each request received, the server unpacks the token, checks its validity (issuer, audience, signature, expiration, etc.), but also checks that the fingerprint contained in the JWT claim matches the one in the received cookie
So, from my understanding, the usage of this fingerprint guarantees that any XSS attack retrieving the token from the client storage won't be able to authenticate against my WebApi because it won't have the corresponding cookie. At the same time, the cookie is protected from XSRF attacks with the options I'm using for the cookie itself.
Is this correct? Is it strong enough?
And also: can I simplify/enhance my algorithm by using the Antiforgery token built-in mechanism provided by ASP.NET Core?

Passing authorization token to Odata client

I've been trying to consume an authorized ASP.NET Odata Web API by using an Odata client. I do know how to set the header with the token for the client, but where should the token be kept for re-use?. Because the Authorization header has to be set with each request, not just once. To be more precise, this is what I am down to:
Get user's credentials, pass them back to the API.
Get token.
Set the header for the Odata client with the token value.
I am struggling with the actions to be taken between 2nd and 3rd step: Where should the token be kept, so you could keep setting the Odata client Header with it?
This is how I set the authorization header value.
EDIT: In regards to the comment, I might've not clearly specified the issue. The problem arises, because controllers will be created for every request and will be garbage collected "sometime after" the request has completed. So, the token value will be gone.
have a look here, they are storing it in a cookie. If you do not want to expose the actual token on the client side, store it somewhere near your e.g. user profile / session, or store the token with a generated id in a lookup-table and save the id to a cookie.
this is another approach using ASP.NET Identity and ApplicationCookies

Obtaining the CSRF Token ID from web site using c#

I have a situation where i will have to download the file from the website. It is a secured site (https) and also It requires the client certificate authentication.
I have a client certificate and managed to get in. After logged in, when i tried to download the file, i am not able to download the file. In turn, the file contains the html with csrftoken. How to get this token id? In order to download the file i need this token. Could someone share what kind of authentication this, and how can i get the csrf token id using c#.
Thanks
It is not authentication. Its security to prevent cross site request forgery.
The technique is:
Any state changing operation requires a secure random token (e.g CSRF
token) to prevent against CSRF attacks.
Unique per user & per user session
Tied to a single user session
Large random value
Generated by a cryptographically secure random number generator
The CSRF token is added as a hidden field for forms or within the URL
if the state changing operation occurs via a GET
The server rejects the requested action if the CSRF token fails
validation
In your case the workflow should be near to this:
Client make a request (tipicaly a HTTP GET) to see info in their
screen.
The response HTML has a hidden field in the generated Form with
the CSRF token.
Client makes a POST when click on a button with the following data: File identification he
wants to download and the CSRF token.
Server checks that this token is valid for this POST.
Server sends the file bites to the response stream.
So, if you want to download a file programmatically with C# I think that you should do a GET first as if you were a webBrowser; retrieve the CSRF token parsing the responsed HTML and send a POST whith the file and the CSRF token.

How to redirect a user to a different server and include HTTP basic authentication credentials?

I have a web application (C# - ASP.net) that needs to pass a user to a page on a remote Apache server using HTTP Basic Authentication. I need to be able to pass a user name and password to this server to allow users authenticated by my application to seamlessly use the other application without being prompted to enter credentials he doesn't have. The hand-off should be secure since both systems require SSL as long as the user name and password are not in client-side script. Is there a way to do this?
Basic authentication details are encoded in the request header named "Authorization" from the client. The header contains the base64 encoded result of "username:password".
e.g. Aladdin:open sesame = Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
There are more details on the Basic Access Auth wikipedia page.
For basic authentication, the Authorization header needs to be added to every request. Usually the browser will take care of this after the user has entered their credentials into the dialog presented by the browser. If you want to avoid having your users enter these credentials, then your ASP.net server will need to sit in between the user and the Apache server (acting as a reverse proxy) adding the auth headers to every request that it forwards on behalf of your users.
It is not possible to simply visit your server once and for it to add a "token" to the request then redirect to the apache server. This approach would be possible if you were using forms/cookies for authentication and your servers presented themselves to the user as within the same domain (e.g. asp.domain.com & apache.domain.com) then the auth cookie could be set on the parent domain (e.g. domain.com) and shared - see Forms Authentication across sub-domains.
Assuming that the basic auth scheme on the Apache server is not something you can easily change, it seems like the reverse proxy is the best option. In the reverse proxy code, the HttpWebRequest is the means to create each request to the apache server and add the additional authentication headers to it.
.net will deal with encoding the credentials in the proxied request using something like:
RemoteServer remoteServer = new RemoteServer(httpContext);
HttpWebRequest request = remoteServer.GetRequest();
request.PreAuthenticate = true;
request.Credentials = new NetworkCredential(UserName, SecurelyStoredPassword);
Try using the url format https://username:password#example.com
Only other thing I can think of - if the page doesnt force its way out, load a page of their site in a frame, send it data+ controls, via javascript so it sends the login and so on. Might be feasible.

Session lost after first Twitter OAuth request

Using ASP.NET MVC, sessions are stored in SQL database (never had a problem with them, and didn't use web farm). Using also Twitterizer2 library. Using Firefox.
First request, no browser instances is opened. Browser instance is started.
We have simple form "Publish on twitter" and submit button Share.
When Share is clicked we store message in Session and redirect to Twitter's OAuth authentication (on POST submit).
We authenticate OK and return to our Action and before posting to Twitter we check if message is stored in Session (and it isn't! - it is lost immediately after Twitter redirection)
When we try another messsage Share it is now working (Session).
We solved it using a Cookie but we don't have a clue while we lost Session (first time) after returning from Twitter.
Any deas?
I'd like to ask how did you maintained the session without cookie the first time?
I think the problem can be of the cookie set process. I also experienced similar problem before a couple of weeks.
The problem was that when I make request for REQUEST token, this request is internal HTTP request (not via user browser). As a response to this request I get REQUEST token and then set it in the user session.
$token = getRequestToken();
$_SESSION['token'] = $token;
However, if the user just came to my site for first time without a session, he does not have a session cookie to sent me. Internally at the web site I have created a session for him, and stored the token inside it, but then instead of sending him response with cookie headers included, so that he "accepts" my session, I make redirect to the provider authorize endpoint. This way, the user does not get the session cookie, and when he is returned back, he is like a new user for my site.
This is the flow of the process that happened to me:
create user session in the database
setcookie(usersession) // add headers to the eventual response
get request token
set the token in the session
redirect the user (user does not receive the session cookie)
user goes to authorization point
user returns, but he is a new user for me
I'd be interested to know if you had similar problem :)
Best regards
check the request and callback domain are the same
i.e. you are making request for oauth from localhost and callback to 127.0.0.1

Categories