Skip to content

Commit 1777eb1

Browse files
authored
Merge pull request #1 from twistor/try-our-best
Do our best do defend against unfortunate serialized strings.
2 parents 06170d4 + 4ee71cd commit 1777eb1

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

src/Decoder.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,28 @@ public function __invoke(string $encodedSessionData): array
1515
return [];
1616
}
1717

18-
preg_match_all('/(^|;|\})(\w+)\|/i', $encodedSessionData, $matchesarray, PREG_OFFSET_CAPTURE);
18+
$serializeTypes = [
19+
'N', // null
20+
'b\:[0-1]', // boolean
21+
'a\:[0-9]+\:\{', // array
22+
's\:[0-9]+\:"', // string
23+
'd\:[0-9]+\.?[0-9]*', // float
24+
'i\:[0-9]+', // integer/resource
25+
'O\:[0-9]+\:"', // object
26+
// We can't support references even though PHP's native session encoder does
27+
// since we deserialize each key in a separate step.
28+
// 'r\:[0-9]+', // resource
29+
];
30+
31+
$serializeTypesString = '(?:' . implode('|', $serializeTypes) . ')';
32+
33+
preg_match_all('/(?:^|;|\})(\w+)\|' . $serializeTypesString . '/', $encodedSessionData, $matchesarray, PREG_OFFSET_CAPTURE);
1934

2035
$decodedData = [];
2136

2237
$lastOffset = null;
2338
$currentKey = '';
24-
foreach ($matchesarray[2] as $value) {
39+
foreach ($matchesarray[1] as $value) {
2540
$offset = $value[1];
2641
if (null !== $lastOffset) {
2742
$valueText = substr($encodedSessionData, $lastOffset, $offset - $lastOffset);

test/unit/DecodeTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ public function provideEncodeAndExpectedDecodedData() : array
6363
],
6464
]
6565
],
66+
[
67+
'evil_string|s:5:";foo|";',
68+
['evil_string' => ';foo|'],
69+
],
70+
[
71+
'null|N;',
72+
['null' => null],
73+
],
6674
];
6775
}
6876
}

0 commit comments

Comments
 (0)