Documentation Patch: Preventing XPath Injection attacks

Here's a patch to rexml/xpath.rb which documents the variables parameter
in REXML::XPath.

--- xpath.rb.old 2008-04-24 17:31:51.000000000 -0500
+++ xpath.rb 2008-04-24 17:37:38.000000000 -0500
@@ -15,10 +15,15 @@
     # node matching '*'.
     # namespaces::
     # If supplied, a Hash which defines a namespace mapping.
+ # variables::
+ # If supplied, a Hash which maps $variables in the query
+ # to values. This can be used to avoid XPath injection attacks
+ # or to automatically handle escaping string values.

···

#
     # XPath.first( node )
     # XPath.first( doc, "//b"} )
     # XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
+ # XPath.first( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"})
     def XPath::first element, path=nil, namespaces=nil, variables={}
       raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
       raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
@@ -38,10 +43,16 @@
     # The xpath to search for. If not supplied or nil, defaults to '*'
     # namespaces::
     # If supplied, a Hash which defines a namespace mapping
+ # variables::
+ # If supplied, a Hash which maps $variables in the query
+ # to values. This can be used to avoid XPath injection attacks
+ # or to automatically handle escaping string values.
     #
     # XPath.each( node ) { |el| ... }
     # XPath.each( node, '/*[@attr='v']' ) { |el| ... }
     # XPath.each( node, 'ancestor::x' ) { |el| ... }
+ # XPath.each( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"}) \
+ # {|el| ... }
     def XPath::each element, path=nil, namespaces=nil, variables={}, &block
       raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
       raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

may want to send that to ruby-core :slight_smile:
-R

···

On Tue, Apr 29, 2008 at 8:15 AM, Ken Bloom <kbloom@gmail.com> wrote:

Here's a patch to rexml/xpath.rb which documents the variables parameter
in REXML::XPath.

--- xpath.rb.old 2008-04-24 17:31:51.000000000 -0500
+++ xpath.rb 2008-04-24 17:37:38.000000000 -0500
@@ -15,10 +15,15 @@
                # node matching '*'.
                # namespaces::
                # If supplied, a Hash which defines a namespace mapping.
+ # variables::
+ # If supplied, a Hash which maps $variables in the query
+ # to values. This can be used to avoid XPath injection attacks
+ # or to automatically handle escaping string values.
                #
                # XPath.first( node )
                # XPath.first( doc, "//b"} )
                # XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
+ # XPath.first( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"})
     def XPath::first element, path=nil, namespaces=nil, variables={}
       raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
       raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
@@ -38,10 +43,16 @@
                # The xpath to search for. If not supplied or nil, defaults to '*'
                # namespaces::
                # If supplied, a Hash which defines a namespace mapping
+ # variables::
+ # If supplied, a Hash which maps $variables in the query
+ # to values. This can be used to avoid XPath injection attacks
+ # or to automatically handle escaping string values.
                #
                # XPath.each( node ) { |el| ... }
                # XPath.each( node, '/*[@attr='v']' ) { |el| ... }
                # XPath.each( node, 'ancestor::x' ) { |el| ... }
+ # XPath.each( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"}) \
+ # {|el| ... }
                def XPath::each element, path=nil, namespaces=nil, variables={}, &block
       raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
       raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

may want to send that to ruby-core :slight_smile: -R

Could somebody else do that for me? (Maybe Matz will notice the patch
here.) I can't seem to get an email through to ruby-core or ruby-doc for
reasons that are completely beyond me.

--Ken

···

On Tue, 29 Apr 2008 12:11:10 -0500, Roger Pack wrote:

On Tue, Apr 29, 2008 at 8:15 AM, Ken Bloom <kbloom@gmail.com> wrote:

Here's a patch to rexml/xpath.rb which documents the variables
parameter
in REXML::XPath.

