aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/xml.lua25
1 files changed, 23 insertions, 2 deletions
diff --git a/util/xml.lua b/util/xml.lua
index dac3f6fe..700da1d4 100644
--- a/util/xml.lua
+++ b/util/xml.lua
@@ -3,6 +3,7 @@ local st = require "util.stanza";
local lxp = require "lxp";
local t_insert = table.insert;
local t_remove = table.remove;
+local error = error;
local _ENV = nil;
-- luacheck: std none
@@ -13,7 +14,7 @@ local parse_xml = (function()
};
local ns_separator = "\1";
local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$";
- return function(xml)
+ return function(xml, options)
--luacheck: ignore 212/self
local handler = {};
local stanza = st.stanza("root");
@@ -64,7 +65,27 @@ local parse_xml = (function()
function handler:EndElement()
stanza:up();
end
- local parser = lxp.new(handler, "\1");
+ local parser;
+ -- SECURITY: These two handlers, especially the Doctype one, are required to prevent exploits such as Billion Laughs.
+ function handler:StartDoctypeDecl()
+ if not parser.stop or not parser:stop() then
+ error("Failed to abort parsing");
+ end
+ end
+ function handler:ProcessingInstruction()
+ if not parser.stop or not parser:stop() then
+ error("Failed to abort parsing");
+ end
+ end
+ if not options or not options.allow_comments then
+ -- NOTE: comments are generally harmless and can be useful when parsing configuration files or other data, even user-provided data
+ function handler:Comment()
+ if not parser.stop or not parser:stop() then
+ error("Failed to abort parsing");
+ end
+ end
+ end
+ parser = lxp.new(handler, ns_separator);
local ok, err, line, col = parser:parse(xml);
if ok then ok, err, line, col = parser:parse(); end
--parser:close();