2

I need to accept job files from users, which would essentially consist of console interaction with a process I will be running for them. Naturally, the first idea that came to mind is to use expect scripts as job files:

spawn process
expect "ready"
send "process DATA"
set timeout 100
expect {
    "done" {send_user "success"}
    timeout {send_user "failure"}
}

However, since I'd like to accept jobs automatically, I want to prevent users from doing something stupid or dangerous, like spawning 10 sysbench processes, or writing random files to the disk, or trying to read /etc/passwd. I want to restrict them to STDIN/STDOUT interactions with the process I spawn for them.

How would I go about this? So far my thoughts are:

  • write my own "expect lite". Sounds feasible but silly and time-consuming.
  • sanitize expect job files. Sounds complex and error-prone.
  • invent my own safe language and translate it to expect. Feasible, but I'll have to provide documentation and tutorials so users can learn it.
  • restrict job process with quota and permissions. Not really an option, since I want my process to use a fair amount of CPU time and create tmp files (which I'm confident it will clean up).
  • give users interactive access to process. Not an option since jobs may have to sit in a queue for some time.

Is there something obvious I'm missing, like expect configuration parameter which restricts the scripts, or a similar tool I could use instead?

  • Expect is a general-purpose programming language (it's TCL plus a library). I think you'll need to use an OS-level restricted environment — dedicated user, permissions, SELinux, etc. – Gilles 'SO- stop being evil' Jan 12 '17 at 13:55
  • 1
    The use case is unclear to me. Do you just need to do some validation on the contents of process DATA? – glenn jackman Jan 12 '17 at 18:39
  • @glennjackman No, I need to make sure users only submit data via send, and don't use other features expect has to offer. – Dmitry Grigoryev Jan 13 '17 at 7:44
  • Who writes the expect scripts? – glenn jackman Jan 13 '17 at 11:39
  • 1
    Read about Tcl "safe interpreters" . You'll be able to remove exec and other commands, and run untrusted code with fewer worries – glenn jackman Jan 13 '17 at 13:44
1

TCL safe interpreters do work with expect. To illustrate, I have created two scripts: unsafe.exp representing user-submitted file and safe.exp, which uses a safe interpreter to run unsafe.exp. Here's the code of unsafe.exp:

#!/usr/bin/expect
spawn whoami
expect {
    "user" { send_user "safe success\n" }
    "root" { send_user "unsafe success\n" }
}

Running unsafe.exp as root results in

# expect unsafe.exp
spawn whoami
root
unsafe success

Now, safe.exp will prevent the user from using dangerous commands like spawn, while still providing access to essential features like send and expect. Here's the code:

#!/usr/bin/expect

# create a safe interpreter
interp create -safe untrusted

# provide it with essetial expect functions
interp alias untrusted send_user {} send_user
interp alias untrusted send {} send
interp alias untrusted expect {} expect
interp alias untrusted interact {} interact

# censor the "spawn" function
# not providing it would be just as safe, but scripts using it would fail
proc safe_spawn {args} {
    puts "censored spawn"
}
interp alias untrusted spawn {} safe_spawn

# create a safe process to interact with
spawn sudo -u user whoami

# run unsafe.exp
untrusted invokehidden source unsafe.exp

Running safe.exp as root results in

# expect safe.exp
spawn sudo -u user whoami
censored spawn
user
safe success

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.