How to work around POST being changed to GET on 302 redirect? - http

Some parts of my website are only accessible via HTTPS (not whole website - security vs performance compromise) and that HTTPS is enforced with a 302 redirect on requests to the secure part if they are sent over plain HTTP.
The problem is for all major browsers if you do a 302 redirect on POST it will be automatically switched to GET (afaik this should only happen on 303, but nobody seems to care). Additional issue is that all POST data is lost.
So what are my options here other than accepting POSTs to secure site over HTTP and redirecting afterwards or changing loads of code to make sure all posts to secure part of website go over HTTPS from the beginning?

You are right, this is the only reliable way. The POST request should go over https connection from the very beginning. Moreover, It is recommended that the form, that leads to such POST is also loaded over https. Usually the first form after that you have the https connection is a login form. All browsers applying different security restrictions to the pages loaded over http and over https. So, this lowers the risk to execute some malicious script in context that own some sensible data.

I think that's what 307 is for. RFC2616 does say:
If the 307 status code is received in response to a request other
than GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
but it says the same thing about 302 and we know what happens there.
Unfortunately, you have a bigger problem than browsers not dealing with response codes the way the RFC's say, and that has to do with how HTTP works. Simplified, the process looks like this:
The browser sends the request
The browser indicates it has sent the entire request
The server sends the response
Presumably your users are sending some sensitive information in their post and this is why you want them to use encryption. However, if you send a redirect response (step 3) to the user's unencrypted POST (step 1), the user has already sent all of the sensitive information out unencrypted.
It could be that you don't consider the information the user sends that sensitive, and only consider the response that you send to be sensitive. However, this turns out not to make sense. Sensitive information should be available only to certain individuals, and the information used to authenticate the user is necessarily part of the request, which means your response is now available to anyone. So, if the response is sensitive, the request is sensitive as well.
It seems that you are going to want to change lots of code to make sure all secure posts use HTTPS (you probably should have written them that way in the first place). You might also want to reconsider your decision to only host some of your website on HTTPS. Are you sure your infrastructure can't handle using all HTTPS connections? I suspect that it can. If not, it's probably time for an upgrade.

Related

CDN: Forward to a different resource instead of redirect

I need to send different resources (specially images) for same urls depending on a complex logic based on different factors (cookie, IP, time, random). I want to take advantage of CDNs (cache, availability, proximity). So, I want this CDN to make a call to my server in order to decide which resource serve to any request. It is very important to not use redirects, so the user will never see a 30X status code.
For clarification:
User makes a request to http://resources.mydomain.com/img/a.jpg, which domain is under CDN
CDN makes a call to my server, sending url requested, cookies and user IP
My server returns the name of the real resource to serve (http://hidden.mydomain.com/img/a-version3.jpg)
CDN requests that image if not in cache
CDN responds to user request sending a-version3.jpg data, but without any redirect
Is it possible using any current commercial solution?
Yes, I think it is already supported by CDNetworks long time ago.
It is called "Origin Logic Control" now. You can check the description from http://www.cdnetworks.com/wp-content/uploads/2013/08/CDNetworks-ContentAccel-DS-EN2.pdf:
Allows a customer’s domain to require checking with the origin on every request.
You can return a special HTTP header (or special HTTP body, I am not sure now) to tell CDNetworks to return resources directly (and using cached version if available), not 30x status code.
You can enable Redirect Chasing to get what you are looking for. Alternatively, look at the Akamai blog post on Edge Redirect for a faster option.

What happens if a 302 URI can't be found?

If I make an HTTP request to get index.html on http://www.example.com but that URL has a 302 re-direct in place that points to http://www.foo.com/index.html, what happens if the redirect target (http://www.foo.com/index.html) isn't available? Will the user agent try the original URL (http://www.example.com/index.html) or just return an error?
Background to the question: I manage a legacy site that supports a few existing customers but doesn't allow new signs ups. Pretty much all the pages are redirected (using 302s rather than 301s for some unknown reason...) to a newer site. This includes the sign up page. On one of the pages that isn't redirected there is still a link to the sign up page which itself links through to a third party payment page (i.e. on another domain). Last week our current site went down for a couple of hours and in that period someone successfully signed up through the old site. The only way I can imagine this happened is that if a 302 doesn't find its intended URL some (all?) user agents bypass the redirect and then go to originally requested URL.
By the way, I'm aware there are many better ways to handle the particular situation we're in with the two sites. We're on it! This is just one of those weird situations I want to get to the bottom of.
You should receive a 404 Not Found status code.
Since HTTP is a stateless protocol, there is no real connection between two requests of a user agent. The redirection status codes are just a way for servers to politely tell their clients that the resource they were looking for is somewhere else now. The clients, however, are in no way obliged to actually request the resource from that other URL.
Oh, the signup page is at that URL now? Well then I don't want it anymore... I'll go and look at some kittens instead.
Moreover, even if the client decides to do request the new URL (which it usually does ^^), this can be considered as a completely new communication between server and client. Neither server nor client should remember that there was a previous request which resulted in a redirection status code. Instead, the current request should be treated as if it was the first (and only) request. And what happens when you request a URL that cannot be found? You get a 404 Not Found status code.

Is there a way to redirect Post requests preserving post data or an alternative?

I am setting up a CDN relying only on Header redirects or temporary URLs served by an API controlled by a Database cluster.
The Goal is to reduce hardware costs and have flexible nodes with only FTP/HTTP/PHP as requirement and create a cheap solution for websites that can work with this.
Howevery my Problem is that i want to have a static Address where file uploads (containing ClientID and Token) can be sent to. I am using simple post.
But the file should be sent directly to the most idle server.
So what I want is to have A Post request to http://whatever.com/upload.php which is redirected to http://server-in-cdn.whatever.com/upload.php whithout loosing the data.
The problem is that the post request gets converted into a GET request and Post data is lost.
The W3C documentation states that the 307 Header code could be used, but its not reliable and user confirmation is required.
Or is there an alternative? I am not really into network stuff... but I think the classic solution would be some sort of Load balancer or router running BGB/Quagga or something like that, and the traffic would still go over that node.. is that correct?
Or is there a way to totally redirect the traffic on Network/DNS basis?
Thanks in advance.

Resolve http form post as https form post

Is there a way to force a non-secure form post to be secure? I understand there are ways to automatically resolve an http URL as an https URL but with form posts, is this type of redirection too late? Will the posted data have already gone through the wire as plain text?
Is there a way to force a non-secure form post to be secure?
Technically, no. You can however make the form's action attribute a fully-qualified HTTPS site, regardless if the protocol that rendered it is secured or not.
Will the posted data have already gone through the wire as plain text?
Yes since a redirect happens on the server by issuing a 301/302 status code in the response.
Generally speaking, the page that serves up the form should be https as well. If it is not, then users have no indication before they submit the form that it will be secure (that is, there'll be no 'lock' icon until after they submit). Also, an attacker could hijack the initial page and still collect responses without any warning to the users.
By setting the 'action' to a full-qualified https URL then the data will be encrypted when it goes to the server, but it is still less secure than doing the whole thing in https from the start.
Here are a few things that come to mind:
As has already been noted, you can just set the URL of the form's action to an HTTPS address.
Change the protocol from HTTP to HTTPS before the page is posted. This would seem to be the most ideal. It also gives your visitors greater sense of security by seeing the secured padlock before entering any info (if this even matters). Three ways to do this come to mind:
Change all links to your form page to be in HTTPS.
Detect when the page is browsed non-securely, and redirect (using client-side scripting)
Do the same thing but on the server, by sending a Location header (a.k.a. Response.Redirect).
An example of this in javascript is simple enough:
if ('https:' != window.location.protocol) {
// This assumes your secured domain is the same as the currently-browsed one...
window.location = String(window.location).replace(/^http:\/\//, 'https://');
}
Good luck!

How to redirect from HTTPS to HTTP without annoying error messages

I want to redirect users, after HTTPS login, to the HTTP pages on the site. Using HTTPS for the whole site is not going to happen.
What I have so far is the following:
User posts the login form to the secure site
The secure server validates the credentials
The secure server sends a 302 redirect to the client
This works, except on my machine in IE6 the user gets an error message because the default is to warn when exiting a secure page. These errors are a usability killer for me and thus a showstopper. I changed it so that step 3 is
Server sends html code with a meta refresh
But this is very slow; even on my local machine it's noticeably slower than doing the 302 redirect.
Is there a better way to accomplish the goal of a hassle-free redirection on standard settings that people use? IE6 represents 20%-25% of our traffic. Also, does anyone have any good info about which browsers will warn and which won't warn for the 302 redirect? I am considering black-listing IE6 so that only it gets the slow meta refresh and everyone else gets the fast 302.
Reviving an old topic , but to make it compelete posting the following so other devs can have a choice of implementation
One way of moving bettween https to http without a warning message is to use client redirect using javascript.
Steps
User enters login details on a https form and click on login button
login button will post back to https form for login validation ( assuming login is correct) will redirect to a holding page which is also under https and displays the message ( please wait while the site redirects you)
This holding page does a javascript redirect to the http page
no browser warning message will be displayed
HTH
I am considering black-listing IE6 so that only it gets the slow meta refresh and everyone else gets the fast 302.
I would do something like that. Also include a plain HTML link in the body for accessibility.
Note that some other browsers do give a similar warning about leaving an HTTPS site, but in their case it is accompanied by a (generally pre-ticked) “don't ask me again” button. So by the time they get to your site they will almost certainly have told that warning to disappear. This doesn't make the warning less pointless, but at least it alleviates the problem.
The secure server sends a 302 redirect to the client
You shouldn't 302 in response to POST. A theoretical browser that took the HTTP RFC seriously might respond to that by re-POSTing the form to the new URL. (Which, ironically, would make IE6's warning about information “being retransmitted to a nonsecure site” less misleading.) Instead use “303 See other”.
I don't think there's any other way. That error message is for the user's benefit, and is present in IE 7 and Firefox 3 now as well. The only way that I know of to prevent it is to add your site as trusted within the browser.
Update: Oh, so it's not the mixed content error. I know which one you mean, though I still don't think you can disable the error. Generally, security errors are for the users benefit to protect them from potentially dangerous sites, and as such, cannot be disable by the (potentially unsafe) website itself.

Resources