Skip to content

Commit

Permalink
Restrict Internet Protocols for Linked Images
Browse files Browse the repository at this point in the history
Do not allow use of Php propietary protocols to retrieve linked images. Restrict to http, https, ftp, file, and s3.
  • Loading branch information
oleibman committed Aug 18, 2024
1 parent a917176 commit e312656
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/PhpSpreadsheet/Worksheet/Drawing.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ public function setPath(string $path, bool $verifyFile = true, ?ZipArchive $zip
if ($verifyFile && preg_match('~^data:image/[a-z]+;base64,~', $path) !== 1) {
// Check if a URL has been passed. https://stackoverflow.com/a/2058596/1252979
if (filter_var($path, FILTER_VALIDATE_URL)) {
if (!preg_match('/^(http|https|file|ftp|s3):/', $path)) {
throw new PhpSpreadsheetException('Invalid protocol for linked drawing');
}
$this->path = $path;
// Implicit that it is a URL, rather store info than running check above on value in other places.
$this->isUrl = true;
Expand Down
47 changes: 47 additions & 0 deletions tests/PhpSpreadsheetTests/Reader/Html/HtmlImage2Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace PhpOffice\PhpSpreadsheetTests\Reader\Html;

use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use PHPUnit\Framework\TestCase;

class HtmlImage2Test extends TestCase
{
public function testCanInsertImageGoodProtocol(): void
{
if (getenv('SKIP_URL_IMAGE_TEST') === '1') {
self::markTestSkipped('Skipped due to setting of environment variable');
}
$imagePath = 'https://phpspreadsheet.readthedocs.io/en/latest/topics/images/01-03-filter-icon-1.png';
$html = '<table>
<tr>
<td><img src="' . $imagePath . '" alt="test image voilà"></td>
</tr>
</table>';
$filename = HtmlHelper::createHtml($html);
$spreadsheet = HtmlHelper::loadHtmlIntoSpreadsheet($filename, true);
$firstSheet = $spreadsheet->getSheet(0);

/** @var Drawing $drawing */
$drawing = $firstSheet->getDrawingCollection()[0];
self::assertEquals($imagePath, $drawing->getPath());
self::assertEquals('A1', $drawing->getCoordinates());
}

public function testCannotInsertImageBadProtocol(): void
{
$this->expectException(SpreadsheetException::class);
$this->expectExceptionMessage('Invalid protocol for linked drawing');
$imagePath = 'httpx://phpspreadsheet.readthedocs.io/en/latest/topics/images/01-03-filter-icon-1.png';
$html = '<table>
<tr>
<td><img src="' . $imagePath . '" alt="test image voilà"></td>
</tr>
</table>';
$filename = HtmlHelper::createHtml($html);
$spreadsheet = HtmlHelper::loadHtmlIntoSpreadsheet($filename, true);
}
}
11 changes: 11 additions & 0 deletions tests/PhpSpreadsheetTests/Reader/Xlsx/URLImageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace PhpOffice\PhpSpreadsheetTests\Reader\Xlsx;

use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use PhpOffice\PhpSpreadsheetTests\Reader\Utility\File;
Expand Down Expand Up @@ -41,4 +42,14 @@ public function testURLImageSource(): void
self::assertSame('png', $extension);
}
}

public function testURLImageSourceBadProtocol(): void
{
$filename = realpath(__DIR__ . '/../../../data/Reader/XLSX/urlImage.bad.xlsx');
self::assertNotFalse($filename);
$this->expectException(SpreadsheetException::class);
$this->expectExceptionMessage('Invalid protocol for linked drawing');
$reader = IOFactory::createReader('Xlsx');
$reader->load($filename);
}
}
Binary file added tests/data/Reader/XLSX/urlImage.bad.xlsx
Binary file not shown.

0 comments on commit e312656

Please sign in to comment.