Skip to content

Python probelms with environment variables

ebranca edited this page Jun 15, 2014 · 1 revision

Classification

  • Affected Components : builtin, os

  • Operating System : Linux

  • Python Versions : 2.6.x, 2.7.x, 3.1.x, 3.2.x

  • Reproducible : Yes

Source code

import os
os.environ['a=b'] = 'c'
try:
    os.environ.clear()
    print("PASS => os.environ.clear removed variable 'a=b'")
except:
    print("FAIL => os.environ.clear removed variable 'a=b'")
    raise

Steps to Produce/Reproduce

To reproduce the problem copy the source code in a file and execute the script using the following command syntax:

$ python -OOBRtt test.py

Alternatively you can open python in interactive mode:

$ python -OOBRtt <press enter>

Then copy the lines of code into the interpreter.

Description

Each operating system supports a specific set of characters and supported names vary greatly depending on platform type and platform version.

Names and syntax of environment variables names are also based on the specific rules used in each platform but python does not share the same logic and tried to implement a generic interface compatible with most operating systems.

This choice of preferring compatibility over security have allowed the existence of cracks in the logic used to work environment variables.

General rule of thumb would be to have a list of of rules for each system and comply with it, but currently this list does not exists and python exposes same function call for all systems.

In the tested python version have been possible to set variable names non conforming with UNIX or POSIX standards, and in many case was also possible to set the variable but was impossible to remove it as the commands was generating errors in the interpreter's core libraries.

Extract of Linux manual pages for command [setenv][01]:

BUGS POSIX.1-2001 specifies that if name contains an '=' character, then setenv() should fail with the error EINVAL; however, versions of glibc before 2.3.4 allowed an '=' sign in name.

Extract of Linux manual pages for command [clearenv][02]:

CONFORMING TO Various Unix variants (DG/UX, HP-UX, QNX, ...). POSIX.9 (bindings for FORTRAN77). POSIX.1-1996 did not accept clearenv() and putenv(), but changed its mind and scheduled these functions for some later issue of this standard (cf. B.4.6.1). However, POSIX.1-2001 only adds putenv(), and rejected clearenv().

It looks possible to define an environment variable with an empty key but not to remove it:

$ env -i =value python -c 'import pprint, os; pprint.pprint(os.environ); del os.environ[""]'
environ({'': 'value'})
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "Lib/os.py", line 662, in __delitem__
    self.unsetenv(encodedkey)
OSError: [Errno 22] Invalid argument

It also looks possible to define an environment variable with a '=' character but not to remove it:

$ env -i python -c 'import pprint, posix, os; os.environ["a="]="1"; print(os.environ); posix.unsetenv("a=")'

The last call posix.unsetenv("a=") generates:

environ({'a=': '1'})
Traceback (most recent call last):
  File "<string>", line 1, in <module>
OSError: [Errno 22] Invalid argument

And also python behaviour changes depends on which version is used, as can be seen when the sample source code is executed.

  • PYTHON 2.6 --> NO ERROR!!
  • PYTHON 2.7 --> OSError: [Errno 22] Invalid argument
  • PYTHON 3.1 --> NO ERROR !!
Result when executed under PYTHON 2.6
PASS => os.environ.clear removed variable 'a=b'

Result --> NO ERROR !!
Result when executed under PYTHON 2.7
FAIL => os.environ.clear removed variable 'a=b'

Traceback (most recent call last):
  File "test.py", line 6, in <module>
    os.environ.clear()
  File "/usr/lib/python2.7/os.py", line 499, in clear
    unsetenv(key)
OSError: [Errno 22] Invalid argument

Result: ***```OSError: [Errno 22] Invalid argument```***
Result when executed under PYTHON 3.1
PASS => os.environ.clear removed variable 'a=b'

Result --> NO ERROR !!

There should be a mean by which python is able to detect the system and at least prevent the usage of 'key-value' pairs associated to environment variable that are invalid, and should definitely prevent the user from setting empty or invalid.

Workaround

We are not aware on any easy solution to deal with system and environment variable other that writing a full library for this specific purpose.

Secure Implementation

WORK IN PROGRESS

References

[UNIX setenv][01] [01]:http://unixhelp.ed.ac.uk/CGI/man-cgi?unsetenv

[UNIX setenv][02] [02]:http://unixhelp.ed.ac.uk/CGI/man-cgi?clearenv+3

[Python bug 14252][03] [03]:http://bugs.python.org/issue4926

[Python bug 14252][04] [04]:http://bugs.python.org/issue20658

  • Home
  • [Security Concerns](Security Concerns)
Clone this wiki locally