LibXML: Add element-nesting depth limit for XML-parsed documents
This change adds a limit of 5000 on the count for how deeply elements can be nested in documents parsed with our XML parser. Blink and WebKit both have such a limit, and both set it at 5000. This prevents bad actors from performing attacks by giving us XML docs with pathological levels of nesting, and causing stack exhaustion.
This commit is contained in:
parent
5cc3e136e4
commit
cfe5ef32e1
1 changed files with 24 additions and 0 deletions
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
namespace XML {
|
||||
|
||||
static constexpr int MAX_XML_TREE_DEPTH = 5000;
|
||||
|
||||
struct ParserContext {
|
||||
Listener* listener { nullptr };
|
||||
Optional<ParseError> error;
|
||||
|
|
@ -26,6 +28,8 @@ struct ParserContext {
|
|||
Version version { Version::Version11 };
|
||||
|
||||
Vector<ParseError> parse_errors;
|
||||
|
||||
int depth { 0 };
|
||||
};
|
||||
|
||||
static ByteString xml_char_to_byte_string(xmlChar const* str)
|
||||
|
|
@ -91,6 +95,24 @@ static void start_element_ns_handler(void* ctx, xmlChar const* localname, xmlCha
|
|||
if (!context)
|
||||
return;
|
||||
|
||||
if (++context->depth > MAX_XML_TREE_DEPTH) {
|
||||
size_t offset = 0;
|
||||
if (parser_ctx->input && parser_ctx->input->cur && parser_ctx->input->base)
|
||||
offset = static_cast<size_t>(parser_ctx->input->cur - parser_ctx->input->base);
|
||||
|
||||
ParseError parse_error {
|
||||
.position = LineTrackingLexer::Position { .offset = offset },
|
||||
.error = ByteString("Excessive node nesting."sv),
|
||||
};
|
||||
context->parse_errors.append(parse_error);
|
||||
|
||||
if (context->listener)
|
||||
context->listener->error(parse_error);
|
||||
|
||||
xmlStopParser(parser_ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder name_builder;
|
||||
if (prefix) {
|
||||
name_builder.append(xml_char_to_string_view(prefix));
|
||||
|
|
@ -162,6 +184,8 @@ static void end_element_ns_handler(void* ctx, xmlChar const* localname, xmlChar
|
|||
if (!context)
|
||||
return;
|
||||
|
||||
--context->depth;
|
||||
|
||||
StringBuilder name_builder;
|
||||
if (prefix) {
|
||||
name_builder.append(xml_char_to_string_view(prefix));
|
||||
|
|
|
|||
Loading…
Reference in a new issue