twigphp/Twig · error · SecurityNotAllowedFunctionError
Function " " is not allowed.
Error message
Function "%s" is not allowed.
What it means
checkSecurity() throws SecurityNotAllowedFunctionError when the template calls a Twig function not in allowedFunctions. With strict mode disabled, 'parent', 'block', and 'attribute' are temporarily permitted via deprecation notices (removed in 4.0); all other unlisted functions throw.
Solutions
- Add the function to the allowlist via the constructor or $policy->setAllowedFunctions([...]).
- Explicitly allow 'parent', 'block', 'attribute' if you rely on the pre-4.0 behavior, and enable strict mode to test 4.0 behavior early.
- Catch SecurityNotAllowedFunctionError to report the blocked function name.
- Wrap function usage in custom whitelisted Twig functions if fine-grained control is needed.
Example fix
// before $policy = new SecurityPolicy([], [], [], [], []); // template calls range() // after $policy = new SecurityPolicy([], [], [], ['range', 'parent', 'block', 'attribute'], []); $policy->setStrict(true);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!in_array($fn, $allowedFunctions, true)) {
throw new \LogicException("Function '$fn' not allowed by sandbox policy");
} Try / catch
try {
$html = $twig->render($tpl, $ctx);
} catch (\Twig\Sandbox\SecurityNotAllowedFunctionError $e) {
$logger->warning('Sandbox blocked function', ['function' => $e->getFunctionName()]);
} Prevention
- Explicitly allow parent/block/attribute ahead of the 4.0 removal.
- Enable strict mode so implicit allowances stop masking gaps.
- Only register trusted, allowlisted functions for sandboxed environments.
- Audit templates for new function calls in code review.
When it happens
Trigger: A sandboxed template calls a function absent from the $functions constructor argument / setAllowedFunctions(); relying on 'parent'/'block'/'attribute' without strict mode (works now, throws in 4.0); a strict-mode policy rejecting any unlisted function.
Common situations: Migrating toward Twig 4.0 sandbox semantics; a template gaining a new function call after the policy was written; macro/namespace tests exercising sandbox exemptions.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Tag " " is not allowed.
- Filter " " is not allowed.
- Test " " is not allowed.
- Calling " " method on a " " object is not allowed.
- Calling " " property on a " " object is not allowed.
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/57ae9d260fde25a8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Sandbox/SecurityPolicy.php:131
}
}
foreach ($filters as $filter) {
if (!\in_array($filter, $this->allowedFilters, true)) {
throw new SecurityNotAllowedFilterError(\sprintf('Filter "%s" is not allowed.', $filter), $filter);
}
}
foreach ($functions as $function) {
if (!\in_array($function, $this->allowedFunctions, true)) {
if (!$this->strict && 'parent' === $function) {
trigger_deprecation('twig/twig', '3.27', 'The "parent" function is always allowed in sandboxes, but won\'t be in 4.0, please enable it explicitly in your sandbox policy if needed (or enable strict mode on the security policy to opt-in to the 4.0 behavior now).');
} elseif (!$this->strict && 'block' === $function) {
trigger_deprecation('twig/twig', '3.27', 'The "block" function is always allowed in sandboxes, but won\'t be in 4.0, please enable it explicitly in your sandbox policy if needed (or enable strict mode on the security policy to opt-in to the 4.0 behavior now).');
} elseif (!$this->strict && 'attribute' === $function) {
trigger_deprecation('twig/twig', '3.27', 'The "attribute" function is always allowed in sandboxes, but won\'t be in 4.0, please enable it explicitly in your sandbox policy if needed (or enable strict mode on the security policy to opt-in to the 4.0 behavior now).');
} else {
throw new SecurityNotAllowedFunctionError(\sprintf('Function "%s" is not allowed.', $function), $function);
}
}
}
foreach ($tests as $test) {
if (!\in_array($test, $this->allowedTests, true)) {
if (!$this->strict) {
trigger_deprecation('twig/twig', '3.28', 'The "%s" test is always allowed in sandboxes, but won\'t be in 4.0, please enable it explicitly in your sandbox policy if needed (or enable strict mode on the security policy to opt-in to the 4.0 behavior now).', $test);
} else {
throw new SecurityNotAllowedTestError(\sprintf('Test "%s" is not allowed.', $test), $test);
}
}
}
}
public function checkMethodAllowed($obj, $method): void
{
if ($obj instanceof Template || $obj instanceof Markup) {View on GitHub (pinned to a414c3a491)