Skip to content

Secure unserialize by restricting allowed classes when using PHP 7 #21090

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

Merged
merged 1 commit into from
Feb 12, 2017
Merged

Secure unserialize by restricting allowed classes when using PHP 7 #21090

merged 1 commit into from
Feb 12, 2017

Conversation

dbrumann
Copy link
Contributor

@dbrumann dbrumann commented Dec 29, 2016

Q A
Branch? master
Bug fix? no
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets ---
License MIT
Doc PR ---

While playing around with Symfony in a PHP 7.1 application I noticed a warning in how EnvParameterResoure uses unserialize. Since PHP 7.0 introduced the options argument which allows to restrict which classes can be unserialized for better security, it might make sense to use it here. As far as I can tell this is no BC break, it only provides an additional safety mechanism.

$options = null;
if (PHP_VERSION_ID >= 70000) {
$options = array('allowed_classes' => false);
}
return unserialize($this->nodes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing $options usage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed that bit for now because $this-nodes contains Node-classes. I will have to check whether I can restrict allowed_classes here.

@dbrumann dbrumann changed the title Secure unserialize in EnvParameterResource when using PHP 7 Secure unserialize by restricting allowed classes when using PHP 7 Dec 29, 2016
if (PHP_VERSION_ID >= 70000) {
$options = array('allowed_classes' => array('Twig_Profiler_Profile'));
}
$this->profile = unserialize($this->data['profile'], $options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid problems with PHP 5.x this could be changed to:

if (PHP_VERSION_ID >= 70000) {
    $this->profile = unserialize($this->data['profile'], array(
        'allowed_classes' => array('Twig_Profiler_Profile'),
    ));
} else {
    $this->profile = unserialize($this->data['profile']);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but do we want this? I was thinking about something like this: https://github.com/dbrumann/polyfill-unserialize

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirm we prefer doing this than adding a dependency yes :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, then I will change the occurrences instead. Thanks for the feedback.

@nicolas-grekas nicolas-grekas added this to the 3.x milestone Jan 2, 2017
@dunglas
Copy link
Member

dunglas commented Jan 3, 2017

👍

@xabbuh
Copy link
Member

xabbuh commented Jan 22, 2017

👍

Status: Reviewed

@fabpot
Copy link
Member

fabpot commented Feb 12, 2017

Thank you @dbrumann.

@fabpot fabpot merged commit b420181 into symfony:master Feb 12, 2017
fabpot added a commit that referenced this pull request Feb 12, 2017
…sing PHP 7 (dbrumann)

This PR was merged into the 3.3-dev branch.

Discussion
----------

Secure unserialize by restricting allowed classes when using PHP 7

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | ---
| License       | MIT
| Doc PR        | ---

While playing around with Symfony in a PHP 7.1 application I noticed a warning in how EnvParameterResoure uses unserialize. Since PHP 7.0 introduced the options argument which allows to restrict which classes can be unserialized for better security, it might make sense to use it here. As far as I can tell this is no BC break, it only provides an additional safety mechanism.

Commits
-------

b420181 Conditionally add options to unserialize in PHP 7.0+.
@nicolas-grekas nicolas-grekas modified the milestone: 3.x Mar 24, 2017
@Tobion Tobion mentioned this pull request Jun 9, 2017
@@ -185,6 +185,10 @@ public function serialize()
*/
public function unserialize($serialized)
{
list($this->message, $this->messageTemplate, $this->messageParameters, $this->messagePluralization, $this->cause) = unserialize($serialized);
if (PHP_VERSION_ID >= 70000) {
list($this->message, $this->messageTemplate, $this->messageParameters, $this->messagePluralization, $this->cause) = unserialize($serialized, array('allowed_classes' => false));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks wrong to me. The cause can be an object (and actually, it is an object in many cases in Symfony)

Gribnif pushed a commit to Gribnif/symfony that referenced this pull request Jun 9, 2017
fabpot added a commit that referenced this pull request Jun 13, 2017
…outing/Route.php (Dan Wilga)

This PR was submitted for the master branch but it was merged into the 3.3 branch instead (closes #23121).

Discussion
----------

[Routing] Revert the change in [#b42018] with respect to Routing/Route.php

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #21090 #23109
| License       | MIT
| Doc PR        |

...because it breaks BC with third-party code which, for instance, might use a subclass of CompiledRoute within the options portion of the Route. Refers to #21090 and #23109

Commits
-------

f09893b [Routing] Revert the change in [#b42018] with respect to Routing/Route.php
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants