From 7882dbefb4b44816af8db644843eabe9cb285073 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Gomez Date: Wed, 18 May 2022 13:23:38 +0200 Subject: [PATCH] =?UTF-8?q?Modified=20the=20AttachedFile=20model=20to=20al?= =?UTF-8?q?ways=20escape=20the=20html=20to=20avoid=20XSS=20attacks=20using?= =?UTF-8?q?=20the=20file=20name.=20Also=20added=20a=20unit=20test=20to=20p?= =?UTF-8?q?revent=20regressions.=20------=20Modificado=20el=20modelo=20Att?= =?UTF-8?q?achedFile=20para=20escapar=20siempre=20el=20html=20y=20evitar?= =?UTF-8?q?=20as=C3=AD=20ataques=20XSS=20usando=20el=20nombre=20del=20arch?= =?UTF-8?q?ivo.=20A=C3=B1adido=20tambi=C3=A9n=20un=20test=20unitario=20par?= =?UTF-8?q?a=20prevenir=20regresiones.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Model/AttachedFile.php | 3 + Test/Core/Model/AttachedFileTest.php | 56 ++++++++++++++++++ ...ss\"'>.jpeg" | Bin 0 -> 20775 bytes 3 files changed, 59 insertions(+) create mode 100644 Test/Core/Model/AttachedFileTest.php create mode 100644 "Test/__files/xss\"'>.jpeg" diff --git a/Core/Model/AttachedFile.php b/Core/Model/AttachedFile.php index 8fe9e52542..23f6b5ff32 100644 --- a/Core/Model/AttachedFile.php +++ b/Core/Model/AttachedFile.php @@ -155,6 +155,9 @@ public function test(): bool return $this->setFile() && parent::test(); } + $this->filename = self::toolBox()::utils()::noHtml($this->filename); + $this->mimetype = self::toolBox()::utils()::noHtml($this->mimetype); + $this->path = self::toolBox()::utils()::noHtml($this->path); return parent::test(); } diff --git a/Test/Core/Model/AttachedFileTest.php b/Test/Core/Model/AttachedFileTest.php new file mode 100644 index 0000000000..6c44205c0f --- /dev/null +++ b/Test/Core/Model/AttachedFileTest.php @@ -0,0 +1,56 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +namespace FacturaScripts\Test\Core\Model; + +use FacturaScripts\Core\Base\ToolBox; +use FacturaScripts\Core\Model\AttachedFile; +use PHPUnit\Framework\TestCase; + +final class AttachedFileTest extends TestCase +{ + public function testSaveFile() + { + $name = 'xss"\'>.jpeg'; + $filePath = FS_FOLDER . '/Test/__files/' . $name; + $this->assertTrue(file_exists($filePath), 'File not found: ' . $filePath); + + // copiamos el archivo a MyFiles + $this->assertTrue(copy($filePath, FS_FOLDER . '/MyFiles/' . $name), 'File not copied'); + + $model = new AttachedFile(); + $model->path = $name; + $this->assertTrue($model->save(), 'can-not-save-file'); + + // filename no puede contener html + $fileNameNoHtml = ToolBox::utils()::noHtml($name); + $this->assertEquals($fileNameNoHtml, $model->filename); + + // si forzamos el html en el filename, debe quitar el html + $model->filename = $name; + $this->assertTrue($model->save(), 'can-not-update-file'); + $this->assertEquals($fileNameNoHtml, $model->filename); + + // podemos eliminar + $this->assertTrue($model->delete(), 'can-not-delete-file'); + + // el archivo ya no está en el path + $this->assertFalse(file_exists($model->path)); + } +} diff --git "a/Test/__files/xss\"'>.jpeg" "b/Test/__files/xss\"'>.jpeg" new file mode 100644 index 0000000000000000000000000000000000000000..5caa4d81c520c7223196151d7764c46f36cec1cf GIT binary patch literal 20775 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 V=$d$wH5&PccYo82C)B&`|JlN$#B%@u literal 0 HcmV?d00001