Moderate severityNVD Advisory· Published Feb 26, 2025· Updated Mar 12, 2025
Relative Path Traversal in assets file upload
CVE-2022-25773
Description
This advisory addresses a file placement vulnerability that could allow assets to be uploaded to unintended directories on the server.
- Improper Limitation of a Pathname to a Restricted Directory: A vulnerability exists in the asset upload functionality that allows users to upload files to directories outside of the intended temporary directory.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
mautic/corePackagist | < 5.2.3 | 5.2.3 |
Affected products
1- Range: < 5.2.3
Patches
1e6aaad99f399Merge pull request from GHSA-4w2w-36vm-c8hf
2 files changed · +63 −1
app/bundles/AssetBundle/EventListener/UploadSubscriber.php+1 −1 modified@@ -39,7 +39,7 @@ public function onPostUpload(PostUploadEvent $event): void { $request = $event->getRequest()->request; $response = $event->getResponse(); - $tempId = $request->get('tempId'); + $tempId = basename($request->get('tempId')); $file = $event->getFile(); $config = $event->getConfig(); $uploadDir = $config['storage']['directory'];
app/bundles/AssetBundle/Tests/Controller/AssetControllerFunctionalTest.php+62 −0 modified@@ -12,6 +12,7 @@ use Mautic\UserBundle\Entity\User; use Mautic\UserBundle\Model\RoleModel; use PHPUnit\Framework\Assert; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -202,6 +203,67 @@ public function getValuesProvider(): \Generator ]; } + public function testAssetUploadPathTraversal(): void + { + $client = $this->client; + $container = $this->getContainer(); + + // Get CSRF token + $csrfToken = $container->get('security.csrf.token_manager')->getToken('mautic_ajax_post')->getValue(); + + // Create a temporary file + $tempFile = tempnam(sys_get_temp_dir(), 'test_'); + file_put_contents($tempFile, '111'); + + // Prepare the file for upload + $uploadedFile = new UploadedFile( + $tempFile, + 'test.txt', + 'text/plain', + null, + true + ); + + $tmpDir = 'tmp_'.substr(md5(uniqid()), 0, 13); + $client->request( + 'POST', + '/s/_uploader/asset/upload', + ['tempId' => '../../'.$tmpDir], + ['file' => $uploadedFile], + [ + 'HTTP_X-Requested-With' => 'XMLHttpRequest', + 'HTTP_X-CSRF-Token' => $csrfToken, + ] + ); + + $response = $client->getResponse(); + + // Assert response is successful + $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); + + // Decode JSON response + $responseData = json_decode($response->getContent(), true); + + // Assert the response contains expected keys + $this->assertArrayHasKey('tmpFileName', $responseData); + + // Assert file was created in the correct directory + $expectedDir = $container->getParameter('mautic.upload_dir').join('/', ['', 'tmp', $tmpDir]); + $expectedFilePath = join('/', [$expectedDir, $responseData['tmpFileName']]); + $this->assertFileExists($expectedFilePath); + + // Clean up + if (file_exists($expectedFilePath)) { + unlink($expectedFilePath); + } + if (is_dir($expectedDir)) { + rmdir($expectedDir); + } + if (file_exists($tempFile)) { + unlink($tempFile); + } + } + private function getUser(string $username): User { $repository = $this->em->getRepository(User::class);
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.