5858use App \Settings \ImportSettings ;
5959use Illuminate \Support \Facades \Storage ;
6060use Illuminate \Support \Str ;
61+ use InvalidArgumentException ;
6162use libphonenumber \NumberParseException ;
6263use libphonenumber \PhoneNumberFormat ;
6364use libphonenumber \PhoneNumberUtil ;
@@ -84,20 +85,28 @@ public function __invoke(Submission $submission, string $fieldId, mixed $respons
8485
8586 foreach ($ response as $ file ) {
8687 $ key = ltrim ($ file ['path ' ], '/ ' );
87-
88- $ media = $ fieldSubmission
89- ->addMediaFromDisk ($ key , 's3 ' )
90- ->usingFileName ($ file ['originalFileName ' ] ?? basename ($ key ))
91- ->toMediaCollection ('files ' , 's3 ' );
92-
93- Storage::disk ('s3 ' )->delete ($ key );
94- $ fieldSubmission ->update ([
95- 'response ' => [
96- 'media_id ' => $ media ->id ,
97- 'file_name ' => $ media ->file_name ,
98- 'original_name ' => $ file ['originalFileName ' ] ?? $ media ->file_name ,
99- ],
100- ]);
88+ $ this ->validatePath ($ key );
89+
90+ if (! Storage::exists ($ key )) {
91+ continue ;
92+ }
93+
94+ try {
95+ $ media = $ fieldSubmission
96+ ->addMediaFromDisk ($ key , 's3 ' )
97+ ->usingFileName ($ file ['originalFileName ' ] ?? basename ($ key ))
98+ ->toMediaCollection ('files ' , 's3 ' );
99+
100+ $ fieldSubmission ->update ([
101+ 'response ' => [
102+ 'media_id ' => $ media ->id ,
103+ 'file_name ' => $ media ->file_name ,
104+ 'original_name ' => $ file ['originalFileName ' ] ?? $ media ->file_name ,
105+ ],
106+ ]);
107+ } finally {
108+ Storage::disk ('s3 ' )->delete ($ key );
109+ }
101110 }
102111 }
103112
@@ -126,6 +135,21 @@ public function __invoke(Submission $submission, string $fieldId, mixed $respons
126135 }
127136 }
128137
138+ protected function validatePath (string $ path ): void
139+ {
140+ if (str_contains ($ path , '.. ' ) || str_contains ($ path , '// ' )) {
141+ throw new InvalidArgumentException ('Invalid path: path traversal not allowed ' );
142+ }
143+
144+ if (! str_starts_with ($ path , 'tmp/ ' )) {
145+ throw new InvalidArgumentException ('Invalid path: must be within tmp/ directory ' );
146+ }
147+
148+ if (! preg_match ('/^tmp\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.[a-zA-Z0-9]+$/i ' , $ path )) {
149+ throw new InvalidArgumentException ('Invalid path: does not match expected format ' );
150+ }
151+ }
152+
129153 protected function handleEducatableEmailField (Submission $ submission , mixed $ response ): void
130154 {
131155 $ submissible = $ submission ->submissible ;
0 commit comments