Skip to content

Add conditional registration for Twig SandboxExtension#18387

Closed
MadMikeyB wants to merge 1 commit intocraftcms:5.xfrom
MadMikeyB:5.x
Closed

Add conditional registration for Twig SandboxExtension#18387
MadMikeyB wants to merge 1 commit intocraftcms:5.xfrom
MadMikeyB:5.x

Conversation

@MadMikeyB
Copy link
Copy Markdown
Contributor

Description

In #18208, the Twig Sandbox was added conditionally to all places it's used, controlled by enableTwigSandbox (commit).

In #18216, the View class was updated (commit), but the conditional check for enableTwigSandbox was not applied to the SandboxExtension registration in createTwig(). As I understand it, , this means SandboxExtension is always added to Twig, even when enableTwigSandbox is false.

(I've been looking into this in circles for hours, so my apologies if I've missed something here)

Related issues

This seemingly breaks the craft-nocache plugin - ttempleton/craft-nocache#42

When nocache compiles templates, they include $this->sandbox->ensureToStringAllowed() calls because SandboxExtension is present. However, $this->sandbox is null during rendering because sandbox mode isn't actually enabled (since enableTwigSandbox is false). This causes fatal errors with no way to resolve other than stripping all $this->sandbox references from compiled templates via regex, so I think it better to fix upstream, apologies if this all sounds unrelated.

This fix ensures SandboxExtension is only registered when enableTwigSandbox is explicitly set to true, resolving the craft-nocache issue. I have tested this by setting ->enableTwigSandbox(false) and the issue with nocache is resolved. If I set it to ->enableTwigSandbox(true), their bug resurfaces, indicating that sandbox was always on.

@brandonkelly
Copy link
Copy Markdown
Member

Yeah sorry for the confusion… we changed our minds a couple times on how to implement sandboxing. As of #18216 / what actually shipped, the only time we register the sandbox extension is when View::renderSandboxedTemplate(), renderSandboxedString(), or renderSandboxedObjectTemplate() are called, and only if enableTwigSandbox is enabled.

The idea is that when something needs to render an untrusted template (like System Messages), the code can simply call the appropriate renderSandboxed* method, and leave it up to the project configuration on whether they want to opt into sandboxing or not.

Where we landed, System Message templates are the only templates that could be affected by any of the sandbox changes. Craft has never used the SandboxExtension besides that. So it’s hard to see how 5.9 would have affected normal templates / third party plugins, unless those plugins were updated based on a prior 5.9 change that didn’t end up actually shipping.

@MadMikeyB
Copy link
Copy Markdown
Contributor Author

MadMikeyB commented Feb 6, 2026

Thanks @brandonkelly - scuppers my idea as to why the nocache plugin is trying to load the sandbox in it's compiled template then! lol

@brandonkelly
Copy link
Copy Markdown
Member

Sorry, I lied! Looking back at the code, I forgot we are in fact always registering the SandboxExtension, but it’s only actually enabled when a renderSandboxed* method is called and the enableTwigSandbox config setting is enabled.

That said, if we were to only register the extension when enableTwigSandbox is enabled, like in this PR, that would only make fixing issues like ttempleton/craft-nocache#42 trickier, because they’d only surface when rendering System Messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants