Node.JS Spawn inside an SELinux Sandbox -


i building node.js application involves redirecting user input server-side command. of course, catastrophic security, desire run child command inside selinux sandbox. (i not want run entire application inside of sandbox because want end users each have own workspace on server.)

for example, consider command cowsay. in order run sandboxed cowsay, need sandbox cowsay. other behind-the-scenes security differences, interface of sandbox cowsay should same of plain cowsay.

however, node.js responds differently these 2 approaches. consider code:

var spawn = require('child_process').spawn;                       var cmd = spawn("cowsay", ["hello"]); // line (no sandbox)  var cmd = spawn("sandbox", ["cowsay", "hello"]); // line b (with sandbox) cmd.stdout.on("data", function(data){     console.log("stdout: "+data); }); cmd.stderr.on("data", function(data){     console.log("stderr: "+data); }); cmd.on("exit", function(err){     console.log("exit: "+err); }); 

here output of version line a:

$ node run.js stdout:  _______  < hello >  -------          \   ^__^          \  (oo)\_______             (__)\       )\/\                 ||----w |                 ||     ||  exit: 0 

but here output of version line b instead:

$ node run.js exit: 0 

in other words, node.js not seem read streams sandbox's child process.

this test can performed using command. example, suppose used python command interpreter. happens here non-sandboxed python waits fed stdin node.js, sandboxed python exists code 0, without waiting.

this behavior exhibited when selinux in "enforcing" mode. sandbox version works fine when selinux in "permissive" (non-enforcing) mode.

what needs happen in order node.js treat sandboxed command same non-sandboxed command?

after playing around couple more weeks, found way make sandbox work expected.

the issue seems involve selinux stopping libuv (the underpinnings of node) reading , writing unix stream socket, of course required node's non-blocking i/o. 1 reason took long find error being hidden selinux's audit dontaudit rules.

we started doing following:

# semodule -db  ## turns off dontaudit rules # tail -f /var/log/audit/audit.log 

then in different terminal, run application. bunch of selinux audits appear, significantly, 1 says:

type=avc msg=audit(1370065734.791:5038): avc:  denied  { read write }  pid=8887 comm="my_command" path="socket:[1258916]" dev=sockfs ino=1258916 scontext=unconfined_u:unconfined_r:sandbox_t:s0:c98,c807 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket 

to make policy, did following:

# grep "type=avc msg=audit(1370065734.791:5038)" /var/log/audit/audit.log  | audit2allow -m unixsocketsandbox # semodule -i unixsocketsandbox.pp 

where unixsocketsandbox unique name policy. policy (via cat unixsocketsandbox.te) reads follows:

allow sandbox_t unconfined_t:unix_stream_socket { read write }; 

after this, application works expected, within limitations of sandbox.


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -