+63
-2
lines changedFilter options
+63
-2
lines changed Original file line number Diff line number Diff line change
@@ -385,6 +385,46 @@ def test_env(self):
385
385
self.addCleanup(p.stdout.close)
386
386
self.assertEqual(p.stdout.read(), "orange")
387
387
388
+
def test_invalid_cmd(self):
389
+
# null character in the command name
390
+
cmd = sys.executable + '\0'
391
+
with self.assertRaises(TypeError):
392
+
subprocess.Popen([cmd, "-c", "pass"])
393
+
394
+
# null character in the command argument
395
+
with self.assertRaises(TypeError):
396
+
subprocess.Popen([sys.executable, "-c", "pass#\0"])
397
+
398
+
def test_invalid_env(self):
399
+
# null character in the enviroment variable name
400
+
newenv = os.environ.copy()
401
+
newenv["FRUIT\0VEGETABLE"] = "cabbage"
402
+
with self.assertRaises(TypeError):
403
+
subprocess.Popen([sys.executable, "-c", "pass"], env=newenv)
404
+
405
+
# null character in the enviroment variable value
406
+
newenv = os.environ.copy()
407
+
newenv["FRUIT"] = "orange\0VEGETABLE=cabbage"
408
+
with self.assertRaises(TypeError):
409
+
subprocess.Popen([sys.executable, "-c", "pass"], env=newenv)
410
+
411
+
# equal character in the enviroment variable name
412
+
newenv = os.environ.copy()
413
+
newenv["FRUIT=ORANGE"] = "lemon"
414
+
with self.assertRaises(ValueError):
415
+
subprocess.Popen([sys.executable, "-c", "pass"], env=newenv)
416
+
417
+
# equal character in the enviroment variable value
418
+
newenv = os.environ.copy()
419
+
newenv["FRUIT"] = "orange=lemon"
420
+
p = subprocess.Popen([sys.executable, "-c",
421
+
'import sys, os;'
422
+
'sys.stdout.write(os.getenv("FRUIT"))'],
423
+
stdout=subprocess.PIPE,
424
+
env=newenv)
425
+
stdout, stderr = p.communicate()
426
+
self.assertEqual(stdout, "orange=lemon")
427
+
388
428
def test_communicate_stdin(self):
389
429
p = subprocess.Popen([sys.executable, "-c",
390
430
'import sys;'
Original file line number Diff line number Diff line change
@@ -52,6 +52,9 @@ Extension Modules
52
52
Library
53
53
-------
54
54
55
+
- [Security] bpo-30730: Prevent environment variables injection in subprocess on
56
+
Windows. Prevent passing other environment variables and command arguments.
57
+
55
58
- [Security] bpo-30694: Upgrade expat copy from 2.2.0 to 2.2.1 to get fixes
56
59
of multiple security vulnerabilities including: CVE-2017-9233 (External
57
60
entity infinite loop DoS), CVE-2016-9063 (Integer overflow, re-fix),
Original file line number Diff line number Diff line change
@@ -3315,6 +3315,12 @@ posix_execve(PyObject *self, PyObject *args)
3315
3315
{
3316
3316
goto fail_2;
3317
3317
}
3318
+
/* Search from index 1 because on Windows starting '=' is allowed for
3319
+
defining hidden environment variables. */
3320
+
if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3321
+
PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3322
+
goto fail_2;
3323
+
}
3318
3324
3319
3325
#if defined(PYOS_OS2)
3320
3326
/* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
Original file line number Diff line number Diff line change
@@ -352,7 +352,7 @@ getenvironment(PyObject* environment)
352
352
p = PyString_AS_STRING(out);
353
353
354
354
for (i = 0; i < envsize; i++) {
355
-
int ksize, vsize, totalsize;
355
+
size_t ksize, vsize, totalsize;
356
356
PyObject* key = PyList_GET_ITEM(keys, i);
357
357
PyObject* value = PyList_GET_ITEM(values, i);
358
358
@@ -363,10 +363,22 @@ getenvironment(PyObject* environment)
363
363
}
364
364
ksize = PyString_GET_SIZE(key);
365
365
vsize = PyString_GET_SIZE(value);
366
+
if (strlen(PyString_AS_STRING(key)) != ksize ||
367
+
strlen(PyString_AS_STRING(value)) != vsize)
368
+
{
369
+
PyErr_SetString(PyExc_TypeError, "embedded null character");
370
+
goto error;
371
+
}
372
+
/* Search from index 1 because on Windows starting '=' is allowed for
373
+
defining hidden environment variables. */
374
+
if (ksize == 0 || strchr(PyString_AS_STRING(key) + 1, '=') != NULL) {
375
+
PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
376
+
goto error;
377
+
}
366
378
totalsize = (p - PyString_AS_STRING(out)) + ksize + 1 +
367
379
vsize + 1 + 1;
368
380
if (totalsize > PyString_GET_SIZE(out)) {
369
-
int offset = p - PyString_AS_STRING(out);
381
+
size_t offset = p - PyString_AS_STRING(out);
370
382
if (_PyString_Resize(&out, totalsize + 1024))
371
383
goto exit;
372
384
p = PyString_AS_STRING(out) + offset;
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4