getgrav/grav · error · SecurityNotAllowedFilterError
Filter "%s" is not allowed on a "%s" object inside sandboxed
Error message
Filter "%s" is not allowed on a "%s" object inside sandboxed content.
What it means
Same dump-guard family as the nesting limit: when the value passed to a guarded filter (print_r, vardump, yaml_encode, json_encode, string) in sandboxed content is an object, its class must be explicitly allowed. Reflective filters (print_r, vardump) accept only stdClass; policy filters (yaml_encode, json_encode, string) require GravSecurityPolicy::isClassAllowed() to be true, i.e. the class appears in the sandbox's allowedMethods map. Serializing anything else would bypass the sandbox's member gate by dumping PHP object state directly (GHSA-mc5q-6hpj-rp7j).
Source
Thrown at system/src/Grav/Common/Twig/Extension/GravExtension.php:395
}
if (is_array($var)) {
foreach ($var as $item) {
$this->scanSandboxDump($policy, $item, $filter, $reflective, $depth + 1);
}
return;
}
if (!is_object($var)) {
return;
}
$allowed = $reflective
? $var instanceof \stdClass
: ($policy !== null && $policy->isClassAllowed($var));
if (!$allowed) {
throw new SecurityNotAllowedFilterError(
sprintf('Filter "%s" is not allowed on a "%s" object inside sandboxed content.', $filter, $var::class),
$filter
);
}
}
/**
* @param Environment $env
* @param mixed $var
* @return string
*/
public function printRGuarded(Environment $env, mixed $var)
{
$this->assertSandboxDumpSafe($env, $var, 'print_r', true);
return $this->print_r($var);
}
/**View on GitHub (pinned to 6040efed04)
Solutions
- Serialize plain arrays/scalars instead of objects: {{ page.header|print_r }} (array) rather than {{ page|print_r }} (Page object)
- Move the debug/serialization into an unsandboxed theme template or a plugin
- If the object must be exposed, add its class to the sandbox policy allowedMethods via the security.twig_content configuration — weigh this carefully, it widens the sandbox
- For config access, use the provided SandboxConfig facade rather than raw Config/Data objects
Example fix
{# before (sandboxed content): Page object is refused #}
{{ page|print_r }}
{# after: plain array header data passes #}
{{ page.header|print_r }} Defensive patterns
Strategy: type-guard
Validate before calling
// only pass values the sandbox will serialize
if (is_object($value) && !$value instanceof stdClass && !$policy->isClassAllowed($value)) {
$value = is_callable([$value, 'toArray']) ? $value->toArray() : (array) $value; // or render a placeholder
} Type guard
function isSandboxSerializable(mixed $v, ?GravSecurityPolicy $policy, bool $reflective): bool
{
if (!is_object($v)) { return true; }
return $reflective ? $v instanceof \stdClass : ($policy !== null && $policy->isClassAllowed($v));
} Try / catch
use Twig\Sandbox\SecurityNotAllowedFilterError;
try { echo $twig->render($sandboxedTemplate, $data); }
catch (SecurityNotAllowedFilterError $e) { log_refused_class($e->getFilterName()); echo '<!-- object dump refused by sandbox -->'; } Prevention
- Pipe plain arrays (page.header) into dump filters, never service objects (page, grav, config)
- Do debugging in unsandboxed theme templates or plugins, not in content
- Use the SandboxConfig facade for config access in sandboxed content
- Review sandbox policy changes on Grav security releases
When it happens
Trigger: {{ page|print_r }} or {{ grav.page|json_encode }} in sandboxed content where Page is not in the policy allowlist; piping raw Config/Data objects when security.twig_content.config_access is off (only the redacting SandboxConfig facade stays allowed); dumping any service object from markdown-rendered Twig.
Common situations: Theme snippets pasted into page content (sandboxed) that worked in theme templates (not sandboxed); attempts to inspect Grav services from sandboxed markdown; sites updated to a Grav version that tightened dump filters.
Related errors
- Filter "%s" is not allowed on deeply nested data inside sand
- Test "%s" is not allowed.
- Tag "%s" is not allowed.
- The callable passed to the "array_group_by" filter must be a
- Twig |filter("{arrow}") is not allowed.
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/f79d1ad043822f1b.
Report an issue: GitHub.