Form submits over HTTP

A form on the page submits to a plain-HTTP URL. Whatever the user types, including passwords and card numbers, leaves the browser unencrypted.

Do this: Point the form action at an https:// URL. Everything typed into the form, passwords included, is posted in the clear.
PassAll forms on the page submit to HTTPS targets.
HighA form on the page submits to a plain-HTTP URL.

The fix, in one snippet

Example to adapt The action must be https
<form action="https://example.com/login" method="post">

Illustrative values. Change the paths, hostnames and options to match your own site before using it.

The sections below explain what is tested, why it matters and the alternatives.

What we test

Scan.now parses every <form> on the HTTPS homepage and resolves its action attribute against the page URL, along with any formaction attribute on submit buttons inside it. A form whose resolved target begins with http:// fails the check at high severity. Forms with no action submit to the page's own URL and pass. The report lists the form's target, its method, and whether it contains type="password", type="email" or card-number-looking fields, which raises the priority. If port 80 serves page content instead of redirecting, Scan.now also reports any password field found on that HTTP page, since credentials typed there are unprotected regardless of where the form posts. Nothing is submitted; the markup alone is examined. Other HTTP resource references are handled by mixed-content.

Why it matters

A visitor sees a padlock and a login box and reasonably assumes the password will be encrypted. If the form posts to http://, the credentials travel in the clear on the very next request, where any on-path observer, from a Wi-Fi hotspot to a compromised router, reads them. Attackers also deliberately engineer this pattern on phishing pages because the visible page looks secure. Browsers have caught up: since Chrome 86 a mixed form submission shows a full-page "The information you're about to submit is not secure" warning, and Firefox shows a warning on password fields of insecure pages, so the immediate effect is lost sign-ups and lost trust even before any interception. On a plain-HTTP page, the same applies with no warning at all in older browsers. The mixed content guide and the HTTPS-only mode guide explain what users see.

How to fix it

Point the form at an HTTPS or relative URL:

<form method="post" action="/login">

Absolute http:// actions are usually generated by a framework that does not know it is behind a TLS-terminating proxy. Fix the proxy headers and the framework's trust setting rather than hard-coding URLs. nginx:

proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;

Django: SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'). Express: app.set('trust proxy', 1). Rails: config.force_ssl = true. Then add a CSP directive that makes the browser refuse any insecure submission, so a regression is blocked instead of shipped:

Content-Security-Policy: form-action 'self' https:; upgrade-insecure-requests

Apache: Header always set Content-Security-Policy "form-action 'self' https:". Finally, make sure port 80 redirects to HTTPS (see http-redirects-to-https), so no page containing a password field is ever served unencrypted.

Where this fits

Form submits over HTTP is check 1 of 10 that the website vulnerability scanner runs under page content and javascript, ordered the way they are worth fixing. That ordering is the point: Fixing this one while the check above it still fails buys less than it looks like.

What fixing this still leaves open

Form submits over HTTP closes one route in. Immediately below it: JavaScript library with known vulnerabilities, where the page loads a JavaScript library version with published vulnerabilities; Mixed content (HTTP resources on an HTTPS page), where the HTTPS page loads scripts, styles, frames or media over plain HTTP; Advertising and tracking endpoints, where which of the page's third-party hosts exist to advertise to the visitor or to follow them, matched against the EasyList and EasyPrivacy blocklists that also power our <a href="/ad-blocker">ad blocker</a>.

Found in the same scan

The website vulnerability scanner reports this alongside checks from other categories that are at least as serious, including Certificate chain and hostname validation, where the certificate presented for this hostname did not validate: The chain does not reach a trusted root, an intermediate is missing, the name does not match, or the certificate is self-signed or expired, and Exposed .env configuration file, where a .env configuration file is served from the web root. A single run of website vulnerability scanner answers all of them at once.

Prompt for an AI Hand this check to an assistant Sign in to copy it
The first few lines
You are a senior web engineer. I ran a security and SEO scanner against my site and it reported the finding below. Fix it properly rather than suppressing the symptom.

Finding: Form submits over HTTP (high severity)
Scanner check id: insecure-form-action
17 more lines, including the evidence and the exact fix

The rest of this prompt names the pages and line numbers we found the problem on, the configuration to change, and the constraints a good answer has to respect. It is free, it just needs an account so the work is not scraped wholesale.

Sign in with Google

Signing in is free and takes one click. We store your email address and nothing else.

References

  1. Chromium Blog: Protecting users from insecure downloads and mixed forms
  2. MDN: CSP form-action
  3. MDN: Mixed content

Related guides