Problem/Motivation

PHPCS using the Drupal coder standards, throws the following warning in "/src/Entity/Micon.php", line 192:

unserialize() is insecure unless allowed classes are limited. Use a safe format like JSON or use the allowed_classes option.

return unserialize(gzuncompress(stripslashes(base64_decode(strtr($data, '-_,', '+/=')))));

I don't have enough experience, but this could definitely be a potential security risk!

Issue fork micon-3271162

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Grevil created an issue. See original summary.

jacobbell84’s picture

Hmm. I'm not sure why there is serialization there to begin with, it's dealing entirely with strings as far as I can tell. @JaceRider, do you recall if there was a reason for that? Thinking we just remove the unserialize/deserialize calls and write an update hook that re-saves existing archives without the serialization. I don't think all the string manipulation is needed either. Maybe it was when the module was first written, but I've saved base64 encoded strings in the configuration before and it automatically prefixes it with !!binary so that it will work.

jacerider’s picture

Sorry I haven't been able to put really any time toward this project. Thanks @jacobbell84 for maintaining things.

The reason it is serialized is that it is an array of IcoMoon data. A better approach would have been JSON. The problem is that to change it now would break existing icon packages unless we wrote a migration/update that would convert the existing data to JSON.

anybody’s picture

Perhaps the risk could be mitigated by using allowed_classes parameter and ensuring this can never add any classes / executable code indeed?

Could someone post a short example of the non encoded contents? Is it an array or something?

Json and update hook would be the most safe way, in the end the risk is someone injecting executable / executed code.

jacobbell84’s picture

No worries, that's why having multiple maintainers is nice so we can cover each other as folks get busy :)
That helps though, let me do some testing and I'll see if I can set it up so that it doesn't use the serialize/unserialize methods. Thanks!

jacobbell84’s picture

And also add an update hook so that we don't break everyone's installs :)

jacobbell84’s picture

Status: Active » Needs review
StatusFileSize
new1.83 KB

Hi all, give this patch a try. In my testing, the encoding/gzcompression/serialization wasn't needed to store the zip. Just writing the zip into the config stored it properly with the binary prefix. Maybe it's a case where it was needed when the module was released, but not anymore. I did my testing on Drupal 9.3, so maybe someone that has Drupal 8 takes a pass at it? I also added an update hook that should convert any existing configs over to the new format.

Status: Needs review » Needs work

The last submitted patch, 7: micon_potential-security-risk-3271162-7.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

jacobbell84’s picture

Status: Needs work » Needs review
StatusFileSize
new1.62 MB

Adding default install configuration to the patch

Status: Needs review » Needs work

The last submitted patch, 9: micon_potential-security-risk-3271162-9.patch, failed testing. View results

jacobbell84’s picture

Trying to fix tests

jacobbell84’s picture

Status: Needs work » Needs review
StatusFileSize
new1.55 MB

Fixing schema

jacobbell84’s picture

anybody’s picture

Thank you very much, tje patch looks quite good to me, but perhaps @JaveRider could also have a look?

In this context it would perhaps make sense to opt into Drupal’s security advisory policy after fixing this issue?

jacobbell84’s picture

Hi @Anybody, that's the plan, I recently got my vetted security role for these projects :)

anybody’s picture

Very cool and congratulations, @jacobbell84! :) Looking forward to the next release.

grevil’s picture

Drupal did not automatically create the issue branch, only the issue fork for this issue, trying to manually create the issue branch, I accidentally based the branch on 8.x-1.x instead of 2.x...

Closing the original merge request and pushing the patch to the issue fork's 2.x branch instead.

grevil’s picture

grevil’s picture

Status: Needs review » Needs work
StatusFileSize
new99.92 KB

I am not able to import a icoMoon icon package.
The following error occurs:

Warning: file_get_contents(public://micon/test/selection.json): Failed to open stream: "Drupal\Core\StreamWrapper\PublicStream::stream_open" call failed in Drupal\micon\Entity\Micon->archiveExtract() (line 334 of modules/custom/micon-3271162/src/Entity/Micon.php)

Steps to reproduce

  • Go to https://icomoon.io/#icons-icomoon and download the "icomoon" free version.
  • Go to "/admin/structure/micon" and add a new icon pack
  • Give the pack a name and upload the just downloaded zip file
  • Error gets thrown

I also tried moving the zip file both into my private and public-files directory. Same error

grevil’s picture

The icon package gets correctly unzipped and moved to "/web/sites/default/files/micon/test".
The problem is, that the "selection.json" is completely empty.

grevil’s picture

grevil’s picture

grevil’s picture

OK, the patch in #12 actually works great! Although, we need to rewrite the "Adding IcoMoon packages" Instructions on the main module page, since icoMoon moved their package builder to "https://icomoon.io/app" and the packages in "https://icomoon.io/#icons" can not be imported, since they have their selection.json in a different file folder then the self built packages from https://icomoon.io/app.

PS: Sorry for the merging mess again...

grevil’s picture

Status: Needs work » Needs review

I will test the new update hook tomorrow, do a final code review, and then we can safely merge this!

grevil’s picture

Status: Needs review » Reviewed & tested by the community

Alright, the update hook also works like a charm! I added "'allowed_classes' => FALSE" to the update hook 'unserialize' function, since we only unserialize strings and never objects.
This way we prevent the security issue there as well, even if it is only used once per update.

I will update dev, create a new release and renew the module description on how to require the micon packages!

grevil’s picture

I will create a seperate release to 2.0.0-beta3, since I have not tested it on D8 (EOL). Just to be sure

  • Grevil committed 11a4411 on 2.x
    Issue #3271162: Potential security risk using "unserialize" without...
grevil’s picture

Status: Reviewed & tested by the community » Fixed

Thanks all! Changes are merged :)

anybody’s picture

Thank you all for fixing this!! :)

I will create a seperate release to 2.0.0-beta3, since I have not tested it on D8 (EOL). Just to be sure

You mean 2.1.0-beta0. Was just released.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.