Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Get correctly the current frame

This change fixes a security issue: __builtins__ was not readonly when
execute() was used!

Bug found by 雪狼 <kurskk141 AT gmail.com>.
  • Loading branch information...
commit c6def352c131302a97ec82df72ecabd82133fc85 1 parent 49cf81c
@haypo authored
View
2  ChangeLog
@@ -3,6 +3,8 @@ Version 1.6
FIXME: repair ClearImport() protection, or remove it
+ * SECURITY FIX: __builtins__ is now readonly when execute() is used.
+ It was only readonly when call() was used.
* Execute code in a subprocess using the Python subprocess module
or os.fork()
* Add --disable-subprocess command line option
View
4 run_tests.sh
@@ -6,7 +6,7 @@ rm -rf build
TESTED=""
for PYVER in 2.5 2.6 2.7; do
PYTHON=python$PYVER
- $PYTHON -c pass || continue
+ $PYTHON -c pass 1>/dev/null 2>&1 || continue
$PYTHON setup.py build
PYTHONPATH=$(cd build/lib.*-$PYVER/; pwd) $PYTHON tests.py --raise
if [ ! -z "$TESTED" ]; then
@@ -16,4 +16,4 @@ for PYVER in 2.5 2.6 2.7; do
fi
done
-echo "pysandbox tesed on Python $TESTED"
+echo "pysandbox tested on Python $TESTED"
View
4 sandbox/builtins.py
@@ -1,7 +1,7 @@
from __future__ import absolute_import
import __builtin__ as BUILTINS_MODULE
from types import FrameType
-from sys import _getframe, version_info
+from sys import version_info
import sys
from sandbox import SandboxError, HAVE_CSANDBOX
@@ -31,7 +31,7 @@ def enable(self, sandbox):
del self.builtin_dict[key]
# Get frame builtins
- self.frame = _getframe(2)
+ self.frame = sandbox.frame
self.builtins_dict = self.get_frame_builtins(self.frame)
# Get module list
View
3  sandbox/config.py
@@ -484,6 +484,7 @@ def fromOptparseOptions(options):
if options.allow_path:
for path in options.allow_path:
config.allowPath(path)
- config.timeout = options.timeout
+ if config.use_subprocess:
+ config.timeout = options.timeout
return config
View
7 sandbox/sandbox_class.py
@@ -1,6 +1,7 @@
from __future__ import with_statement, absolute_import
from .config import SandboxConfig
from .proxy import proxy
+from sys import _getframe
def keywordsProxy(keywords):
# Dont proxy keys because function keywords must be strings
@@ -28,6 +29,8 @@ def __init__(self, config=None):
self.protections = [protection() for protection in self.PROTECTIONS]
self.execute_subprocess = None
self.call_fork = None
+ # set during enable()
+ self.frame = None
def _call(self, func, args, kw):
"""
@@ -35,8 +38,10 @@ def _call(self, func, args, kw):
"""
args = proxy(args)
kw = keywordsProxy(kw)
+ self.frame = _getframe()
for protection in self.protections:
protection.enable(self)
+ self.frame = None
try:
return func(*args, **kw)
finally:
@@ -63,8 +68,10 @@ def _execute(self, code, globals, locals):
"""
if globals is None:
globals = {}
+ self.frame = _getframe()
for protection in self.protections:
protection.enable(self)
+ self.frame = None
try:
_call_exec(code, globals, locals)
finally:
View
8 sandbox/test/test_builtins.py
@@ -2,7 +2,7 @@
from sandbox.test import SkipTest, createSandbox, createSandboxConfig
from sys import version_info
-def test_exec_builtins():
+def test_call_exec_builtins():
def check_builtins_type():
result = []
exec "result.append(type(__builtins__))" in {'result': result}
@@ -14,6 +14,12 @@ def check_builtins_type():
config._builtins_whitelist.add('compile')
Sandbox(config).call(check_builtins_type)
+def test_exec_builtins():
+ config = createSandboxConfig()
+ Sandbox(config).execute("""
+assert type(__builtins__) != dict
+ """.strip())
+
def test_builtins_setitem():
def builtins_superglobal():
if isinstance(__builtins__, dict):
Please sign in to comment.
Something went wrong with that request. Please try again.