1
votes

I have been trying to get this to work for a while now and can't find much docs on it. Or any use cases where the sandbox policy has been used outside of the Symfony framework.

I'm using Twig as a stand-alone package, so can't use any Symfony pseudo-code.

I have strict mode enabled so the sandbox affects all templates. Most templates render fine except this one which makes a call to a class. However I don't know how to allow it through.

Class:

class GetThings {

    public function doStuff() {
        return array(
            'id'   => '...',
            'data' => '...'
        );
    }

}

...

Twig:

$allowedTags = ['if', 'else', 'elseif', 'endif', 'for', 'endfor'];
$allowedFilters = ['upper', 'escape'];
$allowedMethods = [
    'GetThings' => array('doStuff') // Possibly this may be wrong?
];
$allowedProperties = [
    'GetThings' => array('id', 'data') // Or this is wrong? But not sure the correct way.
];
$allowedFunctions = ['range'];

$policy = new Twig_Sandbox_SecurityPolicy($allowedTags, $allowedFilters, $allowedMethods, $allowedProperties, $allowedFunctions);
$sandbox = new Twig_Extension_Sandbox($policy, true);

...

Template:

{% for i in info %}
    {{ i.id }}       <- Code that raises securityPolicy exception.
    {{ i.data }}     <- Code that raises securityPolicy exception.
{% endfor %}

I believe it may be related to the allowed methods or properties, but I wasn't able to find any working examples of these in use. I've tried the full namespaces too, nothing.

EDIT: So I looked into this error a bit deeper and found the exception stack-trace, for some reason it thinks my class is StdClass rather than GetThings? Not sure why. Any ideas?

Twig_Sandbox_SecurityNotAllowedPropertyError: Calling "id" property on a "stdClass" object is not allowed.

To instantiate the class I simply do the following:

public function index() {
    $data = new GetThings();
    // echo get_class($data); // returns GetThings as expected...

    return $twig->render('index.twig', [
        'info' => $data->doStuff()
    ]);
}

If I do 'StdClass' => array('id', 'data') for the allowed properties, the page works fine. But I feel this is not working as intended, as StdClass could be anything? And GetThings should work, no?

EDIT:

I think I figured it out. So my allowed properties allows 'GetThings' => [id, data] which is fine. doStuff() returns a \PDO array of objects, using the \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_OBJ option which causes PDO to convert all returned values into StdClass objects.

Is there any way around this? I want to keep that option, but still want to reference the policy as 'GetThings' => [...] rather than 'StdClass' => [...]

1
What does doStuff returns?DarkBee
Makes a database (\PDO) call then returns the array, see: pastebin.com/raw/0jeNmaB6kafide
See bottom of post for new update on cause. No solution for it as of yet.kafide
you can use \PDO::FETCH_CLASSDarkBee
@DarkBee What would I set the class as? My PDO connection is in a wrapper so any changes are used site wide.kafide

1 Answers

0
votes

It works as intended:

{% for i in info %}
    {{ i.id }}       <- Code that raises securityPolicy exception.
    {{ i.data }}     <- Code that raises securityPolicy exception.
{% endfor %}

Here i is not a GetThings instance. It's whatever you instantiated as value for the id and data key:

return array(
    'id'   => '...',
    'data' => '...'
);

Twig for tag will iterate over the info variable, which happens to be a keyed array. So the loop will iterate over the values of the array - in your case '...' and '...' which I guess are stdClass instances.