Skip to content

Commit 70e0f1c

Browse files
authored
fix: always use codejail.safe_exec.safe_exec when executing code (#26)
Usage of unsafely is determined by the setting `COURSES_WITH_UNSAFE_CODE` in the edx-platform code, when True, the jailed code would skip the sandboxed environment and run directly on the service environment. Allowing the use of unsafely through an HTTP call is an unnecesary attack vector.
1 parent f3655e4 commit 70e0f1c

2 files changed

Lines changed: 8 additions & 8 deletions

File tree

codejailservice/routes/code_exec_service.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def code_exec():
2828
# Lazy imports of codejail functions according(after) the configuration app.
2929
(
3030
safe_exec_exception,
31-
codejail_not_safe_exec,
31+
_,
3232
codejail_safe_exec,
3333
) = import_code_jail_safe_exec()
3434

@@ -37,9 +37,7 @@ def code_exec():
3737

3838
unsafely = payload["unsafely"]
3939
if unsafely:
40-
exec_fn = codejail_not_safe_exec
41-
else:
42-
exec_fn = codejail_safe_exec
40+
log.warning("Ignoring execution with unsafely=true")
4341

4442
try:
4543
python_path = payload["python_path"]
@@ -55,7 +53,7 @@ def code_exec():
5553
course_id,
5654
)
5755
start = timeit.default_timer()
58-
exec_fn(
56+
codejail_safe_exec(
5957
payload["code"],
6058
globals_dict,
6159
python_path=python_path,

codejailservice/tests/test_code_exec_service.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,15 @@ def test_unsafe_code_exec_success(self, import_code_jail_safe_exec):
103103

104104
self.assertEqual(200, response.status_code)
105105
self.assertDictEqual(expected_result, response.json)
106-
unsafe_exec.assert_called_once_with(
106+
safe_exec.assert_called_once_with(
107107
payload["code"],
108108
payload["globals_dict"],
109109
python_path=payload["python_path"],
110110
extra_files=[],
111111
limit_overrides_context=payload["limit_overrides_context"],
112112
slug=payload["slug"],
113113
)
114-
safe_exec.assert_not_called()
114+
unsafe_exec.assert_not_called()
115115

116116
@mock.patch("codejailservice.routes.code_exec_service.import_code_jail_safe_exec")
117117
def test_unsafe_code_exec_failure(self, import_code_jail_safe_exec):
@@ -128,7 +128,7 @@ def test_unsafe_code_exec_failure(self, import_code_jail_safe_exec):
128128
unsafe_exec,
129129
safe_exec,
130130
)
131-
unsafe_exec.side_effect = Exception("SyntaxError: invalid syntax ' with status code: 1")
131+
safe_exec.side_effect = Exception("SyntaxError: invalid syntax ' with status code: 1")
132132
payload = {
133133
"code": "Syntax error",
134134
"globals_dict": {"seed": 1, "anonymous_student_id": "student"},
@@ -152,6 +152,7 @@ def test_unsafe_code_exec_failure(self, import_code_jail_safe_exec):
152152
self.assertEqual(200, response.status_code)
153153
self.assertEqual(expected_result['emsg'], response.json["emsg"])
154154
self.assertEqual(expected_result['globals_dict'], response.json["globals_dict"])
155+
unsafe_exec.assert_not_called()
155156

156157
@mock.patch("codejailservice.routes.code_exec_service.import_code_jail_safe_exec")
157158
def test_safe_code_exec_failure(self, import_code_jail_safe_exec):
@@ -192,3 +193,4 @@ def test_safe_code_exec_failure(self, import_code_jail_safe_exec):
192193
self.assertEqual(200, response.status_code)
193194
self.assertEqual(expected_result['emsg'], response.json["emsg"])
194195
self.assertEqual(expected_result['globals_dict'], response.json["globals_dict"])
196+
unsafe_exec.assert_not_called()

0 commit comments

Comments
 (0)