1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-18 13:39:02 +00:00

Allows HTTP response status lines without a reason phrase. RFC 7230,

section 3.1.2, syntactically requires its presence but prescribes that
clients should ignore it regardless. Some real-world servers do not
use it so NSE could not interact with them without this change.
This commit is contained in:
nnposter
2018-06-18 20:57:43 +00:00
parent 356501dcd0
commit f6790a865e
2 changed files with 56 additions and 1 deletions

View File

@@ -25,6 +25,9 @@ o [GH#1204] Nmap could be fooled into ignoring TCP response packets if they
used an unknown TCP Option, which would misalign the validation, causing it used an unknown TCP Option, which would misalign the validation, causing it
to fail. [Clément Notin, Daniel Miller] to fail. [Clément Notin, Daniel Miller]
o [NSE]The HTTP response parser now tolerates status lines without a reason
phrase, which improves compatibility with some HTTP servers. [nnposter]
o [NSE][GH#1169][GH#1170][GH#1171]][GH#1198] Parser for HTTP Set-Cookie header o [NSE][GH#1169][GH#1170][GH#1171]][GH#1198] Parser for HTTP Set-Cookie header
is now more compliant with RFC 6265: is now more compliant with RFC 6265:
- empty attributes are tolerated - empty attributes are tolerated

View File

@@ -657,7 +657,7 @@ end
local function parse_status_line(status_line, response) local function parse_status_line(status_line, response)
response["status-line"] = status_line response["status-line"] = status_line
local version, status, reason_phrase = string.match(status_line, local version, status, reason_phrase = string.match(status_line,
"^HTTP/(%d+%.%d+) +(%d+) +(.-)\r?\n$") "^HTTP/(%d+%.%d+) +(%d+)%f[ \r\n] *(.-)\r?\n$")
if not version then if not version then
return nil, string.format("Error parsing status-line %q.", status_line) return nil, string.format("Error parsing status-line %q.", status_line)
end end
@@ -2895,6 +2895,58 @@ do
test_suite:add_test(unittest.keys_equal(parsed, test.parsed), test.name) test_suite:add_test(unittest.keys_equal(parsed, test.parsed), test.name)
end end
end end
local status_line_tests = {
{ name = "valid status line",
line = "HTTP/1.0 200 OK\r\n",
result = true,
parsed = {
version = "1.0",
status = 200,
}
},
{ name = "malformed version in status line",
line = "HTTP/1. 200 OK\r\n",
result = false,
parsed = {
version = nil,
status = nil,
}
},
{ name = "non-integer status code in status line",
line = "HTTP/1.0 20A OK\r\n",
result = false,
parsed = {
version = "1.0",
status = nil,
}
},
{ name = "missing reason phrase in status line",
line = "HTTP/1.0 200\r\n",
result = true,
parsed = {
version = "1.0",
status = 200,
}
},
}
for _, test in ipairs(status_line_tests) do
local response = {}
local result, error = parse_status_line(test.line, response)
if test.result then
test_suite:add_test(unittest.not_nil(result), test.name)
else
test_suite:add_test(unittest.is_nil(result), test.name)
test_suite:add_test(unittest.not_nil(error), test.name)
end
test_suite:add_test(unittest.equal(response["status-line"], test.line), test.name)
if result then
test_suite:add_test(unittest.equal(response.status, test.parsed.status), test.name)
test_suite:add_test(unittest.equal(response.version, test.parsed.version), test.name)
end
end
end end
return _ENV; return _ENV;