What's new
SNBForums

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Security Question about using eval inside script

FreshJR

Very Senior Member
I know this question isn't really 100% Merlin-WRT related but I will be using the eval command within my QoS script in an attempt to pass parameters "ByReference" to a function. The answers I get will affect Merlin-WRT in a round-about way.

I already looked this up on stack-exchange exchange and got both answers that eval is the devil and also a proposed solution that should be safe.
I am not 100% sure if it is safe so I would like to ask here first.

Here is a simple easy to read shell example.

Code:
byref()
{
    echo -n "$1=" && eval "echo \${$1}"
    input="bar"                          # this can be any user input
    eval "$1=\$input"        
 
}


var="foo"
byref var
echo "var=${var}"

########OUTPUT########
var=foo
var=bar

The code works as expected. Just worried about security.

not worried about first eval since $1 is explicitly/controlled passed from the "main" function

am worried about second eval due potential to arbitrary command execution user input to escaping quotes​

I tried privilege escalation by escaping the quotes via the following input

Code:
 input='bar" && eval "echo here'

and it didn't escalate like I thought it would.

Is the stackexchange answer safe?
(I do have a messy alternative to eval via 48 almost duplicate functions instead a few byreference equivalents.)
 
Last edited:
Is this actually a security question? Whoever is inputting the potentially dangerous data already has full access to do anything on the router.

Or is it about protecting the user from themselves when they enter incorrect data that may accidentally parse as a valid command?
 
Is this actually a security question? Whoever is inputting the potentially dangerous data already has full access to do anything on the router.

Or is it about protecting the user from themselves when they enter incorrect data that may accidentally parse as a valid command?

I didn't look at it that way. I guess the user already has full privileges inside the shell session so I shouldn't be worried about arbitrary commands..

If the user manages to enter "rm -rf /" as a port rule ..... then it really is their fault for wiping their data.

I was just paranoid since everywhere i read it was recommended to avoid eval when possible, even though it makes everything a lot easier!

But yes it was a serious question. Especially I saw some user venting at some dev for corrupting their flash drive and threating legal action. (FFS this is all free. Community members/devs here spend a lot of time for the things provide.) Thanks again Colin.
 
Last edited:
If the user manages to enter "rm -rf /" as a port rule ..... then it really is their fault for wiping their data
Agreed, but ping me if it ever happens and the user complains. I like a good story.
 
I didn't look at it that way. I guess the user already has full privileges inside the shell session so I shouldn't be worried about arbitrary commands..

If the user manages to enter "rm -rf /" as a port rule ..... then it really is their fault for wiping their data.

I was just paranoid since everywhere i read it was recommended to avoid eval when possible, even though it makes everything a lot easier!

But yes it was a serious question. Especially I saw some user venting at some dev for corrupting their flash drive and threating legal action. (FFS this is all free. Community members/devs here spend a lot of time for the things provide.) Thanks again Colin.
I rely heavily on eval in YazFi for some dynamic variable manipulation. No complaints from users doing something daft yet!
 
If there's user input involved, I would suggest sanitizing that input as much as possible before processing it. Making sure it only contains numbers for instance should make it safer.
 
If there's user input involved, I would suggest sanitizing that input as much as possible before processing it. Making sure it only contains numbers for instance should make it safer.

Yep - good example I found on using eval where things can go wrong, and a way to fix it...

Given some untrusted user input:

% input="Trying to hack you; date"

Construct a command to eval:

% cmd=(echo "User gave:" "$input")

Eval it, with seemingly correct quoting:

% eval "$(echo "${cmd[@]}")"
User gave: Trying to hack you
Thu Sep 27 20:41:31 +07 2018


Note you were hacked. date was executed rather than being printed literally.

So to fix that example, create a token function..

Code:
function token_quote {
  local quoted=()
  for token; do
   quoted+=( "$(printf '%q' "$token")" )
  done
  printf '%s\n' "${quoted[*]}"
}

So with token_quote()

% eval "$(token_quote "${cmd[@]}")"
User gave: Trying to hack you; date
%
 
am worried about second eval due potential to arbitrary command execution user input to escaping quotes
AFAICT you're OK in this case because you have escaped the $ in front of the variable and it's a simple assignment. So your eval command is
eval foo=$input

If you hadn't escaped the $ then the shell would have expanded the string into
eval foo=some string of characters

Code:
# set -x

# input="abcde; yyy=xyz; date; echo hello"
+ input=abcde; yyy=xyz; date; echo hello

# xxx="foo"
+ xxx=foo

# eval "$xxx=\$input"
+ eval foo=$input
+ foo=abcde; yyy=xyz; date; echo hello

# eval "$xxx=$input"
+ eval foo=abcde; yyy=xyz; date; echo hello
+ foo=abcde
+ yyy=xyz
+ date
Wed Feb  6 17:20:12 GMT 2019
+ echo hello
hello
 
Last edited:
AFAICT you're OK in this case because you have escaped the $ in front of the variable and it's a simple assignment. So your eval command is
eval foo=$input

If you hadn't escaped the $ then the shell would have expanded the string into
eval foo=some string of characters

This explanation was so simple. On stackexchange they escaped the "$" but didn't explain the magic behind it! That's why I was still skeptical of using it.

Code:
hacked:        input="Trying to hack you; date" ; eval "echo $input"
safe:          input="Trying to hack you; date" ; eval "echo \$input"
 
This explanation was so simple. On stackexchange they escaped the "$" but didn't explain the magic behind it! That's why I was still skeptical of using it.

Hehe - eval isn't evil - but it knows satan on a first name basis - it just is, a good tool, and tools can do both good and bad.

ash (busybox) has some odd behaviors from bash, but I assume you know this since you're writing scripts - just be aware of bash as entware can pull that in and there, you might get some unexpected results.
 
ash (busybox) has some odd behaviors from bash, but I assume you know this since you're writing scripts - just be aware of bash as entware can pull that in and there, you might get some unexpected results.
Yes the example you quoted earlier doesn't work in native asuswrt because it uses bash-specific array handling, which isn't supported by ash.
 

Similar threads

Latest threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Back
Top