-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inline DTD allows XML bomb attack #71
Comments
Using 'xmerl_scan' on XML from an untrusted source is generally a bad idea anyway: it creates atoms from XML tag and attribute names, which can bring down the VM by exhausting atom table space. Anyway, FWIW, it is possible to block DTD entity definitions altogether by using a custom set of rules, and raising on creation of an entity: def parse([c | _] = doc, options) when is_integer(c) do
ets_table = :ets.new(:sweet_xml_rules, [:set, :public])
try do
{parsed_doc, _} = :xmerl_scan.string(doc, [no_dtd_entities_rules(ets_table) | options])
parsed_doc
after
:ets.delete(ets_table)
end
end
defp no_dtd_entities_rules(ets_table) do
{:rules, &no_dtd_entities_rules_read/3, &no_dtd_entities_rules_write/4, ets_table}
end
defp no_dtd_entities_rules_write(:entity, _name, _value, _state) do
raise "DTD entities not allowed"
end
defp no_dtd_entities_rules_write(context, name, value, state) do
ets_table = :xmerl_scan.rules_state(state)
case :ets.lookup(ets_table, {context, name}) do
[] ->
:ets.insert(ets_table, {{context, name}, value})
_ ->
:ok
end
state
end
defp no_dtd_entities_rules_read(context, name, state) do
ets_table = :xmerl_scan.rules_state(state)
case :ets.lookup(ets_table, {context, name}) do
[] ->
:undefined
[{_, value}] ->
value
end
end |
Are there any mitigations for this? |
hey, any update on this? |
Has there been any progress on this? |
Hi benbarber and everyone, we are discussing this internally. We'll come back to you next week. |
Hi everyone, here are a few vectors that I gathered to help make a decision:
From all that, I'm deciding that:
On a last note, it is still possible to open an issue directly for xmerl to bring changes to it, on https://bugs.erlang.org/secure/Dashboard.jspa |
I did not have much available time to work on it yet, but it's still present in my mind. I'll give an update next week, then try to give updates every two weeks at worst. |
Hi everyone, I've made a first implementation in issue-71, but it still need to be documented, real-world tested, and possibly iterated upon before I'm merging this in master |
Hi everyone, I haven't had time to work on the doc yet, but I've set up a date to do it, I'll update you next week |
Hi everyone, I'm practically done with the documentation. I haven't published a release candidate, but you can test it with: {:sweet_xml, github: "kbrw/sweet_xml", tag: "v0.7.0-rc.1"}, I'll get a few teams to test it on our side as well |
Hi, any news from testing? |
Hi oliver-kriska, I haven't had much time to allocate on this recently, so unfortunately no. That made me think about it again though. I'll get in contact with a specific team and give an update here, by next friday, on whether I could bring the new version to their project |
Hello everyone, the update is currently running on a forked xml flux with the option |
I'm unclear if this should be closed by 088b3be? |
Hey @jc00ke, the version 0.7.0 is indeed published to hex.pm. I didn't close the issue because I wanted it to act as a reminder for Kbrw to update our project to the new version, but I suppose an automated reminder would be a better way. So yes, the issue should be resolved, and obviously if there are problems with the update feedbacks are welcome. |
This is Wiki page for the vulnerability, it is a very well known XML parser vulnerability: https://en.wikipedia.org/wiki/Billion_laughs_attack.
To replicate this issue in SweetXml, you can do the following in an iex session and watch in the observer:
4 hours later, and it's still running! Memory usage is slowly climbing past 900MB, scheduler 1 utilization hovers 70%.
I was looking into xmerl a bit to see if there's a way to disable inline DTD when using xpath before opening this issue, but I'm not familiar enough with it yet. Hoping someone else may be able to chime in. The closest thing I could find was in the release notes for xmerl 1.2.3 there's an option to turn off external DTD parsing. That sounds like that wouldn't solve this issue though, because internal DTD is the problem.
Maybe something can be done by changing the arguments passed to xmerl_xpath.string/3?
One suggestion to make this safer from @ellispritchard is to set the max heap size for the process calling xmerl functions: http://erlang.org/doc/man/erlang.html#process_flag_max_heap_size
The text was updated successfully, but these errors were encountered: