Skip to content

Commit b42b137

Browse files
authored
Use jinja2 Sandbox instead of direct Template and enforce it (#727)
1 parent 70eecd5 commit b42b137

3 files changed

Lines changed: 13 additions & 5 deletions

File tree

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ ignore = [
8787
"TRY301", # raise-within-try: suggested "abstract to inner function" refactor adds indirection
8888
]
8989

90+
[tool.ruff.lint.flake8-tidy-imports.banned-api]
91+
# Force sandboxed rendering:
92+
"jinja2.Template".msg = "Use jinja2.sandbox.SandboxedEnvironment instead; the bare Template is not sandboxed."
93+
"jinja2.Environment".msg = "Use jinja2.sandbox.SandboxedEnvironment instead; the bare Environment is not sandboxed."
94+
9095
[tool.ruff.lint.per-file-ignores]
9196
"tests/**" = ["ANN"]
9297
"notebooks/**" = ["ANN", "T20"] # notebooks routinely print() for analysis output

src/bcbench/agent/shared/mcp.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pathlib import Path
55
from typing import Any
66

7-
from jinja2 import Template
7+
from jinja2.sandbox import SandboxedEnvironment
88

99
from bcbench.agent.shared.altool_paths import build_assembly_probing_paths, compiler_symbol_folder_for_container
1010
from bcbench.dataset import BaseDatasetEntry
@@ -13,6 +13,8 @@
1313

1414
logger = get_logger(__name__)
1515

16+
_jinja = SandboxedEnvironment(autoescape=False)
17+
1618

1719
def _build_server_entry(server: dict[str, Any], template_context: dict[str, Any]) -> tuple[str, dict[str, Any]]:
1820
server_type: str = server["type"]
@@ -26,7 +28,7 @@ def _build_server_entry(server: dict[str, Any], template_context: dict[str, Any]
2628
}
2729
case "stdio":
2830
args: list[str] = server["args"]
29-
rendered_args = [Template(arg).render(**template_context) for arg in args]
31+
rendered_args = [_jinja.from_string(arg).render(**template_context) for arg in args]
3032
command: str = shutil.which(server["command"]) or server["command"]
3133
entry: dict[str, Any] = {
3234
"type": server_type,

src/bcbench/agent/shared/prompt.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import re
22
from pathlib import Path
33

4-
from jinja2 import Template
4+
from jinja2.sandbox import SandboxedEnvironment
55

66
from bcbench.config import get_config
77
from bcbench.dataset import BaseDatasetEntry
88
from bcbench.types import EvaluationCategory
99

1010
_config = get_config()
1111

12+
_jinja = SandboxedEnvironment(autoescape=False)
13+
1214

1315
def _transform_image_paths(content: str) -> str:
1416
dest_dir = _config.file_patterns.problem_statement_dest_dir
@@ -26,8 +28,7 @@ def build_prompt(entry: BaseDatasetEntry, repo_path: Path, config: dict, categor
2628

2729
task = _transform_image_paths(entry.get_task())
2830

29-
template = Template(template_str)
30-
return template.render(
31+
return _jinja.from_string(template_str).render(
3132
repo_path=repo_path,
3233
task=task,
3334
project_paths=", ".join(entry.project_paths),

0 commit comments

Comments
 (0)