-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_hstspreload
173 lines (142 loc) · 6.24 KB
/
check_hstspreload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env python3
#-------------------------------------------------------------------------------
import os
import sys
import subprocess
import argparse
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
#-------------------------------------------------------------------------------
_candebug = False
def candebug():
global _candebug
return _candebug
def setcandebug(value):
global _candebug
_candebug = value
def infomsg(msg):
if candebug() == True:
print(msg, flush=True)
def exitnagios(status,message):
if status=="OK":
exitcode = 0
elif status=="WARNING":
exitcode = 1
elif status=="CRITICAL":
exitcode = 2
elif status=="UNKNOWN":
exitcode = 3
else:
exitcode = 4
print(status+": "+message, flush=True)
sys.exit(exitcode)
#-------------------------------------------------------------------------------
def generatedriver(proxy):
chrome_options = Options()
chrome_options.add_argument("--incognito")
chrome_options.add_argument("--disk-cache-size=0")
chrome_options.add_argument("--media-cache-size=0")
chrome_options.add_argument("--enable-features=EphemeralGuestProfilesOnStartup")
chrome_options.add_argument("--headless=new")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--in-process-gpu")
chrome_options.add_argument("--use-gl=angle")
chrome_options.add_argument("--use-angle=swiftshader-webgl")
chrome_options.add_argument("--proxy-server="+proxy)
chrome_service = webdriver.ChromeService(executable_path="/usr/bin/chromedriver")
driver = webdriver.Chrome(options=chrome_options,service=chrome_service)
#driver.implicitly_Wait(10, TimeUnit.SECONDS)
return driver
def check_page_loaded(driver):
#self.log.info("Checking if {} page is loaded.".format(self.driver.current_url))
page_state = driver.execute_script("return document.readyState;")
return page_state == "complete"
def wait_page_loaded(driver):
timestamp = time.time()
while True:
if check_page_loaded(driver) == True:
break
if time.time() - timestamp > 20:
break
#-------------------------------------------------------------------------------
def dohstspreloadcall(proxy,domain):
infomsg(proxy)
infomsg(domain)
try:
driver = generatedriver(proxy)
wait = WebDriverWait(driver,20)
action=ActionChains(driver)
infomsg("browser OK")
url = "https://hstspreload.org/?domain="+domain
driver.get(url)
infomsg("asking for navigating "+url)
time.sleep(5)
wait_page_loaded(driver)
wait.until(EC.text_to_be_present_in_element((By.ID, "status"),"Status: "))
element = driver.find_element(By.ID, "status")
infomsg(element)
statustext = None
if element == None:
exitnagios("CRITICAL","cannot find the status element")
else:
statustext = element.text.strip()
infomsg(statustext)
errors = driver.find_elements(By.CLASS_NAME, "error")
errormsgs = []
for error in errors:
cleaned = error.text.strip().replace("\n"," ")
infomsg(cleaned)
if cleaned not in errormsgs:
errormsgs.append(cleaned)
errormsg = ". ".join(errormsgs)
infomsg("ERRORS: "+errormsg)
warnings = driver.find_elements(By.CLASS_NAME, "warning")
warningmsgs = []
for warning in warnings:
cleaned = warning.text.strip().replace("\n"," ")
infomsg(cleaned)
if cleaned not in warningmsgs:
warningmsgs.append(cleaned)
warningmsg = ". ".join(warningmsgs)
infomsg("WARNINGS: "+warningmsg)
if statustext=="Status: "+domain+" is currently preloaded.":
exitnagios("OK","the domain is included in the preload list")
elif statustext=="Status: "+domain+" is pending submission to the preload list.":
exitnagios("WARNING","the domain is waiting to be included in the preload list")
elif statustext=="Status: "+domain+" is currently preloaded, but no longer meets the requirements. It may be at risk of removal.":
rest = errormsg
rest = rest.replace("Error: Too many redirects There are more than 3 redirects starting from `http://"+domain+"`.","")
rest = rest.replace("Error: Too many redirects There are more than 3 redirects starting from `https://"+domain+"`.","")
rest = rest.replace(". ","")
if warningmsg == "" and rest == "":
exitnagios("OK","warning about too many redirects")
else:
exitnagios("WARNING","the domain is at risk of removal - "+errormsg+" - "+warningmsg)
elif statustext=="Status: "+domain+" is not preloaded.":
exitnagios("CRITICAL","the domain is not in the preload list")
else:
exitnagios("CRITICAL","cannot parse the output "+str(statustext))
except Exception as e:
exitnagios("CRITICAL","unexpected error during the check - "+str(e))
#-------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-H', '--host', dest="host", help="Hostname")
parser.add_argument("-®", "--debug", action="store_true", dest="debug", default=False, help="be more verbose")
args = parser.parse_args()
setcandebug(args.debug)
if (args.host == ""):
exitnagios("CRITICAL","specify a host/domain to check")
proxy = ""
dohstspreloadcall(proxy,args.host)
if __name__ == "__main__":
main()
#-------------------------------------------------------------------------------