Docs Vector ExpressionsReferenceSecurity FREE

Security

Vector Expressions is designed with a zero-trust security posture. Expressions are author-controlled inputs evaluated server-side, so several hardened guardrails are built directly into the engine.

Who Can Write Expressions?

Only users with the edit_posts capability can save expression bindings to blocks. This maps to the WordPress Editor role and above by default. Subscribers and unauthenticated visitors cannot author or modify expressions. The REST API route used for editor previews enforces the same capability check.

Property Access Restrictions

Access to context data is restricted at multiple layers:

User object: Only an explicit allow-list of properties is accessible — id, name, email, roles, and a small set of curated aliases. Database-level fields like user_pass, user_activation_key, and capability maps (e.g., wp_capabilities) are not in the allow-list and are inaccessible by design.

Meta keys: Both post.meta and the get_meta modifier automatically block access to any key recognized as “protected” by WordPress (keys starting with an underscore, as determined by is_protected_meta()), as well as explicitly sensitive keys like session_tokens.

The engine does not perform a regex scan for words like secret, token, or key — protection relies on the underscore convention and the explicit deny list above. If you register sensitive custom meta with non-underscore-prefixed keys, add those keys to the protected list yourself using the vector_expressions/sanitization/deny_list filter.

The vector_expressions/sanitization/deny_list filter controls HTML attribute injection (blocking attributes like onclick or srcdoc during block rendering), not property access.

Recursion Depth Limiting

The parser enforces a maximum nesting depth of 5. This prevents maliciously crafted or accidentally deeply nested expressions from causing stack overflows. When the limit is exceeded, the parser returns the raw template string as-is rather than an empty string or an error.

Output Escaping

The engine applies different escaping strategies depending on expression syntax:

SyntaxEscaping
{{ expr }}htmlspecialchars() with ENT_QUOTES — prevents all HTML and attribute injection
{{{ expr }}}wp_kses_post() — allows safe HTML; strips dangerous tags like <script>
HTML attribute injectionWP_HTML_Tag_Processor handles encoding natively; recognized URL attributes (href, src) are additionally run through esc_url() to block javascript: URI injection

The raw modifier follows the same wp_kses_post() path as triple-brace syntax.

Expression Sandboxing

The expression language does not allow:

  • Arbitrary PHP function calls
  • File system access
  • HTTP requests (core engine only — Pro adds controlled REST integrations)
  • Raw SQL queries

The parser grammar is strictly defined using a custom recursive-descent tokenizer. Any syntax outside the defined grammar is rejected and returns an empty string. All variable resolution and modifier dispatch run through controlled internal classes (Context and Library) — there is no eval() or dynamic function dispatch.

Best Practices

  1. Keep custom roots read-only. Context roots should expose data, not trigger side effects or mutations.
  2. Prefix sensitive custom meta with an underscore. The engine treats underscore-prefixed meta as protected automatically via is_protected_meta().
  3. Use the sanitization deny list for attributes. If you allow dynamic attribute binding, audit vector_expressions/sanitization/deny_list to ensure dangerous attributes are blocked.
  4. Avoid raw output unless necessary. {{{ }}} and the raw modifier bypass htmlspecialchars. Use them only for trusted content that you control.