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!