User-controlled template sources were rendered with the unrestricted
jinja2.Template, allowing authenticated users to achieve remote code
execution. All rendering now goes through a single shared
RenderSandboxedTemplate() helper backed by jinja2.sandbox, which denies
unsafe attribute access (e.g. __globals__, __class__) while keeping the
intended templating features working:
- POST /api/email/preview: Body and Subject (GHSA-8q4m-52pw-hfmw)
- POST /api/email/send: Body and Subject (same sink class)
- POST /api/updateWireguardConfigurationInfo (OverridePeerSettings):
values were rendered before validation, so the payload executed
before __validateOverridePeerSettings could reject it
- Peer.downloadPeer(): rendered configuration file includes raw
OverridePeerSettings values; also rendered for dashboard clients
via GetAssignedPeers
Verified: lipsum.__globals__, __class__.__mro__, TemplateReference,
cycler/joiner/namespace escape chains all raise SecurityError; normal
templates ({{ configuration.* }}, {{ peer.* }}, filters, loops) render
unchanged.
Co-authored-by: DaanSelen <80752476+DaanSelen@users.noreply.github.com>