mirror of
https://github.com/mozilla/cipherscan.git
synced 2024-11-22 14:23:41 +01:00
report ciphers causing incompatibility for Firefox
It turns out that the situation is even more bleak for Firefox with regards to RC4, add it to report
This commit is contained in:
parent
142726c4fd
commit
1b4dcc4393
@ -21,9 +21,38 @@ def natural_sort(l):
|
|||||||
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
|
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
|
||||||
return sorted(l, key = alphanum_key)
|
return sorted(l, key = alphanum_key)
|
||||||
|
|
||||||
|
""" list of ciphers offerred by Firefox 29 by default """
|
||||||
|
firefox_ciphers=[
|
||||||
|
'ECDHE-ECDSA-AES128-GCM-SHA256',
|
||||||
|
'ECDHE-RSA-AES128-GCM-SHA256',
|
||||||
|
'ECDHE-ECDSA-AES256-SHA',
|
||||||
|
'ECDHE-ECDSA-AES128-SHA',
|
||||||
|
'ECDHE-RSA-AES128-SHA',
|
||||||
|
'ECDHE-RSA-AES256-SHA',
|
||||||
|
'ECDHE-RSA-DES-CBC3-SHA',
|
||||||
|
'ECDHE-ECDSA-RC4-SHA',
|
||||||
|
'ECDHE-RSA-RC4-SHA',
|
||||||
|
'DHE-RSA-AES128-SHA',
|
||||||
|
'DHE-DSS-AES128-SHA',
|
||||||
|
'DHE-RSA-CAMELLIA128-SHA',
|
||||||
|
'DHE-RSA-AES256-SHA',
|
||||||
|
'DHE-DSS-AES256-SHA',
|
||||||
|
'DHE-RSA-CAMELLIA256-SHA',
|
||||||
|
'EDH-RSA-DES-CBC3-SHA',
|
||||||
|
'AES128-SHA',
|
||||||
|
'CAMELLIA128-SHA',
|
||||||
|
'AES256-SHA',
|
||||||
|
'CAMELLIA256-SHA',
|
||||||
|
'DES-CBC3-SHA',
|
||||||
|
'RC4-SHA',
|
||||||
|
'RC4-MD5']
|
||||||
|
|
||||||
report_untrused=False
|
report_untrused=False
|
||||||
|
|
||||||
cipherstats = defaultdict(int)
|
cipherstats = defaultdict(int)
|
||||||
|
FF_RC4_Only_cipherstats = defaultdict(int)
|
||||||
|
FF_RC4_preferred_cipherstats = defaultdict(int)
|
||||||
|
FF_incompatible_cipherstats = defaultdict(int)
|
||||||
pfsstats = defaultdict(int)
|
pfsstats = defaultdict(int)
|
||||||
protocolstats = defaultdict(int)
|
protocolstats = defaultdict(int)
|
||||||
handshakestats = defaultdict(int)
|
handshakestats = defaultdict(int)
|
||||||
@ -53,6 +82,11 @@ for r,d,flist in os.walk(path):
|
|||||||
DES3 = False
|
DES3 = False
|
||||||
CAMELLIA = False
|
CAMELLIA = False
|
||||||
RC4 = False
|
RC4 = False
|
||||||
|
""" the following depends on FF_compat, so by default it can be True """
|
||||||
|
RC4_Only_FF = True
|
||||||
|
FF_compat = False
|
||||||
|
temp_FF_incompat = {}
|
||||||
|
FF_RC4_Pref = None
|
||||||
ADH = False
|
ADH = False
|
||||||
DHE = False
|
DHE = False
|
||||||
AECDH = False
|
AECDH = False
|
||||||
@ -92,6 +126,20 @@ for r,d,flist in os.walk(path):
|
|||||||
if 'False' in entry['trusted'] and report_untrused == False:
|
if 'False' in entry['trusted'] and report_untrused == False:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# check if the advertised ciphers are not effectively RC4 Only
|
||||||
|
# for firefox or incompatible with firefox
|
||||||
|
if entry['cipher'] in firefox_ciphers:
|
||||||
|
# if this is first cipher and we already are getting RC4
|
||||||
|
# then it means that RC4 is preferred
|
||||||
|
if not FF_compat:
|
||||||
|
if 'RC4' in entry['cipher']:
|
||||||
|
FF_RC4_Pref = True
|
||||||
|
FF_compat = True
|
||||||
|
if not 'RC4' in entry['cipher']:
|
||||||
|
RC4_Only_FF = False
|
||||||
|
else:
|
||||||
|
temp_FF_incompat[entry['cipher']] = 1
|
||||||
|
|
||||||
""" store the ciphers supported """
|
""" store the ciphers supported """
|
||||||
if 'ADH' in entry['cipher'] or 'AECDH' in entry['cipher']:
|
if 'ADH' in entry['cipher'] or 'AECDH' in entry['cipher']:
|
||||||
ciphertypes += 1
|
ciphertypes += 1
|
||||||
@ -269,6 +317,20 @@ for r,d,flist in os.walk(path):
|
|||||||
cipherstats['RC4 forced in TLS1.1+'] += 1
|
cipherstats['RC4 forced in TLS1.1+'] += 1
|
||||||
cipherstats['RC4 Preferred'] += 1
|
cipherstats['RC4 Preferred'] += 1
|
||||||
|
|
||||||
|
if FF_compat:
|
||||||
|
if RC4_Only_FF and ciphertypes != 1:
|
||||||
|
cipherstats['x:FF 29 RC4 Only'] += 1
|
||||||
|
for cipher in temp_FF_incompat:
|
||||||
|
FF_RC4_Only_cipherstats[cipher] += 1
|
||||||
|
if FF_RC4_Pref and not 'RC4' in results['ciphersuite'][0]['cipher']:
|
||||||
|
cipherstats['x:FF 29 RC4 Preferred'] += 1
|
||||||
|
for cipher in temp_FF_incompat:
|
||||||
|
FF_RC4_preferred_cipherstats[cipher] += 1
|
||||||
|
else:
|
||||||
|
cipherstats['x:FF 29 incompatible'] += 1
|
||||||
|
for cipher in temp_FF_incompat:
|
||||||
|
FF_incompatible_cipherstats[cipher] += 1
|
||||||
|
|
||||||
for cipher in tempcipherstats:
|
for cipher in tempcipherstats:
|
||||||
cipherstats[cipher] += 1
|
cipherstats[cipher] += 1
|
||||||
|
|
||||||
@ -322,6 +384,13 @@ for r,d,flist in os.walk(path):
|
|||||||
#if total % 1999 == 0:
|
#if total % 1999 == 0:
|
||||||
# break
|
# break
|
||||||
|
|
||||||
|
""" The 'x:FF 29 RC4 Preferred' counts only sites that effectively prefer
|
||||||
|
RC4 when using FF, to make reporting more readable, sum it with sites
|
||||||
|
that do that for all ciphers"""
|
||||||
|
|
||||||
|
if "x:FF 29 RC4 Preferred" in cipherstats and "RC4 Preferred" in cipherstats:
|
||||||
|
cipherstats['x:FF 29 RC4 Preferred'] += cipherstats['RC4 Preferred']
|
||||||
|
|
||||||
print("SSL/TLS survey of %i websites from Alexa's top 1 million" % total)
|
print("SSL/TLS survey of %i websites from Alexa's top 1 million" % total)
|
||||||
if report_untrused == False:
|
if report_untrused == False:
|
||||||
print("Stats only from connections that did provide valid certificates")
|
print("Stats only from connections that did provide valid certificates")
|
||||||
@ -334,6 +403,24 @@ for stat in sorted(cipherstats):
|
|||||||
percent = round(cipherstats[stat] / total * 100, 4)
|
percent = round(cipherstats[stat] / total * 100, 4)
|
||||||
sys.stdout.write(stat.ljust(25) + " " + str(cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
|
sys.stdout.write(stat.ljust(25) + " " + str(cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
|
||||||
|
|
||||||
|
print("\nFF 29 RC4 Only other ciphers Count Percent")
|
||||||
|
print("-----------------------------+---------+------")
|
||||||
|
for stat in sorted(FF_RC4_Only_cipherstats):
|
||||||
|
percent = round(FF_RC4_Only_cipherstats[stat] / total * 100, 4)
|
||||||
|
sys.stdout.write(stat.ljust(30) + " " + str(FF_RC4_Only_cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
|
||||||
|
|
||||||
|
print("\nFF 29 RC4 pref other ciphers Count Percent")
|
||||||
|
print("-----------------------------+---------+------")
|
||||||
|
for stat in sorted(FF_RC4_preferred_cipherstats):
|
||||||
|
percent = round(FF_RC4_preferred_cipherstats[stat] / total * 100, 4)
|
||||||
|
sys.stdout.write(stat.ljust(30) + " " + str(FF_RC4_preferred_cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
|
||||||
|
|
||||||
|
print("\nFF 29 incompatible ciphers Count Percent")
|
||||||
|
print("-----------------------------+---------+------")
|
||||||
|
for stat in sorted(FF_incompatible_cipherstats):
|
||||||
|
percent = round(FF_incompatible_cipherstats[stat] / total * 100, 4)
|
||||||
|
sys.stdout.write(stat.ljust(30) + " " + str(FF_incompatible_cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
|
||||||
|
|
||||||
print("\nSupported Handshakes Count Percent")
|
print("\nSupported Handshakes Count Percent")
|
||||||
print("-------------------------+---------+-------")
|
print("-------------------------+---------+-------")
|
||||||
for stat in sorted(handshakestats):
|
for stat in sorted(handshakestats):
|
||||||
|
Loading…
Reference in New Issue
Block a user