Check the HSTS file is not world-writable

* hsts.c (hsts_file_access_valid): check that the file is a regular
   file, and that it's not world-writable.
   (hsts_store_open): if the HSTS database file does not meet the
   above requirements, disable HSTS at all.
This commit is contained in:
Ander Juaristi 2016-04-06 12:55:17 +02:00 committed by Tim Rühsen
parent 2e6f629061
commit 2aaf12990c

View File

@ -334,6 +334,22 @@ hsts_store_dump (hsts_store_t store, FILE *fp)
} }
} }
/*
* Test:
* - The file is a regular file (ie. not a symlink), and
* - The file is not world-writable.
*/
static bool
hsts_file_access_valid (const char *filename)
{
struct_stat st;
if (stat (filename, &st) == -1)
return false;
return !(st.st_mode & S_IWOTH) && S_ISREG (st.st_mode);
}
/* HSTS API */ /* HSTS API */
/* /*
@ -464,8 +480,6 @@ hsts_store_t
hsts_store_open (const char *filename) hsts_store_open (const char *filename)
{ {
hsts_store_t store = NULL; hsts_store_t store = NULL;
struct_stat st;
FILE *fp = NULL;
store = xnew0 (struct hsts_store); store = xnew0 (struct hsts_store);
store->table = hash_table_new (0, hsts_hash_func, hsts_cmp_func); store->table = hash_table_new (0, hsts_hash_func, hsts_cmp_func);
@ -473,24 +487,40 @@ hsts_store_open (const char *filename)
if (file_exists_p (filename)) if (file_exists_p (filename))
{ {
fp = fopen (filename, "r"); if (hsts_file_access_valid (filename))
if (!fp || !hsts_read_database (store, fp, false))
{ {
/* abort! */ struct_stat st;
FILE *fp = fopen (filename, "r");
if (!fp || !hsts_read_database (store, fp, false))
{
/* abort! */
hsts_store_close (store);
xfree (store);
fclose (fp);
goto out;
}
if (fstat (fileno (fp), &st) == 0)
store->last_mtime = st.st_mtime;
fclose (fp);
}
else
{
/*
* If we're not reading the HSTS database,
* then by all means act as if HSTS was disabled.
*/
hsts_store_close (store); hsts_store_close (store);
xfree (store); xfree (store);
goto out;
}
if (fstat (fileno (fp), &st) == 0) logprintf (LOG_NOTQUIET, "Will not apply HSTS. "
store->last_mtime = st.st_mtime; "The HSTS database must be a regular and non-world-writable file.\n");
}
} }
out: out:
if (fp)
fclose (fp);
return store; return store;
} }