Skip to content

remove not decodable environment variables #48376

Closed

Description

@vstinner
BPO 4126
Nosy @loewis, @vstinner, @abadger
Files
  • unsetenv-2.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2009-05-17.04:36:43.662>
    created_at = <Date 2008-10-15.00:45:24.075>
    labels = ['type-security', 'interpreter-core']
    title = 'remove not decodable environment variables'
    updated_at = <Date 2009-05-17.04:36:43.326>
    user = 'https://github.com/vstinner'

    bugs.python.org fields:

    activity = <Date 2009-05-17.04:36:43.326>
    actor = 'loewis'
    assignee = 'none'
    closed = True
    closed_date = <Date 2009-05-17.04:36:43.662>
    closer = 'loewis'
    components = ['Interpreter Core']
    creation = <Date 2008-10-15.00:45:24.075>
    creator = 'vstinner'
    dependencies = []
    files = ['11800']
    hgrepos = []
    issue_num = 4126
    keywords = ['patch']
    message_count = 8.0
    messages = ['74784', '74785', '74786', '74788', '74789', '74796', '74805', '87957']
    nosy_count = 3.0
    nosy_names = ['loewis', 'vstinner', 'a.badger']
    pr_nums = []
    priority = 'high'
    resolution = 'out of date'
    stage = None
    status = 'closed'
    superseder = None
    type = 'security'
    url = 'https://bugs.python.org/issue4126'
    versions = ['Python 3.1']

    Activity

    1. vstinner commented on Oct 15, 2008

      @vstinner
      MemberAuthor

      Python3 skips environment variables which can not be parsed and
      decoded as unicode strings. But exec*() functions keep the original
      environment and so the child process environment is different than the
      Python environement (than os.environ).

      I propose to remove these variables to avoid strange behaviours, but
      also to avoid possible security issues.

      The attached patch is an implementation of this idea using a custom
      implementation of unsetenv(): _Py_unsetenv() argument is not the name
      of the variable but the raw variable including the value (eg. "a=b").
      So it's also possible to drop truncated variables like "a" (no value
      nor "=" character).

      This issue also affects Python2 since Python2 does also skip variable
      with no value but the variables still exist in memory (and so child
      process get them).

    2. vstinner commented on Oct 15, 2008

      @vstinner
      MemberAuthor

      Note: I don't have Windows at home to test my patch on Windows. At
      least, the patch works correctly on Ubuntu Gutsy/i386.

      Example to demonstrate the issue:
      $ env -i a=a b=$(echo -e '--\xff--') c=c ./python -c "import os;
      os.execvp('/usr/bin/env', ['/usr/bin/env'])"
      a=a
      b=--�--
      c=c

      Patched Python:
      $ env -i a=a b=$(echo -e '--\xff--') c=c ./python -c "import os;
      os.execvp('/usr/bin/env', ['/usr/bin/env'])"
      a=a
      c=c

      I tested Python 2.5: b is also removed, but Python 2.6 keeps the
      variable b.

    3. vstinner commented on Oct 15, 2008

      @vstinner
      MemberAuthor

      while+strcmp() in _Py_unsetenv() is useless since we already get the
      pointer to the evil variable. The new patch is shorter.

    4. vstinner commented on Oct 15, 2008

      @vstinner
      MemberAuthor

      See also issue bpo-4006 which asks the opposite (keep invalid variables,
      even in os.environ(b)) :-)

    5. abadger commented on Oct 15, 2008

      abadgermannequin
      Mannequin

      Yep :-) I am against throwing away valid data just because we can't
      interpret it automatically. Environment variables in Unix hold bytes.
      Those bytes are usually ASCii characters, however, they do not have to
      be. This is a case of being on the border between python and the
      outside world so we need to be able to pass in bytes if the user
      requests it.

      Let's say that you have a local directory of: /home/\xff/username/bin in
      your PATH environment variable and a command named my_app.sh in there.
      At the shell you can happily run myapp.sh and it will do it's thing.
      Now you open your python shell and do:
      subprocess.call(['myapp.sh'])

      and it doesn't work. This is non-intuitive behaviour for people who are
      used to how the shell works. All this patch will do is take away the
      work around of subprocess.call(['bash', 'myapp.sh'])

      """
      I tested Python 2.5: b is also removed, but Python 2.6 keeps the
      variable b.
      """
      I just tested python-2.5.1 and b is kept, not removed.

    6. vstinner commented on Oct 15, 2008

      @vstinner
      MemberAuthor

      About your subprocess example: we choose to refuse it because we don't
      mix bytes (your non decodable PATH) and unicode ('myapp.sh'). Using my
      patch in issue bpo-4036 you will be able to run program with bytes
      arguments (including the program name), but there is no way (yet?) in
      Python3 to read the raw (bytes) environment variable PATH.

      About Python2, I retested and all versions (2.5.2 and trunk (2.7a0))
      keep the variables. But Python2 doesn't convert value to unicode and
      so it's not right example. Python2 skips variable with no "="
      character, but I don't know how to reproduce this example (maybe using
      a C program using execve).

    7. abadger commented on Oct 15, 2008

      abadgermannequin
      Mannequin

      """
      About your subprocess example: we choose to refuse it because we don't
      mix bytes (your non decodable PATH) and unicode ('myapp.sh')
      """
      If python3 is doing things right we shouldn't be mixing bytes and
      unicode here:

      1. the programmer is only sending unicode to subprocess, not a mixture
        of bytes and unicode.

      2. Python should be converting the arguments to subprocess.call() into
        bytes before combining it with PATH, at least on Unix. The conversion
        to bytes is something Python has to do at some point before looking on
        the filesystem for the command as filenames are a sequence of bytes in Unix.

      Note: your patch for bpo-4036 looks like the right thing to do for the args
      argument but as you point out, that doesn't have bearing on the environment.

    8. loewis commented on May 17, 2009

      loewismannequin
      Mannequin

      This patch is out of date with PEP-383

    9. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      interpreter-core(Objects, Python, Grammar, and Parser dirs)type-securityA security issue

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions