Skip to content

Commit f243f13

Browse files
[5.x] Prevent path traversal in file dictionary (#14272)
1 parent ecc1caa commit f243f13

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

src/Dictionaries/File.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Statamic\Dictionaries;
44

5+
use League\Flysystem\PathTraversalDetected;
56
use Statamic\Facades\Antlers;
67
use Statamic\Facades\YAML;
78

@@ -55,7 +56,13 @@ protected function getItemLabel(array $item): string
5556

5657
protected function getItems(): array
5758
{
58-
$path = resource_path('dictionaries').'/'.$this->config['filename'];
59+
$filename = $this->config['filename'];
60+
61+
if (str_contains($filename, '..')) {
62+
throw PathTraversalDetected::forPath($filename);
63+
}
64+
65+
$path = resource_path('dictionaries/'.$filename);
5966

6067
if (! file_exists($path)) {
6168
throw new \Exception('Dictionary file ['.$path.'] does not exist.');

tests/Dictionaries/FileTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Tests\Dictionaries;
44

5+
use League\Flysystem\PathTraversalDetected;
56
use PHPUnit\Framework\Attributes\DataProvider;
67
use PHPUnit\Framework\Attributes\Test;
78
use Statamic\Dictionaries\File;
@@ -180,4 +181,15 @@ public function it_gets_array_from_value()
180181
'emoji' => '🍌',
181182
], $item->data());
182183
}
184+
185+
#[Test]
186+
public function path_traversal_not_allowed()
187+
{
188+
$this->expectException(PathTraversalDetected::class);
189+
$this->expectExceptionMessage('Path traversal detected: ../secret.json');
190+
191+
(new File)
192+
->setConfig(['filename' => '../secret.json'])
193+
->options();
194+
}
183195
}

0 commit comments

Comments
 (0)