The most common case I have seen of people using xdmp:eval() is to evaluate
queries in a new context (transaction, statement, database etc) or to pass a
function-like thing as a parameter or store in a variable or table for later
use.
This can (as of V7) be replaced by using XQuery function items - this
eliminates a big chunk of injection attack problems.
For the case of passing 'code' (or 'lambdas') around simply use an anonymous
function item. They can be used as arguments, put into maps and sequences and
variables and even better they can bind to local variables (lambdas)
E.g. instead of
function callback( $code as xs:string ) as item()*
{
xdmp:eval( $code )
}
let $value := 123
return callback( concat("call-my-function(" , $value ")" ))
use
function callback( $code as function() as item()* )
{
$f()
}
,...
let $value := 123 return
callback( function() { call-my-function( $value ) } )
-------
To call the code in a new context see
xdmp:invoke-function
Or to spawn a function without having to have module lying around see
xdmp:spawn -function
Both take the same options as eval/invoke/spawn
-----------------------------------------------------------------------------
David Lee
Lead Engineer
MarkLogic Corporation
[email protected]
Phone: +1 812-482-5224
Cell: +1 812-630-7622
www.marklogic.com
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Michael Blakeley
Sent: Tuesday, February 24, 2015 9:17 PM
To: MarkLogic Developer Discussion
Subject: Re: [MarkLogic Dev General] What are the best practices for securing a
Public ROXY REST Extension?
The first rule for injection attacks is to avoid evaluating strings as code.
This means avoiding xdmp:eval as well as xdmp:value and xdmp:unpath, although
the latter function is a little less powerful and hence a little less
dangerous. If you do need any eval-like function, use the weakest one that gets
the job done.
If and when some form of dynamic eval becomes necessary, sanitize all its
inputs. This often means writing a regex that matches the sort of thing you
expect the user to send, and forbids anything else. For example if the user
sends an XPath you might forbid colons, because you know that everything should
be in your app's default namespace. If the user is supposed to send an element
localname, make sure it's castable as such. That way it can't be an escaped
function call in disguise. Another trick is to send the user input to a lookup
function, something like map:get. Any nefarious input will fail to find a
match, and anyway you'll only eval your match for the input key.
XQuery doesn't automatically taint user input, so it's up to you to make sure
you don't blindly evaluate any user input. Calling a library function can be
risky: suppose it calls xdmp:eval internally? Try to ensure that all REST
requests run as a user that isn't allowed to call any of the dynamic eval
functions. You could write a negative version of
https://docs.marklogic.com/xdmp:security-assert and call it on every request,
to guard against misconfiguration. For those rare evals that really are
necessary, write an amp'd function that carefully sanitizes its inputs.
Setting up the http server(s) to listen on 127.0.0.1 may be a good idea too. Of
course that means you now need a transparent reverse proxy server to handle
incoming connections, but that's probably a good idea anyway. It won't protect
you against an injection attack, but it raises the level of confidence that
public requests will only be able to access the endpoints you've exposed.
-- Mike
> On 24 Feb 2015, at 14:43 , Gary Russo <[email protected]> wrote:
>
> What are the best practices for securing a ROXY REST Extension that is on the
> public internet?
>
> The REST API will use SSL encryption.
>
> Are there any rules of thumb to prevent Query, Schema, and JavaScript
> Injection attacks?
>
> Mike has this good post about using external variables. =>
> http://blakeley.com/blogofile/2012/09/28/external-variables-(code-review,-part-ii)/
>
> Other NoSQL products, such as Redis, require the ports to be firewalled with
> a loopback interface to restrict external access. =>
> http://redis.io/topics/security#network-security
>
> Is there any value to using the Redis firewall approach?
>
>
>
> Gary Russo
> Enterprise NoSQL Developer
> http://garyrusso.wordpress.com
>
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general