summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-09-05 15:30:32 +0200
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-09-05 18:23:12 +0200
commite3c13af9761895a19fb1f58abf920190aa739348 (patch)
treef64420fcf74f6124ad53665ccb8a3e781c4b6007 /security
parent2b223cce089bb8cbfb1a463fdd42e09eee63c7b2 (diff)
downloaduxp-e3c13af9761895a19fb1f58abf920190aa739348.tar.gz
Properly implement various HSTS states.
Previously, HSTS preload list values could be overridden temporarily due to counter-intuitive behavior of the API's removeState function. This adds an explicit flag to the API for writing knockout values to the Site Security Service, with the default resetting to whatever the preload list state is.
Diffstat (limited to 'security')
-rw-r--r--security/manager/ssl/nsISiteSecurityService.idl12
-rw-r--r--security/manager/ssl/nsSiteSecurityService.cpp31
2 files changed, 27 insertions, 16 deletions
diff --git a/security/manager/ssl/nsISiteSecurityService.idl b/security/manager/ssl/nsISiteSecurityService.idl
index 753f32b571..b615771524 100644
--- a/security/manager/ssl/nsISiteSecurityService.idl
+++ b/security/manager/ssl/nsISiteSecurityService.idl
@@ -23,7 +23,7 @@ namespace mozilla
[ref] native nsCStringTArrayRef(nsTArray<nsCString>);
[ref] native mozillaPkixTime(mozilla::pkix::Time);
-[scriptable, uuid(275127f8-dbd7-4681-afbf-6df0c6587a01)]
+[scriptable, uuid(233908bd-6741-4474-a6e1-f298c6ce9eaf)]
interface nsISiteSecurityService : nsISupports
{
const uint32_t HEADER_HSTS = 0;
@@ -98,15 +98,21 @@ interface nsISiteSecurityService : nsISupports
* Given a header type, removes state relating to that header of a host,
* including the includeSubdomains state that would affect subdomains.
* This essentially removes the state for the domain tree rooted at this
- * host.
+ * host. If any preloaded information is present for that host, that
+ * information will then be used instead of any other previously existing
+ * state, unless the force parameter is set.
+ *
* @param aType the type of security state in question
* @param aURI the URI of the target host
* @param aFlags options for this request as defined in nsISocketProvider:
* NO_PERMANENT_STORAGE
+ * @param force if set, forces no-HSTS state by writing a knockout value,
+ * overriding any preload list state
*/
void removeState(in uint32_t aType,
in nsIURI aURI,
- in uint32_t aFlags);
+ in uint32_t aFlags,
+ [optional] in boolean force);
/**
* See isSecureURI
diff --git a/security/manager/ssl/nsSiteSecurityService.cpp b/security/manager/ssl/nsSiteSecurityService.cpp
index cfee79d8d1..44ee7dcc07 100644
--- a/security/manager/ssl/nsSiteSecurityService.cpp
+++ b/security/manager/ssl/nsSiteSecurityService.cpp
@@ -330,21 +330,22 @@ nsSiteSecurityService::SetHSTSState(uint32_t aType,
uint32_t flags,
SecurityPropertyState aHSTSState)
{
- // If max-age is zero, that's an indication to immediately remove the
- // security state, so here's a shortcut.
- if (!maxage) {
- return RemoveState(aType, aSourceURI, flags);
+ // Exit early if STS not enabled
+ if (!mUseStsService) {
+ return NS_OK;
+ }
+
+ // If max-age is zero, the host is no longer considered HSTS. If the host was
+ // preloaded, we store an entry indicating that this host is not HSTS, causing
+ // the preloaded information to be ignored.
+ if (maxage == 0) {
+ return RemoveState(aType, aSourceURI, flags, true);
}
MOZ_ASSERT((aHSTSState == SecurityPropertySet ||
aHSTSState == SecurityPropertyNegative),
"HSTS State must be SecurityPropertySet or SecurityPropertyNegative");
- // Exit early if STS not enabled
- if (!mUseStsService) {
- return NS_OK;
- }
-
int64_t expiretime = ExpireTimeFromMaxAge(maxage);
SiteHSTSState siteState(expiretime, aHSTSState, includeSubdomains);
nsAutoCString stateString;
@@ -367,7 +368,7 @@ nsSiteSecurityService::SetHSTSState(uint32_t aType,
NS_IMETHODIMP
nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI,
- uint32_t aFlags)
+ uint32_t aFlags, bool force = false)
{
// Child processes are not allowed direct access to this.
if (!XRE_IsParentProcess()) {
@@ -387,8 +388,9 @@ nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI,
mozilla::DataStorageType storageType = isPrivate
? mozilla::DataStorage_Private
: mozilla::DataStorage_Persistent;
- // If this host is in the preload list, we have to store a knockout entry.
- if (GetPreloadListEntry(hostname.get())) {
+ // If this host is in the preload list, we have to store a knockout entry
+ // if it's explicitly forced to not be HSTS anymore
+ if (force && GetPreloadListEntry(hostname.get())) {
SSSLOG(("SSS: storing knockout entry for %s", hostname.get()));
SiteHSTSState siteState(0, SecurityPropertyKnockout, false);
nsAutoCString stateString;
@@ -769,7 +771,10 @@ nsSiteSecurityService::ProcessPKPHeader(nsIURI* aSourceURI,
return NS_ERROR_FAILURE;
}
- // if maxAge == 0 we must delete all state, for now no hole-punching
+ // If maxAge == 0, we remove dynamic HPKP state for this host. Due to
+ // architectural constraints, if this host was preloaded, any future lookups
+ // will use the preloaded state (i.e. we can't store a "this host is not HPKP"
+ // entry like we can for HSTS).
if (maxAge == 0) {
return RemoveState(aType, aSourceURI, aFlags);
}