New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[3.3] Regression: Twig functions defined extensions, added in content no longer work. #6437
Comments
Where is |
https://github.com/bolt/PasswordProtect/blob/master/src/PasswordProtectExtension.php#L50-L64 I've just run into this one too on another extension. |
This is expected behavior.
|
Does this need to be done manually? If so, this is a (small) Breaking Change, imho, and it also needs to be documented properly. |
There is logic implemented to handle BC with old ways of specifying "safe". Such as The extension does neither of these. Additionally |
I don't think that's the entirety of the problem.. After I fix the
How would I add that function? Something like this doesn't work:
|
what about |
Thanks, @rossriley. That indeed helps.. I've made it work now, using this:
Is this what we want? |
I'm not sure that's ideal to be honest, it inverts the responsibility putting it on the extension author. In reality the extension author might not explicitly want to mark the functions as safe, but the site owner, depending on their threat model might be fine with anything being used in Twig. It would be nicer if we could whitelist everything by default and allow a siteowner to restrict as needed, i'm guessing for most of us when we use |
I think if the end-user (site implementor in this case) install an extension like passwordprotect, they will have to accept it. We could see if we could add an option for the control freaks to list somewhere which extension allows what? But, let's not invest too much time in that, until people actually request that. One thing that might help is more verbose notices in the system log. For example, this:
Does not make it clear to most people you'll need to add this in an extension:
A descriptive message in system log might go a long way, there. |
@bobdenotter @rossriley First off, STOP DOING THIS: $app['twig.sandbox.policy']->addAllowedMethod('session', 'get'); How many times do I have to say that invokes the service, and prevents further modification to the service.
This is a blacklist, and anyone you talk to about security says not do this. Always whitelist.
I agree with this. I haven't implemented anything yet, because I wasn't sure how to make it easier for users. Other than adding to each app parameter directly: $app['twig.sandbox.policy.tags'] = $app->share($app->extend('twig.sandbox.policy.tags', function ($tags) {
$tags[] = 'foo';
return $tags;
}));
$app['twig.sandbox.policy.functions']...
$app['twig.sandbox.policy.filters']...
$app['twig.sandbox.policy.methods']...
$app['twig.sandbox.policy.properties']... |
What good is the (not trying to be snarky, i really don't understand) |
$app['twig.sandbox.policy'] = $app->share($app->extend('twig.sandbox.policy', function ($policy) {
$policy->addAllowedMethod('');
return $policy;
})); I know it's verbose, everyone agrees. That's why they changed it in Silex 2.0. $app->extend('twig.sandbox.policy', function ($policy) {
$policy->addAllowedMethod('');
return $policy;
}); |
Think of it like this: The way you did it says "I need this service now", even though you aren't asking anything of it. The example I gave says "Hey when someone asks for this service, change it in this way before you give it to them". This is lazy, so if the service is never asked for that code doesn't need to run. And it allows others to add their modifications, right before it's needed. This may seem subtle for the Security Policy. It has a larger impact though when the service has dependencies and that dependency has dependencies. Twig for example: $app['twig']->addFunction(); Twig now asks for Config and Config asks for Filesystem. And now I don't get to swap out "files" filesystem for an S3 version, because that came after this statement. This is exactly why we've had so many loading problems the past two years. I think they've all been resolved now though, ResourceManager was the last one. I hope that clarifies things. Not sure if I explained it very well. |
It does make sense if you explain it like that. The verbosity makes it look fugly and verbose though. Like you said. I'll change them for my extension. However, this does not negate the fact that this is a breaking change between 3.2 and 3.3. At the very least we should document this properly, so that we can point people bumping into this problem to some proper docs. :-) |
Which is part of why we went with the
Throwing an exception vs returning null was a known change when I was coding the sandbox. I looked into what it would take to swallow the exception and I was in Twig's compilation land. I talked it over with @GawainLynch and we quickly decided against that and the break would be ok. But it seems we dropped the ball since then communicating that to everyone else. 😔 We can definitely update the exception message to give a suggestion of what to do. Which is the question. Maybe something like: # config.yml
twig_sandbox_security_policy: # nicer name plz?
# Twig functions
functions:
- passwordform
# Twig filters
filters:
# Twig tags
tags:
# PHP methods
methods:
- [Symfony\Component\HttpFoundation\Session\SessionInterface, get]
# and maybe shortcut for multiple methods of same class
- Symfony\Component\HttpFoundation\Session\SessionInterface:
- get
- has
# PHP properties
properties: I know part of the problem is a lack of documentation and that's on me. |
Oh, yes, getting an exception is much better than just having something "stop working". :-)
Nah, that sounds like overkill.. I've solved it like this for now: https://github.com/bolt/PasswordProtect/blob/master/src/PasswordProtectExtension.php#L36-L47 We should document that, and make sure the error message people get is distinctive enough for people to lead to that part of the docs. |
Should we also consider making the whitelisting coarser / simpler? From:
To:
|
So you could add
…and allow the whole service to be use in records giving editors the ability to grant "login" access to someone that load the page they wrote? |
This:
Is required, because the extension does:
Don't think that's easy to circumvent. |
… but that is still a CVE worthy hole |
Let alone the whole session data is open the line up |
Right. Ok, nevermind making it broader. Let's keep it more verbose. |
Documentation for the win! |
Sorry, to keep being the backwards compatibility moaner but I really think this is too big a break for a minor version. We encourage extension developers to add I agree with the concept of having a separate Twig sandbox, I'm not really sure that extension developers should have to care about it at all, I guess in some cases if you were doing something you knew wasn't suitable for general use then you could reasonably say don't let this near the general public... most Twig functions that are added though are just to do general stuff like output a tracking tag, output social links, we often provide things like prices that come from a separate db etc, they might be used in a mix of templates and in free copy too. So is there anything we can do to patch this in the 3.x series, preferably letting Twig function normally but if not doing something to whitelist all extension functions/filters as they are added? We can obviously be more specific about how things should work when we are bumping up a version, but I'm a bit concerned that a semver composer update is going to break a lot of functionality that depends on every single extension author auditing their code. |
I can go either way on this. I see why it's a worthwhile effort, and I wouldn't mind putting in some effort to get a number of extensions updated. Especially if the warning is descriptive to know what to add.
It's not that, exactly. In the case of my passwordprotect extension, the two Twig functions it adds aren't the problem. It was breaking on other things, like |
@rossriley that's not even what we did 3.0-3.2. If the function/filter was added with a Unless some where was being rendered with the main twig instead of safe_twig and now it's being rendered with the sandbox... Also, like bob said we can't know all the use cases magically. However, we could go through and add to the whitelist ourselves. There's already a substantial default list here |
I assume you're looking for @rossriley 😀 |
@ross AH! Sorry man. That's what I get for replying before coffee 🤦♂️ |
We've decided to not revert the work done wrt SecurityPolicy, and instead mitigate the slight BC break by adding better notices for developers to fix it in their extensions. (see #6504, for a WIP) |
Details
Reproduction
Step 1: Install
passwordprotect
step 2: edit the contenttype of Pages, for example to have
allowtwig: true
:Step 3: Add
{{ passwordform() }}
to a page:Step 4: Expect to see the form in the frontend, but see this instead:
System log says:
@carson, can you look into this?
The text was updated successfully, but these errors were encountered: