Although I have been reading and testing many things I could not get a working solution. I want to do something simple, I want to restrict access to some folders to only logged users. If an user is not logged it should get a redirect to the login page.
I do not want to serve files directly using another script. I want to serve files only to authenticated files, I know that it is possible because I saw some websites like Dropbox (not sure if they use nginx) and other services (with nginx in the headers) do not allow direct access to public files without being logged.
I guess that once the user is authenticated I should add a cookie in the header in the backed so I should be able to check it in Nginx. But I do not know if I can set the cookie and do the check entirely in Nginx
I need to whitelist login and register urls. Because if I check if one cookie exists in the request and it does not exist, I will enter into an infinite loop in the login/register urls
If the cookie does not exist or is not valid, it should redirect user to the login page
I checked the following question which is almost the same as mine:
And I have been trying the next config:
location ~* ^/assets/users/images/(.*)$ {
if ($cookie_cookieafterlogin != "secret_value") {
return 301 https://example_domain.com/login;
}
}
I must say that I am a newbie to Nginx and I am starting to learn now. So the above code is partially working because it blocks direct access to anymous access but it also blocks access for logged users, so I think that I am not setting properly the cookie in my web app.
Once the user is authenticated I am sending in the header my cookie data and checking headers in the browser I can see this:
Set-Cookie cookieafterlogin=secret_value; expires=Sun, 13-Jun-2021 ....
Anyone could say me where is my mistake?
Thanks in advance!
Related
I'm working on a WordPress website: https://samarazakaz.ru/
The client discovered a strange bug. After newly opening a browser the first login always fails, second one succeeds.
I tracked down the issue to a strange cookie with the name RCPC that is being set when the login form is submitted. If the cookie is missing then the login fails regardless of proper credentials.
I searched high and wide for any information about this cookie but could not find anything useful. The only thing remotely resembling my case was on some discussion on a site called https://codeforces.com/ . But nothing on that mentioned anything related to WordPress.
The site has a bare-bones setup with Elementor and my own plugin. And nothing in my code messes with cookies or the login process. I downloaded all website files and search in all files for "RCPC" but found nothing.
The site is behind an Nginx proxy, but I could not find any connection with this cookie and Nginx either.
I noticed that the value of this cookie is constant. So, as a workaround I jerry-rigged my plugin to set this cookie any time when it's not set. But, of course, I'm not very happy with that solution because I don't know if this will just stop working one day.
Update:
I verified that this is coming from the hosting. I renamed the /wp-login.php file and made a request to it, and it didn't return a 404 error but a 200 page with the same redirect code and the header to set the cookie. The hosting is reg.ru .
As far as I can figure this is a counter measure against automated password guessing. Any request (POST, GET, etc) to the /wp-login.php will get the redirect script with the cookie setting header. Only requests containing the correct RCPC cookie will get forwarded.
Upon further testing found that the value of the RCPC cookie is some kind of hash generated from the request's IP address. Because all of our computers got the same one but from other locations its different.
This does not cause any problem if the standard WordPress login form is used because that lives at the /wp-login.php address, so the first GET request will generate the cookie. However, we had a custom login page which didn't access /wp-login.php until the form was submitted.
Based on these discoveries I made a workaround, which is simply adding a one line JS script to the login page which makes a (fetch) request to the /wp-login.php page and simply discards the result. This is enough to set the cookie in the browser so that the form will work at the first try.
Need on hosting disable test-cookie-module
We've recently run into an issue with our ASP.NET application where if a user goes to ourcompany.com instead of www.ourcompany.com, they will sometimes end up on a page that does not load data from the database. The issue seems to be related to our SSL certificate, but I've been tasked to investigate a way on the code side to fix this.
Here's the specific use case:
There is a user registration page that new users get sent to after they "quick register" (enter name, email, phone). With "www" in the URL (e.g. "www.ourcompany.com") it works fine, they can proceed as normal. However, if they browsed to just "ourcompany.com" or had that bookmarked, when they go to that page some data is not loaded (specifically a list of states from the DB) and, worse, if they try to submit the page they are kicked out entirely and sent back to the home page.
I will go in more detail if necessary but my question is simply if there is an application setting I can say to keep the session for the app regardless of if the URL has the "www" or not? Buying a second SSL cert isn't an option at this point unless there is no recourse, and I have to look at a way to solve this without another SSL.
Any ideas to point me in the right direction?
When your users go to www.ourcompany.com they get a session cookie for the www subdomain. By default, cookies are not shared across subdomains, which is why users going to ourcompany.com do not have access to their sessions.
There is a useful thread discussing this issue here. The suggested solution is:
By the way, I implemented a fairly good fix/hack today. Put this code
on every page: Response.Cookies["ASP.NET_SessionId"].Value =
Session.SessionID; Response.Cookies["ASP.NET_SessionId"].Domain =
".mydomain.com";
Those two lines of code rewrite the Session cookie so it's now
accessible across sub-domains.
Doug, 23 Aug 2005
Surely you are trying to solve the wrong problem?
Is it possible for you to just implement URL rewriting and make it consistent?
So for example, http://example.com redirects to http://www.example.com ?
For an example of managing rewriting see:
http://paulstack.co.uk/blog/post/iis-rewrite-tool-the-pain-of-a-simple-rule-change.aspx
From the browsers point of view, www.mysite.com is a different site than mysite.com.
If you have a rewrite engine, add a rule to send all requests to www that don't already have it.
Or (this is what I did) add a separate IIS site with the "mysite.com" host header and set the IIS flag to redirect all traffic to www.
In either of these cases, any time a browser requests a page without the www prefix, it will receive a redirect response sending it to the correct page.
Here's the redirect site home directory properties:
And the relevant host header setting:
This fixes the issue without requiring code changes, and incidentally prevents duplicate search results from Google etc.
Just an update, I was able to fix the problem with a web.config entry:
<httpCookies domain=".mycompany.com" />
After adding that, the problem went away.
I can't seem to find the one right answer to my problem. I'm being overwhelmed with information I'm finding on the internet, and I have no idea what I should do.
My setup is as follows : Apache server (front end), Tomcat 6.0 (back end), RapidSSL certificate is on the Apache server, my site is made up of Java Server Pages.
The problem :
I have a few pages that are under https, while the rest of the site pages are under http.
The login page I have, is under https, and I've noticed that when I login, and redirect to an http page, that the session is not being maintained. Its creating a new one, which results in the user being sent to my 'session expired' page, when really, upon a successful login, they would be redirected to a different page.
Questions:
Why is the session not maintained when switched from https to http?
How do I fix this problem?
I need the session attributes that are created on the http pages, to be present on the https pages, so when the user is then directed to an http page again, the session hasn't been recreated, and the attributes lost.
Please ask me any questions you feel are necessary in order to help me figure this out. I greatly appreciate any help I receive. This issue has become a stumbling block for me, especially since I obviously lack the 'expertise' to figure it out myself.
Allowing the user to use the same session after logging in is a security vulnerability. Tomcat by default does not allow sessions to migrate from SSL to non SSL pages.
You should change your logic so if a user is doing a login, the session is silently updated, and logged in instead of going to the session expired page.
It's likely that you're using "secure cookies" to maintain the session: these cookies don't propagate from HTTPS to HTTP. This is generally a good thing.
You can chose not to do this, but when you transfer a session from HTTPS to HTTP you have to take extra care that you don't allow it to be reused over HTTPS later, as it may have been compromised.
Are you using a simple reverse proxy to connect to Tomcat? If that's your case, use mod_proxy_ajp to use AJP to connect Apache HTTP Server to Tomcat Application Server.
I have the same issue, where some parts of the site are https, and some are http. I've found that with Tomcat, session cookies created over http carry over to https no problem, however session cookies created over https are lost when moving to http.
One solution I have found maintaining a session as the user travels the site, is to bounce the user around when they first arrive. I created a RequestFilter with the following code:
if (request.isSecure() && session.isNew()) { // session cookie created over ssl
try { session.invalidate(); }
catch (Exception e) { /* handle error */ }
String url = request.getRequestURI().replaceFirst("https", "http");
response.sendRedirect(url);
}
else if (!request.isSecure()) {
String url = request.getRequestURI().replaceFirst("http", "https");
response.sendRedirect(url);
}
This forces new sessions to non SSL to create a lasting session cookie, and then once a session exists, the user forwarded back to secure request. This results in the session staying alive.
Or here's an options that involves less bouncing around, just overwrite the session cookie with one that isn't secure:
if (request.isSecure() && session.isNew()) {
Cookie c = new Cookie("JSESSIONID", request.getSession().getId());
c.setSecure(false);
response.addCookie(c);
}
While I realise that this is usually related to cross site scripting attacks, what I'm wondering is how can a session remain valid throughout multiple subdomains belonging to a single domain (example: a user logging in only once, and being able to access both subdomain1.domain.com and subdomain2.domain.com with the same session). I guess I first need to understand how it works, but so far I haven't been able to find much that would be of any relevance.
But then again, maybe I wasn't asking the right question.
Thanks in advance :)
Inproc sessions cannot remain valid, however you can code your web application to allow cookies across multiple subdomains. You will need to set the domain equal to:
Response.Cookies("CookieName").Domain = ".mydomain.com"
Remember the period.
There are quite a few ways to share session data or cookie data across domains. The simplest is to share it on the server side through a shared data store. But you would not be asking this question if it were that easy.
The other way to do this is equally simple. The domain one.com contains some session data say name=aleem and id=123 and wishes to pass this along to two.com. It will follow these steps:
Make a call to two.com/api/?name=aleem&id=123
When two.com gets the data via query parameters, it creates a cookie with the data. This cookie will be stored under the two.com domain.
two.com will then redirect back to the REFERER which in this case happens to be one.com
This is a simplified scenario. The domain two.com needs to be able to trust one.com and not only that but it needs to know that the request is authentic and not just crafted by the user so you need to use public/private keys to mitigate this.
By default, all cookies for a site are stored together on the client, and all cookies are sent to the server with any request to that site. In other words, every page in a site gets all of the cookies for that site. However, you can set the scope of cookies in two ways:
Limit the scope of cookies to a folder on the server, which allows you to limit cookies to an application on the site.
Set scope to a domain, which allows you to specify which subdomains in a domain can access a cookie.
You can learn more here.
The comments about the cookie being set for the domain to allow subdomains to receive that cookie give you that side but what's missing is the consistency of session.
I think this is very much like the problem of maintaining state across servers in a farm and the solution is probably to ensure that your session store is consistent across both sites (if they are not server from the same 'web site' in IIS). You can move the Session store into SQL Server (HOW TO: Configure SQL Server to Store ASP.NET Session State) which would probably serve the purpose as each site would query the same store when looking for the session data related to the cookie they've been presented with.
I hope that gets you on the right track.
If you have the ability to set up a common subdomain, you can do this:
In your subdomain html files, include a javascript file at the top like this:
<script src="http: //common.domain.com/check.asp"></script>
In check.asp, look for your logged_in cookie and if not present, show a page say, http://common.domain.com/login.asp using something like
<%
if (cookie_not_found){
%>
location.href = "http: //common.domain.com/login.asp";
<%
}
%>
Once a person submits username password, submit it back to the same login.asp and set the session cookie, (which will be set in common.domain.com domain) and then redirect to http://subdomain1.domain.com.
What will happen now is, a call will be made to the embedded "common.domain.com/check.asp", and cookies for common.domain.com will be sent by the browser along with the request. So you will know whether your session is valid or not, even when you are in subdomain1.domain.com.
You can set a cookie for a specific domain.
In php, the setCookie() method contains a parameter in which you can specify the top-level domain, so the cookie is valid for all subdomains. Based on your tags, I see you are working in asp.net. Probably this also exists for asp...
after a little search for asp:
try this:
Response.Cookies("CookieName").Domain = ".mydomain.com"
or read this
Here is a solution which works:
http://anantgarg.com/2010/02/18/cross-domain-cookies-in-safari/
I implemented OpenID support for an ASP.Net 2.0 web application and everything seems to be working fine on my local machine.
I am using DotNetOpenId library. Before I redirect to the third party website I store the orginal OpenID in the session to use when the user is authenticated (standard practice I believe).
However I have a habit of not typing www when entering a URL into the address bar. When I was testing the login on the live server I was getting problems where the session was cleared. My return url was hard coded as www.mysite.com.
Is it possible that switching from mysite.com to www.mysite.com caused the session to switch?
Another issue is that www.mysite.com is not under the realm of mysite.com.
What is the standard solution to these problems. Should the website automatically redirect to www.mysite.com? I could just make my link to the log in page an absolute url with containing www? Or are these just hiding another problem?
Solve the realm problem that you mentioned is easy. Just set the realm to *.mysite.com instead of just mysite.com. If you're using one of the ASP.NET controls included in the library, you just set a property on the control to set the realm. If you're doing it programmatically, you set the property on the IAuthenticationRequest object before calling RedirectToProvider().
As far as the session/cookie problem goes with hopping between the www and non-www host name, you have two options:
Rather than storing the original identifier in the session, which is a bad idea anyway for a few reasons, use the IAuthenticationRequest.AddCallbackArguments(name, value) method to store the user's entered data and then use IAuthenticationResponse.GetCallbackArgument(name) to recall the data when the user has authenticated.
Forget it. There's a reason the dotnetopenid library doesn't automatically store this information for you. Directed identity is just one scenario: If the user types 'yahoo.com', you probably don't want to say to them 'Welcome, yahoo.com!' but rather 'Welcome, id.yahoo.com/andrewarnott'! The only way you're going to get the right behavior consistently is to use the IAuthenticationResponse.FriendlyIdentifierForDisplay property to decide what to display to the user as his logged in identifier. It gives more accurate information, and is easier than storing a value in the callback and getting it back. :)
I dunno how OpenID works, but LiveID gives you a token based on the combination of user and domain. I just would have forwarded www to mysite.com.
The cookies and sessions and everything else get lost between www.site.com and site.com. I don't have patience enough to thoroughly read all the specs, but http://www.w3.org/Protocols/rfc2109/rfc2109 states that
A is a FQDN string and has the form
NB, where N is a non-empty name
string, B has the form .B', and B' is
a FQDN string. (So, x.y.com
domain-matches .y.com but not y.com.)
Note that domain-match is not a
commutative operation: a.b.c.com
domain-matches .c.com, but not the
reverse.
I think that means yes, you do need to forward to www. I have always added domain correction code to my sites when cookies and sessions are being used.