1

I am working on a Web application and need to pass data across HTTP redirects. For example:

http://foo.com/form.html 

POSTs to

http://foo.com/form/submit.html

If there is an issue with the data, the Response is redirected back to

http://foo.com/form.html?error=Some+error+message

and the query param "error"'s value is displayed on the page.

Is there any other reliable way to pass data across redirects (ie HTTP headers, etc.).

Passing the data as query params works but isn't ideal because:

  • its cleartext (and in the query string, so SSL cant be relied on to encyrpt) so I wouldn't want to pass sensitive data
  • URIs are limited in length by the browser (albiet the length is generally fairly long).

IMPORTANT: This platform is state-less and distributed across many app servers, so I can't track the data in a server-side session object.

empire29
  • 3,729
  • 6
  • 45
  • 71
  • 2
    "*[...] and in the query string, so SSL cant be relied on to encyrpt*". Not sure what you're trying to say here (you're using plain HTTP anyway), but [HTTPS encrypts **all** the HTTP traffic](http://stackoverflow.com/a/8858241/372643). – Bruno May 04 '12 at 20:49
  • 1
    Just to stress @Bruno's comment once more: How do you come to the point that the request line is not SSL protected. Some comments later you repeat: "Cookies are encrpyted, Request line not"... This is not true. SSL tunnels IP payload, and all of the HTTP protocol is part of it (request line, header, payload...). The request line is exceptionally simple to see on *application* (browser, logs) layer. But, even a *little* more complicated, you will have the same security leak here. – mtraut May 05 '12 at 07:37

3 Answers3

1

I think using cookies would be a reasonable solution depending on the amount of data. As you can't track it on the server side (by using a sessions for example, which would be much simpler)

eduardohl
  • 1,176
  • 2
  • 10
  • 23
  • Cookies are also insecure. They're passed as plain text. – Pavel Strakhov May 04 '12 at 20:39
  • 1
    Agreed, didn't pay attention to that. But I don't think there's any way to pass data to the client side safely, unless you use encription. Maybe storing info in the users session (or database like mentioned above) would be a nicer solution. – eduardohl May 04 '12 at 20:41
  • The cookie value can be encrypted, so only a plain base64 text is passed – Arne Burmeister May 04 '12 at 21:09
  • @ArneBurmeister base64 on its own is *encoding* not *encryption*. Of course it could be base64-encoding of encrypted content. – Bruno May 04 '12 at 23:38
  • Cookies can be secured over HTTPS as they are passed via HTTP Request Headers. I thought of this after I posted and am looking at a way Cookie-based mechanism -- although most cookies also have a site limit of 4KB -- which in the real world should be sufficient for even very large forms.. – empire29 May 05 '12 at 02:10
  • @eduardohl Like i said - Session state is not an option as this is a RESTful platform. – empire29 May 05 '12 at 02:12
1

You can store error message in database on server and reference to it by id:

http://foo.com/form.html?error_id=42

If error texts are fixed you even don't need to use a database.

Also, you can use Web Storage. Instead of redirection with "Location" header you can display output page with this JavaScript:

var error_message = "Something is wrong";
if( typeof(Storage) !== "undefined" ) {
  localStorage.error_message = error_message;
else {
  // fallback for IE < 8
  alert(error_message);
}
location.href = "new url";

And after redirection you can read localStorage.error_message using JavaScript and display the message.

Pavel Strakhov
  • 39,123
  • 5
  • 88
  • 127
  • Hrm - true - this would require a persistence mechanism with some clearing/flushing routine. Not sure I like this solution that much because of this. – empire29 May 05 '12 at 02:09
1

From the client-server interaction point of view, this is a server internal dispatch issue.

Browsers are not meant to re-post the entity of the initial request automatically according to the HTTP specification: "The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD."

If it's not already the case, make form.html dynamic so that it's an HTML static file. Send the POST request to itself and pre-fill the value in case of error. Alternatively, you could make submit.html use the same template as form.html if there is a problem.

its cleartext (and in the query string, so SSL cant be relied on to encyrpt) so I wouldn't want to pass sensitive data

I'm not sure what the issue is here. You're submitting everything over plain HTTP anyway. Cookie, query parameters and request entity will all be visible. Using HTTPS would actually protect all this, although query parameters can still be an issue with browser history and server logs (that's not part of the connection, which is what TLS protects).

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
  • Oops - i meant to say the POST could optionally be SSL -- thus the body (contents of the POST) would be encrypted. Query Parameters, even on SSL/HTTPS requests, are not encrypted by SSL -- a custom encryption solution would be required. – empire29 May 05 '12 at 02:08
  • not sure im clear on your proposed solution. I am using the POST-Redirect-GET design pattern, and want to send info from the POST handler to the resultant GET response. This design pattern is absolutely inline w the guidance you cite. – empire29 May 05 '12 at 02:14
  • 1
    @empire29 query parameters **ARE** encrypted when you're using HTTPS. Check my previous answer linked in the text. You don't have to believe it, of course: read the HTTPS spec and try out with Wireshark. – Bruno May 05 '12 at 07:35
  • @empire29, for the actual pattern, I'm suggesting you don't use the "POST-Redirect-GET" pattern, but provide the error messages within the form itself as part of the POST response. That will be RESTful and stateless (since it seems to be what you say you need). – Bruno May 05 '12 at 07:42
  • user's refreshing triggering POST submissions. Also, I would argue that the resource responsible for displaying the form is /form.html and not form/submit.html .. having form/submit.html also represent the form (albiet with errors) doesn't sit well with me. – empire29 May 05 '12 at 15:57
  • Ill have to checkout the HTTPS encryption of query params. i did not realize that. wow. – empire29 May 05 '12 at 15:58
  • If you're picky about the URI structure, submit to form.html itself and use your GET redirect pattern in case of success. If you want something RESTful, passing what needs to be done next by the user (regarding errors or anything else) back in the returned representation is the way to go. [That's what REST is all about](http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven). – Bruno May 07 '12 at 19:52