{"record":{"id":"90898387607287a8","repo":"twigphp/Twig","slug":"tag-s-is-not-allowed","errorCode":null,"errorMessage":"Tag \"%s\" is not allowed.","messagePattern":"Tag \"(.+?)\" is not allowed\\.","errorType":"exception","errorClass":"SecurityNotAllowedTagError","httpStatus":null,"severity":"error","filePath":"src/Sandbox/SecurityPolicy.php","lineNumber":111,"sourceCode":"    public function isStrict(): bool\n    {\n        return $this->strict;\n    }\n\n    public function checkSecurity($tags, $filters, $functions, array $tests = []): void\n    {\n        if (\\func_num_args() < 4) {\n            trigger_deprecation('twig/twig', '3.28', 'Not passing the \"$tests\" argument to \"%s::checkSecurity()\" is deprecated; it will be required in 4.0.', static::class);\n        }\n\n        foreach ($tags as $tag) {\n            if (!\\in_array($tag, $this->allowedTags, true)) {\n                if (!$this->strict && 'extends' === $tag) {\n                    trigger_deprecation('twig/twig', '3.12', 'The \"extends\" tag 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).');\n                } elseif (!$this->strict && 'use' === $tag) {\n                    trigger_deprecation('twig/twig', '3.12', 'The \"use\" tag 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).');\n                } else {\n                    throw new SecurityNotAllowedTagError(\\sprintf('Tag \"%s\" is not allowed.', $tag), $tag);\n                }\n            }\n        }\n\n        foreach ($filters as $filter) {\n            if (!\\in_array($filter, $this->allowedFilters, true)) {\n                throw new SecurityNotAllowedFilterError(\\sprintf('Filter \"%s\" is not allowed.', $filter), $filter);\n            }\n        }\n\n        foreach ($functions as $function) {\n            if (!\\in_array($function, $this->allowedFunctions, true)) {\n                if (!$this->strict && 'parent' === $function) {\n                    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).');\n                } elseif (!$this->strict && 'block' === $function) {\n                    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).');\n                } elseif (!$this->strict && 'attribute' === $function) {\n                    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).');","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Sandbox/SecurityPolicy.php#L93-L129","documentation":"The sandbox SecurityPolicy throws SecurityNotAllowedTagError during checkSecurity() when a Twig tag used in the template is not in the allowedTags list. With strict mode off, 'extends' and 'use' are still permitted with a deprecation notice; everything else unlisted is rejected.","triggerScenarios":"Rendering a template inside {% sandbox %} (or via SandboxExtension) whose policy allowlist omits a tag the template uses (e.g. 'if', 'for', 'include' not passed to the SecurityPolicy constructor or setAllowedTags()).","commonSituations":"Tightening a sandbox policy for Twig 4.0 compatibility (tags like extends/use/parent/block/attribute will no longer be implicitly allowed); new template code using a tag the policy author never allowlisted.","solutions":["Add the required tag to the policy: new SecurityPolicy($tags, ...) or $policy->setAllowedTags([...]) including 'extends'/'use' explicitly.","Enable strict mode ($policy->setStrict(true)) in development to surface all future 4.0 rejections now and fix the allowlist.","Restructure the sandboxed template to avoid the disallowed tag.","Handle SecurityNotAllowedTagError in the rendering wrapper to report which tag was blocked."],"exampleFix":"// before\n $policy = new SecurityPolicy([], [], [], [], []); // no tags allowed\n// after\n $policy = new SecurityPolicy(['if', 'for', 'extends', 'use'], [], [], [], []);\n $policy->setStrict(true);","handlingStrategy":"try-catch","validationCode":"$usedTags = extractTemplateTags($templateSource); // your own static scan\n$missing = array_diff($usedTags, $allowedTags);\nif ($missing) { /* adjust policy before rendering */ }","typeGuard":null,"tryCatchPattern":"try {\n    $html = $twig->render($sandboxedTemplate, $data);\n} catch (\\Twig\\Sandbox\\SecurityNotAllowedTagError $e) {\n    $logger->warning('Sandbox blocked tag', ['tag' => $e->getTagName()]);\n    $html = '';\n}","preventionTips":["Explicitly allowlist 'extends' and 'use' before Twig 4.0.","Enable strict mode in dev/CI to catch policy gaps early.","Keep sandbox policy definitions next to the templates they govern.","Wrap sandboxed rendering in handlers for SecurityNotAllowed*Error."],"tags":["twig","sandbox","security-policy"],"backgroundTag":"permission-denied","analyzedSha":"a414c3a491defb5a60f2fc88ef79ff37c90010cd","analyzedAt":"2026-09-13T15:10:46.849Z","contentChangedAt":"2026-09-13T15:10:46.849Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}