1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-15 20:29:03 +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
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
is now more compliant with RFC 6265:
- empty attributes are tolerated

View File

@@ -657,7 +657,7 @@ end
local function parse_status_line(status_line, response)
response["status-line"] = 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
return nil, string.format("Error parsing status-line %q.", status_line)
end
@@ -2895,6 +2895,58 @@ do
test_suite:add_test(unittest.keys_equal(parsed, test.parsed), test.name)
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
return _ENV;