--- xpath.rb.old 2008-04-24 17:31:51.000000000 -0500 +++
xpath.rb 2008-04-24 17:37:38.000000000 -0500 @@ -15,10 +15,15 @@
                # node matching '*'.
                # namespaces::
                # If supplied, a Hash which defines a namespace
                mapping.
+ # variables::
+ # If supplied, a Hash which maps $variables in
the query + # to values. This can be used to avoid
XPath injection attacks + # or to automatically
handle escaping string values.
                #
                # XPath.first( node )
                # XPath.first( doc, "//b"} )
                # XPath.first( node, "a/x:b", { "x"=>"http://doofus" }
                )
+ # XPath.first( node,
'/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"})
     def XPath::first element, path=nil, namespaces=nil, variables={}
       raise "The namespaces argument, if supplied, must be a hash
       object." unless namespaces.nil? or namespaces.kind_of?(Hash)
       raise "The variables argument, if supplied, must be a hash
       object." unless variables.kind_of?(Hash)
@@ -38,10 +43,16 @@
                # The xpath to search for. If not supplied or nil,
                defaults to '*' # namespaces::
                # If supplied, a Hash which defines a namespace
                mapping
+ # variables::
+ # If supplied, a Hash which maps $variables in
the query + # to values. This can be used to avoid
XPath injection attacks + # or to automatically
handle escaping string values.
                #
                # XPath.each( node ) { |el| ... }
                # XPath.each( node, '/*[@attr='v']' ) { |el| ... } #
                XPath.each( node, 'ancestor::x' ) { |el| ... }
+ # XPath.each( node,
'/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"}) \
+ # {|el| ... }
                def XPath::each element, path=nil, namespaces=nil,
                variables={}, &block
       raise "The namespaces argument, if supplied, must be a hash
       object." unless namespaces.nil? or namespaces.kind_of?(Hash)
       raise "The variables argument, if supplied, must be a hash
       object." unless variables.kind_of?(Hash)

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

Ken Bloom wrote:

may want to send that to ruby-core :slight_smile: -R

Could somebody else do that for me? (Maybe Matz will notice the patch
here.) I can't seem to get an email through to ruby-core or ruby-doc for
reasons that are completely beyond me.

Try to subscribe with @googlemail.com, instead of @gmail.com.

That fixes this sort of issue for me, usually.

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan
Blog: http://justarubyist.blogspot.com

~ "Mom and dad say I should make my life an example of the principles I
~ believe in. But every time I do, they tell me to stop it."
~ --- Calvin

···

On Tue, 29 Apr 2008 12:11:10 -0500, Roger Pack wrote:

Ok. I didn't know I needed to be subscribed, and gmail ate the bounce
messages.

--Ken

···

On Tue, 29 Apr 2008 22:52:35 -0500, Phillip Gawlowski wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ken Bloom wrote:
> On Tue, 29 Apr 2008 12:11:10 -0500, Roger Pack wrote: |
>> may want to send that to ruby-core :slight_smile: -R |
> Could somebody else do that for me? (Maybe Matz will notice the patch
> here.) I can't seem to get an email through to ruby-core or ruby-doc
for | reasons that are completely beyond me.

Try to subscribe with @googlemail.com, instead of @gmail.com.

That fixes this sort of issue for me, usually.

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

I don't need to be subscribed to post to ruby-talk. I didn't know I
needed to be subscribed to post to ruby-doc or ruby-core. (I also haven't
gotten any bounce telling me that.)

--Ken

···

On Tue, 29 Apr 2008 22:52:35 -0500, Phillip Gawlowski wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ken Bloom wrote:
> On Tue, 29 Apr 2008 12:11:10 -0500, Roger Pack wrote: |
>> may want to send that to ruby-core :slight_smile: -R |
> Could somebody else do that for me? (Maybe Matz will notice the patch
> here.) I can't seem to get an email through to ruby-core or ruby-doc
for | reasons that are completely beyond me.

Try to subscribe with @googlemail.com, instead of @gmail.com.

That fixes this sort of issue for me, usually.

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/