10

I'm trying to trying to run another script via the shell, that uses a modified set of environment variables.

def cgi_call(script, environ):
    pSCRIPT = subprocess.Popen(script, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 
                        stdin=subprocess.PIPE, env=environ, shell=True)

    pc = pSCRIPT.communicate()

    status = "200 OK"
    headers = [('Content-Type',"text/html")]
    if pc[1] != '':
        raise RuntimeError, pc[1]
    else:
        rval = str(pc[0])

    return status, headers, rval

After running the code above, I get the following error:

File "server/httpd.py", line 76, in DynamicServer
    status, headers, rval = handler(environ)
File "server/httpd.py", line 43, in handler
    status, headers, rval = cgi_call(srvpath+"../www/public_html"+environ["PATH_INFO"]+'index.py',environ)
File "server/httpd.py", line 21, in cgi_call
    stdin=subprocess.PIPE, env=environ, shell=True)
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
<type 'exceptions.TypeError'> execve() arg 3 contains a non-string value

The error comes when passing the environment variables... I've also tried passing them as a string - It errors out and says that it needs a mapping object. However, as it is, the environ being passed IS a mapping object...

What is the problem?

Additional Information: I am running Python 2.7 on Ubuntu 12.04.1

Abram I
  • 185
  • 2
  • 7
  • 8
    `execve() arg 3` is the environment. Are you sure the `env` parameter you are passing only contains strings? – Pedro Romano Nov 03 '12 at 21:37
  • Yes, I am positive. That was the first thing I checked. – Abram I Nov 03 '12 at 21:38
  • 10
    I'm not sure, but I believe that at least the keys, and possibly the values also, in Python 2.x need to be byte strings. So if you are using unicode strings, make sure you encode them to `utf-8`. Also, if you are using unicode literals by default via `from __future__ import unicode_literals` make sure your string literals for the dictionary keys are prefixed with `b` to be byte literals instead of unicode literals. – Pedro Romano Nov 03 '12 at 21:44
  • I have not tried that, I'll see if that's the issue. – Abram I Nov 03 '12 at 21:45
  • Hey thanks! The help is much appreciated! It runs as expected now! – Abram I Nov 03 '12 at 21:51
  • Did someone abuse that gaping shell injection hole by now, btw? I hope that's not a public site. – jhermann Sep 14 '13 at 00:38
  • @Pedro Romano Could you post the your comment as answer? It would be nice to see the actual response at the proper location. – Rod Sep 23 '13 at 00:17

3 Answers3

8

Copying the answer from the comments in order to remove this question from the "Unanswered" filter:

"...the keys, and possibly the values also, in Python 2.x need to be byte strings. So if you are using unicode strings, make sure you encode them to utf-8. Also, if you are using unicode literals by default via from __future__ import unicode_literals make sure your string literals for the dictionary keys are prefixed with b to be byte literals instead of unicode literals."

~ answer per Pedro Romano

Community
  • 1
  • 1
DreadPirateShawn
  • 8,164
  • 4
  • 49
  • 71
2

I ran into a similar problem. In my case, the problem was because I was just passing python native types in the dictionary I passed to env. This could actually be consistent with what the OP, given the level of information here. Consider the point where

cgi_call(srvpath+"../www/public_html"+environ["PATH_INFO"]+'index.py',environ)

is called. If environ looked like

{"variable": True}

Then the True in there would almost certainly be the cause of the error. You can use the string (bytestring, as per the other answer) "true" in its place.

AlanSE
  • 2,597
  • 2
  • 29
  • 22
2

in my case, the environment variables's value was a number. treating the value as string with quoting was my soluction as the error message, execve() arg 3 contains a non-string value.

from

- env:
  - VARIABLES: 1

to

- env:
  - VARIABLES: "1"
zmag
  • 7,825
  • 12
  • 32
  • 42
John Kang
  • 21
  • 1