{"record":{"id":"68cf3a949c59209b","repo":"twigphp/Twig","slug":"test-s-is-not-allowed","errorCode":null,"errorMessage":"Test \"%s\" is not allowed.","messagePattern":"Test \"(.+?)\" is not allowed\\.","errorType":"exception","errorClass":"SecurityNotAllowedTestError","httpStatus":null,"severity":"error","filePath":"src/Sandbox/SecurityPolicy.php","lineNumber":141,"sourceCode":"            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).');\n                } else {\n                    throw new SecurityNotAllowedFunctionError(\\sprintf('Function \"%s\" is not allowed.', $function), $function);\n                }\n            }\n        }\n\n        foreach ($tests as $test) {\n            if (!\\in_array($test, $this->allowedTests, true)) {\n                if (!$this->strict) {\n                    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);\n                } else {\n                    throw new SecurityNotAllowedTestError(\\sprintf('Test \"%s\" is not allowed.', $test), $test);\n                }\n            }\n        }\n    }\n\n    public function checkMethodAllowed($obj, $method): void\n    {\n        if ($obj instanceof Template || $obj instanceof Markup) {\n            return;\n        }\n\n        $allowed = false;\n        $method = strtolower($method);\n        foreach ($this->allowedMethods as $class => $methods) {\n            if ($obj instanceof $class && \\in_array($method, $methods, true)) {\n                $allowed = true;\n                break;\n            }","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Sandbox/SecurityPolicy.php#L123-L159","documentation":"checkSecurity() throws SecurityNotAllowedTestError when a template uses a Twig test (e.g. is odd, is defined) not in allowedTests. Before strict mode, unlisted tests only trigger a deprecation (they were historically always allowed in sandboxes); with strict mode enabled they throw immediately, matching planned 4.0 behavior.","triggerScenarios":"checkSecurity() called with $this->strict = true and a test absent from allowedTests (as exercised by testStrictModeCanBeEnabledViaSetterAfterConstruction, testStrictModeRejectsTestsViaSetter, testAllowedTestsCanBeUpdatedViaSetter); enabling strict mode via setStrict(true) then rendering a template that uses tests.","commonSituations":"Testing the Twig 3.28 deprecation/strict-mode transition for sandboxed tests; hardening a sandbox ahead of 4.0 where tests must be explicitly allowed.","solutions":["Add the required tests to the policy: $policy->setAllowedTests([...]) or the constructor's $tests argument.","Catch SecurityNotAllowedTestError around sandboxed rendering to identify the blocked test.","Explicitly enumerate every test used by sandboxed templates when strict mode is on.","Keep strict mode enabled in CI so missing test allowlist entries fail tests, not production."],"exampleFix":"// before\n $policy->setStrict(true); // template: {% if n is odd %}\n// after\n $policy->setAllowedTests(['odd', 'even', 'defined']);\n $policy->setStrict(true);","handlingStrategy":"try-catch","validationCode":"foreach ($testsUsed as $t) {\n    if (!in_array($t, $allowedTests, true)) { /* update setAllowedTests */ }\n}","typeGuard":null,"tryCatchPattern":"try {\n    $html = $twig->render($tpl, $ctx);\n} catch (\\Twig\\Sandbox\\SecurityNotAllowedTestError $e) {\n    $logger->warning('Sandbox blocked test', ['test' => $e->getTestName()]);\n}","preventionTips":["List every Twig test used by sandboxed templates via setAllowedTests().","Keep strict mode on in tests to replicate 4.0 behavior.","Cover test usage in sandbox integration tests.","Review 3.28 deprecation notices in logs as a checklist."],"tags":["twig","sandbox","security-policy","tests"],"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"}