A new boolean on XModuleSystem that determines whether to allow execution of untrusted unsandboxed code.
This commit is contained in:
@@ -502,6 +502,10 @@ class JavascriptResponse(LoncapaResponse):
|
||||
return tmp_env
|
||||
|
||||
def call_node(self, args):
|
||||
# Node.js code is un-sandboxed. If the XModuleSystem says we aren't
|
||||
# allowed to run unsafe code, then stop now.
|
||||
if not self.system.can_execute_unsafe_code:
|
||||
raise LoncapaProblemError("Execution of unsafe Javascript code is not allowed.")
|
||||
|
||||
subprocess_args = ["node"]
|
||||
subprocess_args.extend(args)
|
||||
|
||||
@@ -40,6 +40,7 @@ def test_system():
|
||||
node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules"),
|
||||
anonymous_student_id='student',
|
||||
cache=None,
|
||||
can_execute_unsafe_code=False,
|
||||
)
|
||||
return the_system
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import textwrap
|
||||
import mock
|
||||
import textwrap
|
||||
|
||||
from . import new_loncapa_problem
|
||||
from . import new_loncapa_problem, test_system
|
||||
|
||||
from capa.responsetypes import LoncapaProblemError, \
|
||||
StudentInputError, ResponseError
|
||||
@@ -30,9 +30,9 @@ class ResponseTest(unittest.TestCase):
|
||||
if self.xml_factory_class:
|
||||
self.xml_factory = self.xml_factory_class()
|
||||
|
||||
def build_problem(self, **kwargs):
|
||||
def build_problem(self, system=None, **kwargs):
|
||||
xml = self.xml_factory.build_xml(**kwargs)
|
||||
return new_loncapa_problem(xml)
|
||||
return new_loncapa_problem(xml, system=system)
|
||||
|
||||
def assert_grade(self, problem, submission, expected_correctness, msg=None):
|
||||
input_dict = {'1_2_1': submission}
|
||||
@@ -746,16 +746,37 @@ class JavascriptResponseTest(ResponseTest):
|
||||
coffee_file_path = os.path.dirname(__file__) + "/test_files/js/*.coffee"
|
||||
os.system("coffee -c %s" % (coffee_file_path))
|
||||
|
||||
problem = self.build_problem(generator_src="test_problem_generator.js",
|
||||
grader_src="test_problem_grader.js",
|
||||
display_class="TestProblemDisplay",
|
||||
display_src="test_problem_display.js",
|
||||
param_dict={'value': '4'})
|
||||
system = test_system()
|
||||
system.can_execute_unsafe_code = True
|
||||
problem = self.build_problem(
|
||||
system=system,
|
||||
generator_src="test_problem_generator.js",
|
||||
grader_src="test_problem_grader.js",
|
||||
display_class="TestProblemDisplay",
|
||||
display_src="test_problem_display.js",
|
||||
param_dict={'value': '4'},
|
||||
)
|
||||
|
||||
# Test that we get graded correctly
|
||||
self.assert_grade(problem, json.dumps({0: 4}), "correct")
|
||||
self.assert_grade(problem, json.dumps({0: 5}), "incorrect")
|
||||
|
||||
def test_cant_execute_javascript(self):
|
||||
# If the system says to disallow unsafe code execution, then making
|
||||
# this problem will raise an exception.
|
||||
system = test_system()
|
||||
system.can_execute_unsafe_code = False
|
||||
|
||||
with self.assertRaises(LoncapaProblemError):
|
||||
problem = self.build_problem(
|
||||
system=system,
|
||||
generator_src="test_problem_generator.js",
|
||||
grader_src="test_problem_grader.js",
|
||||
display_class="TestProblemDisplay",
|
||||
display_src="test_problem_display.js",
|
||||
param_dict={'value': '4'},
|
||||
)
|
||||
|
||||
|
||||
class NumericalResponseTest(ResponseTest):
|
||||
from response_xml_factory import NumericalResponseXMLFactory
|
||||
|
||||
@@ -702,6 +702,7 @@ class ModuleSystem(object):
|
||||
open_ended_grading_interface=None,
|
||||
s3_interface=None,
|
||||
cache=None,
|
||||
can_execute_unsafe_code=False,
|
||||
):
|
||||
'''
|
||||
Create a closure around the system environment.
|
||||
@@ -749,6 +750,9 @@ class ModuleSystem(object):
|
||||
.get(key) returns an object from the cache or None.
|
||||
.set(key, value, timeout_secs=None) stores a value in the cache with a timeout.
|
||||
|
||||
can_execute_unsafe_code - A boolean, whether or not to allow the execution
|
||||
of unsafe, unsandboxed code.
|
||||
|
||||
'''
|
||||
self.ajax_url = ajax_url
|
||||
self.xqueue = xqueue
|
||||
@@ -774,6 +778,7 @@ class ModuleSystem(object):
|
||||
self.s3_interface = s3_interface
|
||||
|
||||
self.cache = cache or DoNothingCache()
|
||||
self.can_execute_unsafe_code = can_execute_unsafe_code
|
||||
|
||||
def get(self, attr):
|
||||
''' provide uniform access to attributes (like etree).'''
|
||||
|
||||
Reference in New Issue
Block a user