P0+P1 fixes: RCE sandbox, SQL injection, RLS tenant isolation, DB roles, test syntax, attachment, permission registry, membership check
Check Cross-Plugin Imports / check (push) Has been cancelled
Check Cross-Plugin Imports / check (push) Has been cancelled
This commit is contained in:
@@ -8,7 +8,8 @@ from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape, StrictUndefined
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
|
||||
# ─── Constants ──────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -63,14 +64,17 @@ PRESET_META: list[dict[str, Any]] = [
|
||||
# ─── Jinja2 Environment ─────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def _get_env() -> Environment:
|
||||
"""Create a Jinja2 environment with file system loader for templates dir."""
|
||||
return Environment(
|
||||
def _get_env() -> SandboxedEnvironment:
|
||||
"""Create a sandboxed Jinja2 environment with file system loader for templates dir."""
|
||||
env = SandboxedEnvironment(
|
||||
loader=FileSystemLoader(str(TEMPLATES_DIR)),
|
||||
autoescape=select_autoescape(["html", "htm", "j2", "xml"]),
|
||||
trim_blocks=True,
|
||||
lstrip_blocks=True,
|
||||
undefined=StrictUndefined,
|
||||
)
|
||||
env.globals.clear()
|
||||
return env
|
||||
|
||||
|
||||
# ─── Public API ─────────────────────────────────────────────────────────────
|
||||
@@ -111,11 +115,13 @@ def render_template_string(template_content: str, data: dict[str, Any]) -> str:
|
||||
Returns:
|
||||
Rendered HTML string
|
||||
"""
|
||||
env = Environment(
|
||||
env = SandboxedEnvironment(
|
||||
autoescape=select_autoescape(["html", "htm", "xml"]),
|
||||
trim_blocks=True,
|
||||
lstrip_blocks=True,
|
||||
undefined=StrictUndefined,
|
||||
)
|
||||
env.globals.clear()
|
||||
template = env.from_string(template_content)
|
||||
if "generated_at" not in data:
|
||||
data["generated_at"] = datetime.now(timezone.utc).strftime(
|
||||
|
||||
@@ -77,10 +77,12 @@ def _report_to_response(r: ReportInstance) -> dict:
|
||||
|
||||
|
||||
def _render_jinja2(template_content: str, data: dict) -> str:
|
||||
"""Render a Jinja2 template string with the given data."""
|
||||
from jinja2 import Environment, StrictUndefined
|
||||
"""Render a Jinja2 template string with the given data (sandboxed)."""
|
||||
from jinja2 import StrictUndefined
|
||||
from jinja2.sandbox import SandboxedEnvironment
|
||||
|
||||
env = Environment(autoescape=False, undefined=StrictUndefined)
|
||||
env = SandboxedEnvironment(autoescape=True, undefined=StrictUndefined)
|
||||
env.globals.clear()
|
||||
template = env.from_string(template_content)
|
||||
return template.render(**data)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user