escaped word groups can't be unserialized #1121

Closed
opened 2026-10-05 00:32:07 +02:00 by adam · 4 comments
Owner

In https://github.com/Piwigo/Piwigo/commit/2e70ebf777e416748fcc3b2831b403eb30d51daa#diff-68e19e1f78d7f667fc58d480a5da7163da3939e1f6833fd22f62a7e21ae17ec0 (and https://github.com/Piwigo/Piwigo/commit/fd8394df07268b024c01ab54abea3e000f65c143#diff-68e19e1f78d7f667fc58d480a5da7163da3939e1f6833fd22f62a7e21ae17ec0) Piwigo 11 now escapes the word groups with backticks. Unfortunately a string like this:

a:13:{s:6:"`groups`";a:0:{}s:5:"level";i:0;s:4:"what";a:3:{i:0;s:10:"categories";i:1;s:8:"specials";i:2;s:11:"collections";}s:10:"photo_size";s:8:"original";s:9:"multisize";b:1;s:14:"archive_prefix";s:6:"piwigo";s:15:"archive_timeout";i:48;s:12:"max_elements";i:500;s:8:"max_size";i:100;s:10:"last_clean";i:1611238136;s:11:"one_archive";b:0;s:12:"force_pclzip";b:0;s:6:"direct";b:0;}

Can't be unserialized, because groups is escaped. For now, I have fixed the problem locally to Batch Downloader https://github.com/Piwigo/Piwigo-BatchDownloader/commit/9ddff8fb67815bf21c9747d1b66b823534f696c7

but it needs to be fixed at Piwigo level. I see 2 solutions:

  1. avoid the automatic escape (added by pwg_query) when called from conf_update_param
  2. remove the escapes in safe_unserialize
In https://github.com/Piwigo/Piwigo/commit/2e70ebf777e416748fcc3b2831b403eb30d51daa#diff-68e19e1f78d7f667fc58d480a5da7163da3939e1f6833fd22f62a7e21ae17ec0 (and https://github.com/Piwigo/Piwigo/commit/fd8394df07268b024c01ab54abea3e000f65c143#diff-68e19e1f78d7f667fc58d480a5da7163da3939e1f6833fd22f62a7e21ae17ec0) Piwigo 11 now escapes the word `groups` with backticks. Unfortunately a string like this: ``` a:13:{s:6:"`groups`";a:0:{}s:5:"level";i:0;s:4:"what";a:3:{i:0;s:10:"categories";i:1;s:8:"specials";i:2;s:11:"collections";}s:10:"photo_size";s:8:"original";s:9:"multisize";b:1;s:14:"archive_prefix";s:6:"piwigo";s:15:"archive_timeout";i:48;s:12:"max_elements";i:500;s:8:"max_size";i:100;s:10:"last_clean";i:1611238136;s:11:"one_archive";b:0;s:12:"force_pclzip";b:0;s:6:"direct";b:0;} ``` Can't be unserialized, because `groups` is escaped. For now, I have fixed the problem locally to Batch Downloader https://github.com/Piwigo/Piwigo-BatchDownloader/commit/9ddff8fb67815bf21c9747d1b66b823534f696c7 but it needs to be fixed at Piwigo level. I see 2 solutions: 1) avoid the automatic escape (added by `pwg_query`) when called from `conf_update_param` 2) remove the escapes in `safe_unserialize` <!-- github-sync-id:791195520 -->
adam closed this issue 2026-10-05 00:32:07 +02:00
Author
Owner

Solution 1 is obviously better to me and I'm going with it. But for the record, here is how the safe_unserialize could be also modified:

function safe_unserialize($value)
{
  if (is_string($value))
  {
    // Piwigo 11 has started to automatically espace the word "groups" with pwg_query. That
    // is a problem with conf_update_param because the string may contain this word and the
    // upcoming unserialize will fail. We need to unescape it before the unserialize.
    $value = str_replace('`groups`', 'groups', $value);
    $value = str_replace('`rank`', 'rank', $value);

    return unserialize($value);
  }
  return $value;
}
Solution 1 is obviously better to me and I'm going with it. But for the record, here is how the `safe_unserialize` could be also modified: ``` function safe_unserialize($value) { if (is_string($value)) { // Piwigo 11 has started to automatically espace the word "groups" with pwg_query. That // is a problem with conf_update_param because the string may contain this word and the // upcoming unserialize will fail. We need to unescape it before the unserialize. $value = str_replace('`groups`', 'groups', $value); $value = str_replace('`rank`', 'rank', $value); return unserialize($value); } return $value; } ``` <!-- github-comment-id:764708189 -->
Author
Owner

Another solution can be to encode in base64 (for example) the serialized data before insert them in database.

Another solution can be to encode in base64 (for example) the serialized data before insert them in database. <!-- github-comment-id:764714807 -->
Author
Owner

@nikrou could be a solution yes, but how ugly it would be in the database :-/ By looking at the config table, you would easily think it has been hacked.

@nikrou could be a solution yes, but how ugly it would be in the database :-/ By looking at the `config` table, you would easily think it has been hacked. <!-- github-comment-id:764715954 -->
Author
Owner

and actually, no it would not work. The problem is not to insert in the database, the problem is to unserialize the string. Storing it encoded in base64 would not change the problem.

In my opinion, the real problem is that pwg_query does not make the difference between:

select * from groups;

and

insert into config set param='nikrou', value='belong to many groups';

In both cases, pwg_query will str_replace "groups" into "groups", be it in the SQL (first case) or in a string (second case).

and actually, no it would not work. The problem is not to insert in the database, the problem is to unserialize the string. Storing it encoded in base64 would not change the problem. In my opinion, the real problem is that pwg_query does not make the difference between: > select * from groups; and > insert into config set param='nikrou', value='belong to many groups'; In both cases, pwg_query will `str_replace` "groups" into "groups", be it in the SQL (first case) or in a string (second case). <!-- github-comment-id:764719046 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/Piwigo#1121