I think this is important so please read this message.
There is a DoS for Ruby on Rails that is easily exploitable.
The attack involves sending a malformed xml document in
an HTTP request.
There has been an exploitable spec in the Ruby on Rails
which allows:
Anyone on the Internet to...
Send a single HTTP request to...
Any Rails Web application program using...
Rexml parsing with...
A malformed Xml document that...
Causes the Ruby process to go into a 99% CPU heavily-loaded loop.
What happens is that the Xml document (included DTD) is given as:
I'm looking for a hot fix release, or a avoidance technique.
(For example, How to disable the DTD for Rails XML Parser.)
Hi 3arrows,
Thanks for the report. I've immediately tried to contact the REXML
guys. This will be a problem for all Ruby applications that accept XML
from the outside world. So a hotfix should preferably come from them,
so it can benefit everyone in the Ruby community.
But in the mean time, it'd be great if others also looked into ways of
stopping this from the Rails side.
I've done some investigation into what's going on. It's the &x100;
entity causing issues. At the top of the doctype you define
<!ENTITY x0 "hello">
So, &x0; is 'hello'. Then:
<!ENTITY x1 "&x0;&x0;">
&x1; is 'hellohello'
That cycle continues, so &x100; would have to navigate backwards
through all 99 entities and figure out what the value is. It's pretty
big This is probably something for REXML or XmlSimple to fix. In
the meantime, someone could create a filter that scrubs doctype
entities before processing them.
Also, don't bother pinging rails apps, you can test it locally like
this:
Rick's code works very well on my test confirming the risk of this
Dos.
It will resolve serious, widespread problems.
(But, I've never checked the adverse affect.)
I'll go on additional tests.
This setting is desirable from the viewpoint of security of the Rails
based Web Application.
As far as I know, Major commercial server applications reject the
outside DTD(Doctypes) by default setting.
I should like to thank you promptly and fully for your cooperation.
This is an exponential expansion of entities -- the test XML is
requiring REXML to produce a string that is 5 * 2^100 characters long.
This isn't something for REXML to fix, because it isn't a bug; it is a
side-effect of the proper operation of the entity expansion. You have
two options: either apply the doctype-erasing process that was
suggested by Rick, or have the code that processes the SOAP message
check for DOS attacks.
There are two solutions: either remove the doctype declaration, or
have the code that interprets the SOAP message check for DOS attacks.
Removing the doctype can be done either prior to parsing:
REXML::Document.class_eval { def doctype() nil end }
(as suggested by Rick) or after parsing:
d = REXML::Document.new( bad_xml )
d << REXML::DocType.new
Unfortunately for both of these cases, the XML spec requires that
undefined entities be reported as errors, so that trying to read the
text will result in an Exception. Therefore, it really is up to the
SOAP toolkit to perform sanity checks on the DocType to see if an
exploit like this is being attempted -- you should NOT blindly delete
the DocType in an attempt to avoid this exploit.
Also, if you don't need to support XML uploads in your application,
you can disable Rails use of XMLSimple by including the following in
your environment:
Also, if you don't need to support XML uploads in your application,
you can disable Rails use of XMLSimple by including the following in
your environment: