diff --git a/CHANGELOG b/CHANGELOG index 00cc59e74..d8a0d67d5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] New script http-hsts-verify reports whether or not HTTP Strict + Transport Security is configured. [Ícaro Torres] + o [NSE] Script ssh-hostkey now recognizes and reports Ed25519 keys [nnposter] o [NSE][GH#627] Fixed script hang in several brute scripts due to the "threads" diff --git a/scripts/http-hsts-verify.nse b/scripts/http-hsts-verify.nse new file mode 100644 index 000000000..d761c61ba --- /dev/null +++ b/scripts/http-hsts-verify.nse @@ -0,0 +1,67 @@ +local http = require "http" +local shortport = require "shortport" +local stdnse = require "stdnse" +local table = require "table" + +description = [[ +Verify that HTTP Strict Transport Security is enabled. + +HTTP Strict-Transport-Security (HSTS) (RFC 6797) forces a web browser to communicate with a web server over HTTPS. +This script examines HTTP Response Headers to determine whether HSTS is configured. + +References: https://www.owasp.org/index.php/HTTP_Strict_Transport_Security_Cheat_Sheet +]] + +--- +-- @usage +-- nmap -p --script http-hsts-verify +-- +-- @output +-- PORT STATE SERVICE +-- 443/tcp open https +-- | http-hsts-verify: +-- | HSTS is configured. +-- |_ Header: Strict-Transport-Security: max-age=31536000 +-- +-- @args http-hsts-verify.path The URL path to request. The default path is "/". + +author = "Icaro Torres" +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" +categories = {"discovery", "safe"} + +portrule = shortport.http + +local function fail (err) return stdnse.format_output(false, err) end + +action = function(host, port) + local path = stdnse.get_script_args(SCRIPT_NAME..".path") or "/" + local response + local output_info = {} + local hsts_header = {} + + response = http.head(host, port, path) + + if response == nil then + return fail("Request failed") + end + + if response.rawheader == nil then + return fail("Response didn't include a proper header") + end + + for _, line in pairs(response.rawheader) do + if line:match("strict.transport.security") or line:match("Strict.Transport.Security") then + table.insert(hsts_header, line) + end + end + + if #hsts_header > 0 then + table.insert(output_info, "HSTS is configured.") + table.insert(output_info, "Header: " .. table.concat(hsts_header, " ")) + else + table.insert(output_info, "HSTS is not configured.") + end + + return stdnse.format_output(true, output_info) + +end diff --git a/scripts/script.db b/scripts/script.db index 44dd9df9f..fe9f6dc5a 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -189,6 +189,7 @@ Entry { filename = "http-gitweb-projects-enum.nse", categories = { "discovery", Entry { filename = "http-google-malware.nse", categories = { "discovery", "external", "malware", "safe", } } Entry { filename = "http-grep.nse", categories = { "discovery", "safe", } } Entry { filename = "http-headers.nse", categories = { "discovery", "safe", } } +Entry { filename = "http-hsts-verify.nse", categories = { "discovery", "safe", } } Entry { filename = "http-huawei-hg5xx-vuln.nse", categories = { "exploit", "vuln", } } Entry { filename = "http-icloud-findmyiphone.nse", categories = { "discovery", "external", "safe", } } Entry { filename = "http-icloud-sendmsg.nse", categories = { "discovery", "external", "safe", } }