mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
Issue #16400: Add command line option for isolated mode.
-I Run Python in isolated mode. This also implies -E and -s. In isolated mode sys.path contains neither the script’s directory nor the user’s site-packages directory. All PYTHON* environment variables are ignored, too. Further restrictions may be imposed to prevent the user from injecting malicious code.
This commit is contained in:
parent
562d9cbfe9
commit
ad73a9cf97
11 changed files with 77 additions and 10 deletions
|
@ -329,7 +329,11 @@ Process-wide parameters
|
||||||
|
|
||||||
.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv)
|
.. c:function:: void PySys_SetArgv(int argc, wchar_t **argv)
|
||||||
|
|
||||||
This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set to 1.
|
This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set
|
||||||
|
to 1 unless the :program:`python` interpreter was started with the
|
||||||
|
:option:`-I`.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`.
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: void Py_SetPythonHome(wchar_t *home)
|
.. c:function:: void Py_SetPythonHome(wchar_t *home)
|
||||||
|
|
|
@ -24,7 +24,7 @@ Command line
|
||||||
|
|
||||||
When invoking Python, you may specify any of these options::
|
When invoking Python, you may specify any of these options::
|
||||||
|
|
||||||
python [-bBdEhiOqsSuvVWx?] [-c command | -m module-name | script | - ] [args]
|
python [-bBdEhiIOqsSuvVWx?] [-c command | -m module-name | script | - ] [args]
|
||||||
|
|
||||||
The most common use case is, of course, a simple invocation of a script::
|
The most common use case is, of course, a simple invocation of a script::
|
||||||
|
|
||||||
|
@ -175,6 +175,8 @@ Generic options
|
||||||
Python 3.0
|
Python 3.0
|
||||||
|
|
||||||
|
|
||||||
|
.. _using-on-misc-options:
|
||||||
|
|
||||||
Miscellaneous options
|
Miscellaneous options
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -213,6 +215,17 @@ Miscellaneous options
|
||||||
raises an exception. See also :envvar:`PYTHONINSPECT`.
|
raises an exception. See also :envvar:`PYTHONINSPECT`.
|
||||||
|
|
||||||
|
|
||||||
|
.. cmdoption:: -I
|
||||||
|
|
||||||
|
Run Python in isolated mode. This also implies -E and -s.
|
||||||
|
In isolated mode :data:`sys.path` contains neither the script's directory nor
|
||||||
|
the user's site-packages directory. All :envvar:`PYTHON*` environment
|
||||||
|
variables are ignored, too. Further restrictions may be imposed to prevent
|
||||||
|
the user from injecting malicious code.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
|
||||||
.. cmdoption:: -O
|
.. cmdoption:: -O
|
||||||
|
|
||||||
Turn on basic optimizations. This changes the filename extension for
|
Turn on basic optimizations. This changes the filename extension for
|
||||||
|
@ -398,7 +411,7 @@ Environment variables
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
These environment variables influence Python's behavior, they are processed
|
These environment variables influence Python's behavior, they are processed
|
||||||
before the command-line switches other than -E. It is customary that
|
before the command-line switches other than -E or -I. It is customary that
|
||||||
command-line switches override environmental variables where there is a
|
command-line switches override environmental variables where there is a
|
||||||
conflict.
|
conflict.
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,8 @@ Significantly Improved Library Modules:
|
||||||
|
|
||||||
Security improvements:
|
Security improvements:
|
||||||
|
|
||||||
* None yet.
|
* command line option for :ref:`isolated mode <using-on-misc-options>`,
|
||||||
|
:issue:`16499`.
|
||||||
|
|
||||||
Please read on for a comprehensive list of user-facing changes.
|
Please read on for a comprehensive list of user-facing changes.
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ PyAPI_DATA(int) Py_DontWriteBytecodeFlag;
|
||||||
PyAPI_DATA(int) Py_NoUserSiteDirectory;
|
PyAPI_DATA(int) Py_NoUserSiteDirectory;
|
||||||
PyAPI_DATA(int) Py_UnbufferedStdioFlag;
|
PyAPI_DATA(int) Py_UnbufferedStdioFlag;
|
||||||
PyAPI_DATA(int) Py_HashRandomizationFlag;
|
PyAPI_DATA(int) Py_HashRandomizationFlag;
|
||||||
|
PyAPI_DATA(int) Py_IsolatedFlag;
|
||||||
|
|
||||||
/* this is a wrapper around getenv() that pays attention to
|
/* this is a wrapper around getenv() that pays attention to
|
||||||
Py_IgnoreEnvironmentFlag. It should be used for getting variables like
|
Py_IgnoreEnvironmentFlag. It should be used for getting variables like
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import test.support, unittest
|
import test.support, unittest
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -439,6 +440,31 @@ class CmdLineTest(unittest.TestCase):
|
||||||
self.assertEqual(b'', out)
|
self.assertEqual(b'', out)
|
||||||
|
|
||||||
|
|
||||||
|
def test_isolatedmode(self):
|
||||||
|
self.verify_valid_flag('-I')
|
||||||
|
self.verify_valid_flag('-IEs')
|
||||||
|
rc, out, err = assert_python_ok('-I', '-c',
|
||||||
|
'from sys import flags as f; '
|
||||||
|
'print(f.no_user_site, f.ignore_environment, f.isolated)',
|
||||||
|
# dummyvar to prevent extranous -E
|
||||||
|
dummyvar="")
|
||||||
|
self.assertEqual(out.strip(), b'1 1 1')
|
||||||
|
with test.support.temp_cwd() as tmpdir:
|
||||||
|
fake = os.path.join(tmpdir, "uuid.py")
|
||||||
|
main = os.path.join(tmpdir, "main.py")
|
||||||
|
with open(fake, "w") as f:
|
||||||
|
f.write("raise RuntimeError('isolated mode test')\n")
|
||||||
|
with open(main, "w") as f:
|
||||||
|
f.write("import uuid\n")
|
||||||
|
f.write("print('ok')\n")
|
||||||
|
self.assertRaises(subprocess.CalledProcessError,
|
||||||
|
subprocess.check_output,
|
||||||
|
[sys.executable, main], cwd=tmpdir,
|
||||||
|
stderr=subprocess.DEVNULL)
|
||||||
|
out = subprocess.check_output([sys.executable, "-I", main],
|
||||||
|
cwd=tmpdir)
|
||||||
|
self.assertEqual(out.strip(), b"ok")
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test.support.run_unittest(CmdLineTest)
|
test.support.run_unittest(CmdLineTest)
|
||||||
test.support.reap_children()
|
test.support.reap_children()
|
||||||
|
|
|
@ -515,7 +515,7 @@ class SysModuleTest(unittest.TestCase):
|
||||||
attrs = ("debug",
|
attrs = ("debug",
|
||||||
"inspect", "interactive", "optimize", "dont_write_bytecode",
|
"inspect", "interactive", "optimize", "dont_write_bytecode",
|
||||||
"no_user_site", "no_site", "ignore_environment", "verbose",
|
"no_user_site", "no_site", "ignore_environment", "verbose",
|
||||||
"bytes_warning", "quiet", "hash_randomization")
|
"bytes_warning", "quiet", "hash_randomization", "isolated")
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
self.assertTrue(hasattr(sys.flags, attr), attr)
|
self.assertTrue(hasattr(sys.flags, attr), attr)
|
||||||
self.assertEqual(type(getattr(sys.flags, attr)), int, attr)
|
self.assertEqual(type(getattr(sys.flags, attr)), int, attr)
|
||||||
|
|
|
@ -10,6 +10,8 @@ Projected Release date: 2013-09-08
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #16400: Add command line option for isolated mode.
|
||||||
|
|
||||||
- Issue #15301: Parsing fd, uid, and gid parameters for builtins
|
- Issue #15301: Parsing fd, uid, and gid parameters for builtins
|
||||||
in Modules/posixmodule.c is now far more robust.
|
in Modules/posixmodule.c is now far more robust.
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,14 @@ python \- an interpreted, interactive, object-oriented programming language
|
||||||
.B \-i
|
.B \-i
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
.B \-m
|
.B \-I
|
||||||
.I module-name
|
|
||||||
]
|
]
|
||||||
.br
|
.br
|
||||||
[
|
[
|
||||||
|
.B \-m
|
||||||
|
.I module-name
|
||||||
|
]
|
||||||
|
[
|
||||||
.B \-q
|
.B \-q
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
|
@ -139,6 +142,13 @@ command. It does not read the $PYTHONSTARTUP file. This can be
|
||||||
useful to inspect global variables or a stack trace when a script
|
useful to inspect global variables or a stack trace when a script
|
||||||
raises an exception.
|
raises an exception.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-I
|
||||||
|
Run Python in isolated mode. This also implies \fB\-E\fP and \fB\-S\fP. In
|
||||||
|
isolated mode sys.path contains neither the script’s directory nor the user’s
|
||||||
|
site-packages directory. All PYTHON* environment variables are ignored, too.
|
||||||
|
Further restrictions may be imposed to prevent the user from injecting
|
||||||
|
malicious code.
|
||||||
|
.TP
|
||||||
.BI "\-m " module-name
|
.BI "\-m " module-name
|
||||||
Searches
|
Searches
|
||||||
.I sys.path
|
.I sys.path
|
||||||
|
|
|
@ -43,7 +43,7 @@ static wchar_t **orig_argv;
|
||||||
static int orig_argc;
|
static int orig_argc;
|
||||||
|
|
||||||
/* command line options */
|
/* command line options */
|
||||||
#define BASE_OPTS L"bBc:dEhiJm:OqRsStuvVW:xX:?"
|
#define BASE_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?"
|
||||||
|
|
||||||
#define PROGRAM_OPTS BASE_OPTS
|
#define PROGRAM_OPTS BASE_OPTS
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ Options and arguments (and corresponding environment variables):\n\
|
||||||
static char *usage_2 = "\
|
static char *usage_2 = "\
|
||||||
-i : inspect interactively after running script; forces a prompt even\n\
|
-i : inspect interactively after running script; forces a prompt even\n\
|
||||||
if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
|
if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
|
||||||
|
-I : isolate Python from the user's environment (implies -E and -s)\n\
|
||||||
-m mod : run library module as a script (terminates option list)\n\
|
-m mod : run library module as a script (terminates option list)\n\
|
||||||
-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\
|
-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\
|
||||||
-OO : remove doc-strings in addition to the -O optimizations\n\
|
-OO : remove doc-strings in addition to the -O optimizations\n\
|
||||||
|
@ -426,6 +427,12 @@ Py_Main(int argc, wchar_t **argv)
|
||||||
Py_InteractiveFlag++;
|
Py_InteractiveFlag++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'I':
|
||||||
|
Py_IsolatedFlag++;
|
||||||
|
Py_NoUserSiteDirectory++;
|
||||||
|
Py_IgnoreEnvironmentFlag++;
|
||||||
|
break;
|
||||||
|
|
||||||
/* case 'J': reserved for Jython */
|
/* case 'J': reserved for Jython */
|
||||||
|
|
||||||
case 'O':
|
case 'O':
|
||||||
|
|
|
@ -112,6 +112,7 @@ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
|
||||||
int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
|
int Py_NoUserSiteDirectory = 0; /* for -s and site.py */
|
||||||
int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
|
int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */
|
||||||
int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
|
int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */
|
||||||
|
int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */
|
||||||
|
|
||||||
PyThreadState *_Py_Finalizing = NULL;
|
PyThreadState *_Py_Finalizing = NULL;
|
||||||
|
|
||||||
|
|
|
@ -1369,6 +1369,7 @@ static PyStructSequence_Field flags_fields[] = {
|
||||||
{"bytes_warning", "-b"},
|
{"bytes_warning", "-b"},
|
||||||
{"quiet", "-q"},
|
{"quiet", "-q"},
|
||||||
{"hash_randomization", "-R"},
|
{"hash_randomization", "-R"},
|
||||||
|
{"isolated", "-I"},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1376,7 +1377,7 @@ static PyStructSequence_Desc flags_desc = {
|
||||||
"sys.flags", /* name */
|
"sys.flags", /* name */
|
||||||
flags__doc__, /* doc */
|
flags__doc__, /* doc */
|
||||||
flags_fields, /* fields */
|
flags_fields, /* fields */
|
||||||
12
|
13
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
|
@ -1406,6 +1407,7 @@ make_flags(void)
|
||||||
SetFlag(Py_BytesWarningFlag);
|
SetFlag(Py_BytesWarningFlag);
|
||||||
SetFlag(Py_QuietFlag);
|
SetFlag(Py_QuietFlag);
|
||||||
SetFlag(Py_HashRandomizationFlag);
|
SetFlag(Py_HashRandomizationFlag);
|
||||||
|
SetFlag(Py_IsolatedFlag);
|
||||||
#undef SetFlag
|
#undef SetFlag
|
||||||
|
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
|
@ -1944,7 +1946,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
|
||||||
void
|
void
|
||||||
PySys_SetArgv(int argc, wchar_t **argv)
|
PySys_SetArgv(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
PySys_SetArgvEx(argc, argv, 1);
|
PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reimplementation of PyFile_WriteString() no calling indirectly
|
/* Reimplementation of PyFile_WriteString() no calling indirectly
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue