POST redirect for GET request - http

I am looking at the best way to implement POST redirect. Consider this example:
Customer receives the URL: https://domain-a.com
When customer clicks on this URL, we need to redirect the customer to https://domain-b.com
The redirect needs to be over HTTPS POST. In this redirect, some parameters would also be sent.
I searched around for the best way to implement it so that it works for both JS enabled & disabled browsers.
HTTP protocol doesn't support POST redirect. I read about new HTTP status code 307 that can be used for redirect. However, it will not work for us. It says that redirect should happen in the same way as original request. In this case, original request is GET.
The method which I am thinking is this:
domain-a returns an HTML form with all the parameters. The form is present in noscript tag.
Javascript is executed on body load to automatically submit the form to domain-b. I don't want to show the experience of "Submit" button to customer for which they don't need to take any action. It should look more like a normal redirect to them.
JS disabled browser will see the form and they would need to manually click it.
I am looking for feedback on any potential issues with this approach or better way to handle this case.

Related

Push into browser's history via HTTP headers

I need to make the client to navigate through a series of redirects. After the user arrives to the destination, I'd like to allow the user to go back to an intermediate page to be redirected elsewhere.
For example, take the following diagram:
Current Page -> Processing Page -> Landing Page
Status: 3XX
|
V
Alternative Page
Disclaimer: I do not have control over Landing Page but I do have control over the others.
From the Current Page, the user is sent to the Processing Page which, after checking the DB, redirects the user to the Landing Page. What I would like is, if the user presses the back button, to be sent back to the Processing Page so it can redirect the user to the Alternative Page.
The problem is that, because of the 3XX status code, the Processing Page is never injected into the browser's history so when the users goes back, they are sent to the Current Page directly.
So far, I've achieved my goal by making Processing Page to return 200 and force a redirect via JS as the first thing but it feels like a clunky solution.
Would it be possible to achieve the same outcome with a combination of HTTP headers? Another solution, since I have control over Current Page is to place the decision making algorithm there but this is a complex enough page already that I'd rather prefer to avoid this option.
Many thanks!

"the page cannot be refreshed without resending the information" with http post method but not with get why?

When i forward a request from within a post method, a confirmation alert appear
with a message "page cannot be refreshed without resending the information".
But this alert box doesn't appear when the forward is done from a get method.
What is the reason ?
Please help.
Because a POST, in the HTTP specifications, is intended for requests that are non-idempotent, because they modify state on the server (for example, by adding a new product to a category), that would be modified again if the request was resubmlited (it would create yet a new product in the category, for example).
A GET, on the other hand, is intended for requests that are idempotent. For example, a google search is idempotent. Searching twice for the same thing doesn't modify anything on the server, and resubmitting the same request doesn't have any unwanted effect.
The browser expects web applications to respect this convention, and thus warns the user about this unwanted side-effect before re-submitting a POST request.
The usual practice is to follow the post-redirect-get pattern to let the user refresh after a post without this annoying popup, and without unwanted side-effect.
Because a GET request includes those parameters in the URL (e.g. the URL ends with ?param1=foo&param2=bar). GET requests usually don't involve sensitive data or actions that change state of the server. From the URL, you know what you're sending.
With a POST, the parameters are "hidden", submitted in the background as part of your HTTP request, and you can't see them by looking at the URL. Those params cause the server to change state, and it could cause issues if that same data was transmitted twice (e.g. you'd accidentally purchase something twice from a web store). The browser lets you know in case you don't realize you'd be resending it.

Whats the difference between the following page transfer methods

What is the difference between the following:
Server.transfer?
Response.Redirect?
Postbackurl?
When should I decide to use which?
Server.Transfer tells ASP.NET to redirect processing to another page within the same application. This happens completely server side. This is more "efficient" as it happens on the server side but there are some limitations with this method. The link below describes some of these.
Response.Redirect actually sends a HTTP 302 status code back to client in the response with a different location. The client is then responsible for following the new location. There is another round trip happening here.
PostBackUrl is not a "transfer method" but rather an property that tells the browser which URL to post the form to. By default the form will post back to itself on the server.
Here's a good link: http://haacked.com/archive/2004/10/06/responseredirectverseservertransfer.aspx
Server.Transer() works server-side. It will reply to the client with a different page than the client requested. If the client refreshes (F5), he will refresh the original page.
Response.Redirect() replies to the client that it should go to a different page. This requires an additional roundtrip, but the client will know about the redirect, so F5 will request the destination page.
PostbackUrl is a property telling an ASP control where to go when clicked on the client. This does not require an additional round trip while keeping the client informed. If you can use this method, it's generally preferable to the other choices.
Server.Transfer:
Transfers request from one page to other on server.
e.g. Browser request for /page1.aspx
Request comes on page1 where you do Server.Transfer("/page2.aspx") so request transfers to page2 And page2 returns in response but browser's address bar remains showing URL of /page1.aspx
Response.Redirect
This statements tells browser to request for next page. In this case browser's address bar also changes and shows new page URL
PostBackUrl
You can mention it on Buttons or Link buttons. This will submit the form to the page provided. It is similar to the:
<form method="post" action="/page2.aspx">

How to know if the current Servlet request is the result of a redirect?

Is there a way to know if the request has been redirected or forwarded in the doGet method of a Servlet?
In my application, when a user (whose session has timed out) clicks on a file download link, they're shown the login page, which is good. When they login, they are immediately sent the file they requested, without updating the page they see, which is bad. Basically, they get stuck on the login screen (a refresh is required).
What I want to do is interrupt this and simply redirect to the page with the link, when a file is requested as a result of a redirect.
Perhaps there are better ways to solve this?
The redirect happens client-side. The browser is instructed by the previous request to send a new request, so to the server it does not make a difference. The Referer header might contain some useful information, but it's not certain.
When redirecting you can append some parameter, like ?targetPage=dowloadpage and then check if the parameter exists. You may have to put this in a hidden field on the login page if you want it to be transferred through multiple pages.
If you're using container managed authentication, then I don't believe you can detect this since the server will only involve your resource once authentication has been completed successfully.
If you're managing authentication differently, please explain.

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!

Resources