Closed Bug 1564481 (CVE-2019-11747) Opened 5 years ago Closed 5 years ago

"Forget This Site" can override HSTS Preload List

Categories

(Core :: Security: PSM, defect, P1)

68 Branch
defect

Tracking

()

VERIFIED FIXED
mozilla70
Tracking Status
firefox-esr60 --- wontfix
firefox-esr68 69+ verified
firefox68 --- wontfix
firefox69 + verified
firefox70 + verified

People

(Reporter: thenlich+bugmoz, Assigned: keeler)

References

Details

(Keywords: sec-low, Whiteboard: [psm-assigned][post-critsmash-triage][adv-main69+][adv-esr68.1+])

Attachments

(2 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0

Steps to reproduce:

  1. Opened a HSTS website (which was not in HSTS preload list) with Firefox 67
  2. Get the domain included in HSTS preload list for Firefox 68
  3. Upgrading to Firefox 68
  4. Remove website from history ("Forget This Site")
  5. Restart browser
  6. Open http:// connection to the website

Actual results:

Connection is over http (unencrypted)

SiteSecurityServiceState.txt before step 4:
henlich.de:HSTS 1 18086 1594223236082,1,1,2

SiteSecurityServiceState.txt after step 5:
henlich.de:HSTS 1 18086 0,2,0,0

Expected results:

Connection should be upgraded to https, because domain is on HSTS preload list

Component: Untriaged → Data Sanitization
Flags: needinfo?(jhofmann)
Product: Firefox → Toolkit

Seems to work on more domains:

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0

Steps to reproduce:

  1. Open the URL https://hstspreload.org/ in Firefox 68
  2. Remove this website from history ("Forget This Site")
  3. Restart browser
  4. Open http://hstspreload.org/

Actual results:

Connection is over http (unencrypted)

Expected results:

Connection should be upgraded to https, because domain is on HSTS preload list

See Also: → 1119778

jc: is HSTS and the pre-load of it part of the crypto team? or general "DOM: Security".

I'm surprised this overrides the pre-load list. Is that dynamically loaded from remote settings now? Maybe it regenerates after a period if you remove it in this way and that's "good enough"?

Group: firefox-core-security → dom-core-security
Component: Data Sanitization → Security: PSM
Flags: needinfo?(jjones)
Product: Toolkit → Core

Looks like ClearDataService.jsm calls nsISiteSecurityService.removeState. I think the documentation is unclear about what this function actually does. Furthermore, it looks like it does the wrong thing. Currently it makes it so the given host is not considered HSTS (or HPKP), whereas what we actually want is to remove any indication that the user has interacted with that host, which for preloaded hosts means they will still be considered HSTS/HPKP.

Assignee: nobody → dkeeler
Flags: needinfo?(jjones)
Flags: needinfo?(jhofmann)
Priority: -- → P1
Whiteboard: [psm-assigned]
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true

Thanks for taking this, it would be great if we could have tests in the cleardata module that verify this.

I'm going to call this sec-low, since it requires specific user action.

Keywords: sec-low

To reiterate: As described on https://blog.mozilla.org/security/2012/11/01/preloading-hsts/ only under very specific circumstances should the browser behave as if the host were not on the preload list (max-age=0 --> knockout value). Manually removing a single website from history (https://support.mozilla.org/en-US/kb/delete-browsing-search-download-history-firefox#w_remove-a-single-website-from-your-history) is clearly not one of them - hence this bug.

Hopefully there are no other (exploitable) ways to trigger this behavior (which would allow an attacker to effectively disable HSTS preloading).

Side note:

parameter maxAge in nsSiteSecurityService::SetHSTSState() is defined as int64_t, but called with uint64_t maxAge.

ExpireTimeFromMaxAge() takes max-age value from header, casts it to int64_t, multiplies by 1000, and adds it to timestamp in milliseconds.

There is potential for integer overflow (HSTS standard places no upper limit on max-age). A very large max-age is valid, should not result in expiry time in past, nor which is shorter than the largest max-age value which does not overflow.

HPKP is similar, but mitigated by the fact that max-age is capped at pref setting "security.cert_pinning.max_max_age_seconds".

Not sure what happens with negative values, e.g. "max-age=-1" (an invalid value), but this should be rejected.

[Tracking Requested - why for this release]:

While this is sec-low, it seems worth tracking for ESR 68, as it is a problematic security hole.

(In reply to Thomas Henlich from comment #8)

There is potential for integer overflow (HSTS standard places no upper limit on max-age). A very large max-age is valid, should not result in expiry time in past, nor which is shorter than the largest max-age value which does not overflow.
[...]
Not sure what happens with negative values, e.g. "max-age=-1" (an invalid value), but this should be rejected.

These are good tests to add. If not in this bug, then we should open a follow-on.

Thanks - I filed bug 1566558 (note that negative values are already rejected).

Group: dom-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla70

Please nominate this for Beta & ESR68 approval when you get a chance.

Comment on attachment 9078220 [details]
bug 1564481 - reset HSTS/HPKP state to factory settings rather than storing knockout entries for preloaded sites r?jcj,KevinJacobs

Beta/Release Uplift Approval Request

  • User impact if declined: Users that use "forget about this site" could temporarily disable HSTS for preloaded sites.
  • Is this code covered by automated tests?: Yes
  • Has the fix been verified in Nightly?: No
  • Needs manual test from QE?: Yes
  • If yes, steps to reproduce: 1. Visit a site on the HSTS preload list (e.g. https://www.python.org)
  1. Open up the history panel (ctrl + h)
  2. Find and select the site, right-click on it, select "forget about this site"
  3. Wait a few seconds for that to finish
  4. Close Firefox
  5. Check that the SiteSecurityServiceState.txt file in the profile directory doesn't have an HSTS entry for that site in it ("www.python.org" in this case)
  • List of other uplifts needed: none
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): The change is fairly localized, small, and it has test coverage.
  • String changes made/needed: none
Flags: needinfo?(dkeeler)
Attachment #9078220 - Flags: approval-mozilla-beta?
Flags: qe-verify+
Attached patch patch for esr68Splinter Review

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: Users could temporarily disable HSTS for sites on the preload list if they use the "forget about this site" feature (there's also a bit of a privacy issue in that the user's profile can retain state from sites they told Firefox to "forget").
  • User impact if declined: ^
  • Fix Landed on Version: 70
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Small, localized change, has tests.
  • String or UUID changes made by this patch: none
Attachment #9079194 - Flags: approval-mozilla-esr68?
QA Whiteboard: [qa-triaged]

Comment on attachment 9078220 [details]
bug 1564481 - reset HSTS/HPKP state to factory settings rather than storing knockout entries for preloaded sites r?jcj,KevinJacobs

Avoids HSTS circumvention via the "Forget about this site" option. Approved for 69.0b7.

Attachment #9078220 - Flags: approval-mozilla-beta? → approval-mozilla-beta+

Reproduced this issue on Windows 10 with Nightly 70.0a1 from 07/15/2019.
Confirm the fix on latest Nightly 70.0a1, build ID 20190721215935. Verified on Window 10 x64, Mac OS 10.13.6 and Ubuntu 18.04.

Comment on attachment 9079194 [details] [diff] [review]
patch for esr68

Approved for 68.1esr also.
Attachment #9079194 - Flags: approval-mozilla-esr68? → approval-mozilla-esr68+

Looks like the ESR68 patch needs rebasing, however.

Flags: needinfo?(dkeeler)
Flags: needinfo?(dkeeler)

Yes, it landed with that. Sorry for not updating the bug.

Whiteboard: [psm-assigned] → [psm-assigned][post-critsmash-triage]

Verified as fixed on Beta 69.0b11 on Window 10 x64, Mac OS 10.13.6 and Ubuntu 18.04.

Tested this bug on latest ESR 68.0.2esr, build ID 20190813155538 on Windows 10 and the issue is still reproducible. I followed the STR from comment 14 and after step 6 the SiteSecurityServiceState.txt file in the profile directory contains a line with "www.python.org".

Am I missing any setting or something should go different on the ESR build?

Please note that I have retested on latest Beta 69.0b13 and here the bug is fixed.

Flags: needinfo?(dkeeler)

This is fixed in 68.1esr, not 68.0.2esr.

Flags: needinfo?(dkeeler) → needinfo?(brindusa.tot)

Thank you Ryan for clarification. Confirm the fix on esr build 68.1.0esr, build id 20190814122844.

Status: RESOLVED → VERIFIED
Flags: qe-verify+
Flags: needinfo?(brindusa.tot)
Alias: CVE-2019-11747
Whiteboard: [psm-assigned][post-critsmash-triage] → [psm-assigned][post-critsmash-triage][adv-main69+][adv-esr68.1+]
Group: core-security
CC list accessible: false
Not accessible to reporter

(I'm assuming the sec group / CC list restrictions were accidental, as the person who filed it removed access to the bug from themselves, so I'm reverting them.)

Group: core-security
CC list accessible: true
Accessible to reporter

(In reply to :Gijs (he/him) from comment #27)

(I'm assuming the sec group / CC list restrictions were accidental, as the person who filed it removed access to the bug from themselves, so I'm reverting them.)

My mistake. I intended to remove access restrictions but got confused and still can't figure it out. (Since Security Advisory 2019-25 is out there is no need to keep this confidential any more.)

(In reply to Thomas Henlich from comment #28)

(In reply to :Gijs (he/him) from comment #27)

(I'm assuming the sec group / CC list restrictions were accidental, as the person who filed it removed access to the bug from themselves, so I'm reverting them.)

My mistake. I intended to remove access restrictions but got confused and still can't figure it out. (Since Security Advisory 2019-25 is out there is no need to keep this confidential any more.)

I'm afraid you likely don't have bugzilla privileges to alter which security groups the bug belongs to yourself.

esr60 is still supported until the next 68 esr release; I think we normally keep the bug hidden until there are no more supported releases with the problem. Al, can you confirm?

Flags: needinfo?(abillings)

(In reply to :Gijs (he/him) from comment #29)

I'm afraid you likely don't have bugzilla privileges to alter which security groups the bug belongs to yourself.

And, in fact, this is a purposeful decision. We generally open up bugs no less than 45 or 60 days following a release without a reason to do so sooner.

esr60 is still supported until the next 68 esr release; I think we normally keep the bug hidden until there are no more supported releases with the problem. Al, can you confirm?

This is correct. We still support products affected by this bug. The soonest it will be opened is after the next full release of Firefox when 70 ships.

Flags: needinfo?(abillings)
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: