nystudio107/craft-twig-sandbox

允许您轻松创建一个沙盒化的Twig环境,您可以在其中控制允许哪些标签、过滤器、函数、对象方法和属性

5.0.1 2024-07-31 21:19 UTC

This package is auto-updated.

Last update: 2024-08-31 21:25:59 UTC


README

Scrutinizer Code Quality Code Coverage Build Status Code Intelligence Status

Craft Twig Sandbox

允许您轻松创建一个沙盒化的Twig环境,您可以在其中控制允许哪些标签、过滤器、函数、对象方法和属性

要求

Craft Twig Sandbox 需要 Craft CMS 5.x

安装

要安装 Craft Twig Sandbox,请按照以下步骤操作

  1. 打开您的终端并转到您的 Craft 项目

     cd /path/to/project
    
  2. 然后告诉 Composer 需要此包

     composer require nystudio107/craft-twig-sandbox
    

关于 Craft Twig Sandbox

与仅为沙盒创建新的Twig Environment 相比,Craft Twig Sandbox 继承了 Craft View 类,这带来了一些好处

  • 如果您想,您可以获得所有 Craft 提供的标签、过滤器、函数、对象、全局变量等。
  • 如果您想,则可以使用插件提供的标签、过滤器、函数和对象。
  • 您可以访问熟悉的 .renderObjectTemplate().renderString().renderPageTemplate().renderTemplate() 方法。
  • 还有所有与模板渲染相关的正常 Craft 事件和框架。

它还实现了一个 ErrorHandler,该处理器继承自 Craft ErrorHandler,用于处理渲染Twig模板时发生的异常。这允许它正确处理和显示异常,例如

Twig\Sandbox\SecurityNotAllowedFunctionError
Function "dump" is not allowed in "__string_template__b0120324b463b0e0d2c2618b7c5ce3ba" at line 1.

此外,如果安装了 Craft Closure 包,它将自动添加到沙盒中,以便在所有 Twig 模板渲染函数中使用。

使用 Craft Twig Sandbox

在其最简单的形式中,您可以创建一个类似于以下的Twig沙盒

use nystudio107\crafttwigsandbox\web\SandboxView;

$sandboxView = new SandboxView();

这将创建一个新的 SandboxView,它的工作方式与 Craft 网络的 View 类相同,因此您可以使用任何 View 渲染方法用于 Twig 模板。

$result = $sandboxView->renderString();
$result = $sandboxView->renderObjectTemplate();
$result = $sandboxView->renderPageTemplate();
$result = $sandboxView->renderTemplate();

...并且它们将使用默认的 BlacklistSecurityPolicy 进行渲染,因此黑名单中的 Twig 标签、过滤器、函数和对象方法和属性将不允许。

如果使用任何安全策略不允许的标签、过滤器、函数、对象方法和属性,则将抛出 SecurityError 异常。

注意:出于性能原因,您应创建一个 SandboxView 一次,并在整个应用程序生命周期中使用它,而不是每次渲染 Twig 时都重新创建它。

BlacklistSecurityPolicy

BlacklistSecurityPolicy 是一个 SecurityPolicy,它指定了不允许的 Twig 标签、过滤器、函数和对象方法和属性。

它默认为 合理数量的黑名单 Twig 标签、过滤器和函数,但您可以按需进行自定义。

use nystudio107\crafttwigsandbox\twig\BlacklistSecurityPolicy;
use nystudio107\crafttwigsandbox\web\SandboxView;

$securityPolicy = new BlacklistSecurityPolicy([
   'twigTags' => ['import'],
   'twigFilters' => ['base64_decode', 'base64_encode'],
   'twigFunctions' => ['dump'],
]);
$sandboxView = new SandboxView(['securityPolicy' => $securityPolicy]);
$result = $sandboxView->renderString("{{ dump() }}", []);

您还可以控制可以访问哪些对象方法和属性。默认情况下,BlacklistSecurityPolicy 不限制对任何对象方法或属性的访问。

例如,如果您不希望人们通过以下方式访问 DbConfig 对象的 password 属性

{{ craft.app.config.db.password }}

{{ craft.app.getConfig().getDb().password }}

...您将执行以下操作

use craft\config\DbConfig;
use nystudio107\crafttwigsandbox\twig\BlacklistSecurityPolicy;
use nystudio107\crafttwigsandbox\web\SandboxView;

$securityPolicy = new BlacklistSecurityPolicy([
   'twigProperties' => [
       DbConfig::class => ['password']
   ],
   'twigMethods' => [
       DbConfig::class => ['getPassword']
   ],
]);
$sandboxView = new SandboxView(['securityPolicy' => $securityPolicy]);
$result = $sandboxView->renderString("{{ craft.app.config.db.password }}", []);

如果您不希望任何对象上的属性或方法可以访问,可以传递一个 * 通配符。

   'twigProperties' => [
       DbConfig::class => '*'
   ],
   'twigMethods' => [
       DbConfig::class => '*'
   ],

WhitelistSecurityPolicy

WhitelistSecurityPolicy 是一种 SecurityPolicy,它指定了允许使用的 Twig 标签、过滤器、函数以及对象的方法/属性。

它默认为合理的白名单子集,包括允许的 Twig 标签、过滤器、函数和对象方法/属性,但您可以根据需要对其进行自定义。

use nystudio107\crafttwigsandbox\twig\WhitelistSecurityPolicy;
use nystudio107\crafttwigsandbox\web\SandboxView;

$securityPolicy = new WhitelistSecurityPolicy([
   'twigTags' => ['for', 'if'],
   'twigFilters' => ['replace', 'sort'],
   'twigFunctions' => ['date', 'random'],
]);
$sandboxView = new SandboxView(['securityPolicy' => $securityPolicy]);
$result = $sandboxView->renderString("{{ dump() }}", []);

您还可以控制允许访问的对象方法和属性。默认情况下,WhitelistSecurityPolicy 限制了所有对象方法或属性的访问。

这意味着您必须显式指定每个对象属性或方法。

例如,如果您想授予访问权限

{{ craft.app.config.general.devMode }}

{{ craft.app.getConfig().getGeneral().getDevMode() }}

...您将执行以下操作

use craft\config\GeneralConfig;
use craft\services\Config;
use craft\web\Application;
use craft\web\twig\variables\CraftVariable;
use nystudio107\crafttwigsandbox\twig\WhitelistSecurityPolicy;
use nystudio107\crafttwigsandbox\web\SandboxView;

$securityPolicy = new WhitelistSecurityPolicy([
   'twigProperties' => [
       CraftVariable::class => ['app'],
       Application::class => ['config'],
       Config::class => ['general'],
       GeneralConfig::class => ['devMode'],
   ]
   'twigMethods' => [
       Application::class => ['getConfig'],
       Config::class => ['getGeneral'],
   ],
]);
$sandboxView = new SandboxView(['securityPolicy' => $securityPolicy]);
$result = $sandboxView->renderString("{{ craft.app.config.general.devMode }}", []);

如果您希望某个对象的所有属性或方法都可以被访问,您可以通过传递一个 * 通配符来实现

   'twigProperties' => [
       DbConfig::class => '*'
   ],
   'twigMethods' => [
       DbConfig::class => '*'
   ],

自定义 SecurityPolicy

您还可以创建自己的自定义 SecurityPolicy 来使用,只需要符合 Twig 的 SecurityPolicyInterface

use my\custom\SecurityPolicy;
use nystudio107\crafttwigsandbox\web\SandboxView;

$securityPolicy = new SecurityPolicy([
]);
$sandboxView = new SandboxView(['securityPolicy' => $securityPolicy]);
$result = $sandboxView->renderString("{{ dump() }}", []);

通过 config/app.php 添加 SandboxView

如果您想在 Craft 应用程序中全局提供 Twig sandbox,可以将以下内容添加到您的 config/app.php

use craft\config\DbConfig;
use nystudio107\crafttwigsandbox\twig\BlacklistSecurityPolicy;
use nystudio107\crafttwigsandbox\web\SandboxView;

return [
    // ...
    'components' => [
        'sandboxView' => [
            'class' => SandboxView::class,
            'securityPolicy' => new BlacklistSecurityPolicy([
                'twigProperties' => [
                    DbConfig::class => '*'
                ],
                'twigMethods' => [
                    DbConfig::class => '*'
                ],
            ]),
        ],
    ],
];

这将创建一个全局可用的组件,您可以通过

Craft::$app->sandboxView->renderString('{% set password = craft.app.getConfig().getDb().password("") %}');

您甚至可以全局替换默认的 Craft viewSandboxView,如果需要的话

return [
    // ...
    'components' => [
        'view' => [
            'class' => SandboxView::class,
            'securityPolicy' => new BlacklistSecurityPolicy([
                'twigProperties' => [
                    DbConfig::class => '*'
                ],
                'twigMethods' => [
                    DbConfig::class => '*'
                ],
            ]),
        ],
    ],
];

Craft Twig Sandbox 路线图

一些待办事项和潜在功能的想法

  • 初始发布

nystudio107 提供