Skip to content

Commit

Permalink
add new Security service, that can be overridden, add some doc about …
Browse files Browse the repository at this point in the history
…new Security service, fix security issue on scheme for cert html tag attributes, fix UTF8 example
  • Loading branch information
spipu committed Feb 26, 2025
1 parent e66a9a9 commit f93e818
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 49 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this project will be documented in this file.

## [5.3.1](https://github.com/spipu/html2pdf/compare/v5.3.0...v5.3.1) - 2025-02-26

* add new Security service, that can be overridden
* add some doc about new Security service
* fix security issue on scheme for cert html tag attributes - thanks to [Positive Technologies](https://www.ptsecurity.com)
* fix UTF8 example

## [5.3.0](https://github.com/spipu/html2pdf/compare/v5.2.8...v5.3.0) - 2025-01-08

* bump supported phpversion from **5.6 -> 8.2** to **7.2 -> 8.4**
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Html2Pdf is a HTML to PDF converter written in PHP, and compatible with PHP **7.

It allows the conversion of valid HTML in PDF format, to generate documents like invoices, documentation, ...

You have to write a code of HTML for Html2Pdf, and not try to convert directly an already existing html page.
You have to write specific cleaned HTML code for Html2Pdf.
Do not try to convert directly an already existing html page, or HTML code coming from WYSIWYG, no help will be provided in this case.

Specific tags have been implemented, to adapt the html standard to a PDF usage.

Expand Down
2 changes: 2 additions & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
* [Exceptions](./exception.md)
* [Useful Methods](./methods.md)
* [Tcpdf Methods](./tcpdf_methods.md)
* [Security / Blind SSRF](./security.md)

## Recommandations

* It is very important to provide valid HTML 4.01 to the converter, but only what is in the `<body>`.
* You have to write specific cleaned HTML code for Html2Pdf. Do not try to convert directly an already existing html page, or HTML code coming from WYSIWYG, no help will be provided in this case.
* Use the `<page>` tag. Does not use the `<html>` or `<body>` tag.
* for borders: it is advised that they are like `solid 1mm #000000`
* for padding, they are applicable only on tags `table`, `th`, `td`, `div`, `li`
Expand Down
21 changes: 21 additions & 0 deletions doc/security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Security

[back](./README.md)

Html2Pdf is using the default [Security](../src/Security/Security.php) service to protect the external included files (CSS, images, ...).

It allows :

* HTTP/HTTPS external files
* Local Files

It does **not** protect again **Blind SSRF**. This means that the library loads external resources
without validating the destination address before sending an HTTP request.

This is not the responsibility of this library.

You must ensure that the HTML you want to convert is secure, **especially if it is generated from uncontrolled data contributed by users**.
In such cases, an attacker could send requests to both external servers and restricted-access servers (e.g., within a local network).

If you need additional security, you can implement the [SecurityInterface](../src/Security/SecurityInterface.php),
and call the method `setSecurityService` on the Html2Pdf object to use it.
127 changes: 127 additions & 0 deletions examples/res/utf8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
Sentences that contain all letters commonly used in a language
--------------------------------------------------------------

This file is UTF-8 encoded.

Czech (cz)
---------

Příšerně žluťoučký kůň úpěl ďábelské ódy.
Hleď, toť přízračný kůň v mátožné póze šíleně úpí.
Zvlášť zákeřný učeň s ďolíčky běží podél zóny úlů.
Loď čeří kýlem tůň obzvlášť v Grónské úžině.
Ó, náhlý déšť již zvířil prach a čilá laň teď běží s houfcem gazel k úkrytům.

Danish (da)
---------

Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen
Wolther spillede på xylofon.
(= Quiz contestants were eating strawbery with cream while Wolther
the circus clown played on xylophone.)

German (de)
-----------

Falsches Üben von Xylophonmusik quält jeden größeren Zwerg
(= Wrongful practicing of xylophone music tortures every larger dwarf)

Zwölf Boxkämpfer jagten Eva quer über den Sylter Deich
(= Twelve boxing fighters hunted Eva across the dike of Sylt)

Heizölrückstoßabdämpfung
(= fuel oil recoil absorber)
(jqvwxy missing, but all non-ASCII letters in one word)

English (en)
------------

The quick brown fox jumps over the lazy dog

Spanish (es)
------------

El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y
frío, añoraba a su querido cachorro.
(Contains every letter and every accent, but not every combination
of vowel + acute.)

French (fr)
-----------

Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à
côté de l'alcôve ovoïde, où les bûches se consument dans l'âtre, ce
qui lui permet de penser à la cænogenèse de l'être dont il est question
dans la cause ambiguë entendue à Moÿ, dans un capharnaüm qui,
pense-t-il, diminue çà et là la qualité de son œuvre.

l'île exiguë
Où l'obèse jury mûr
Fête l'haï volapük,
Âne ex aéquo au whist,
Ôtez ce vœu déçu.

Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en
canoë au delà des îles, près du mälström où brûlent les novæ.

Irish Gaelic (ga)
-----------------

D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh

Hungarian (hu)
--------------

Árvíztűrő tükörfúrógép
(= flood-proof mirror-drilling machine, only all non-ASCII letters)

Icelandic (is)
--------------

Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa

Sævör grét áðan því úlpan var ónýt
(some ASCII letters missing)

Greek (el)
-------------

Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ στὸ χρυσαφὶ ξέφωτο
(= No more shall I see acacias or myrtles in the golden clearing)

Ξεσκεπάζω τὴν ψυχοφθόρα βδελυγμία
(= I uncover the soul-destroying abhorrence)

Hebrew (iw)
-----------

? דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה

Polish (pl)
-----------

Pchnąć w tę łódź jeża lub osiem skrzyń fig
(= To push a hedgehog or eight bins of figs in this boat)

Zażółć gęślą jaźń

Russian (ru)
------------

В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
(= Would a citrus live in the bushes of south? Yes, but only a fake one!)

Thai (th)
---------

[--------------------------|------------------------]
๏ เป็นมนุษย์สุดประเสริฐเลิศคุณค่า กว่าบรรดาฝูงสัตว์เดรัจฉาน
จงฝ่าฟันพัฒนาวิชาการ อย่าล้างผลาญฤๅเข่นฆ่าบีฑาใคร
ไม่ถือโทษโกรธแช่งซัดฮึดฮัดด่า หัดอภัยเหมือนกีฬาอัชฌาสัย
ปฏิบัติประพฤติกฎกำหนดใจ พูดจาให้จ๊ะๆ จ๋าๆ น่าฟังเอย ฯ

[The copyright for the Thai example is owned by The Computer
Association of Thailand under the Royal Patronage of His Majesty the
King.]

Example is coming from https://github.com/tecnickcom/TCPDF/blob/main/examples/data/utf8test.txt
2 changes: 1 addition & 1 deletion examples/utf8.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
try {
$html2pdf = new Html2Pdf('P', 'A4', 'fr');

$content = file_get_contents(K_PATH_MAIN.'examples/data/utf8test.txt');
$content = file_get_contents(dirname(__FILE__) . '/res/utf8.txt');
$content = '<page style="font-family: freeserif"><br />'.nl2br($content).'</page>';

$html2pdf->pdf->SetDisplayMode('real');
Expand Down
43 changes: 35 additions & 8 deletions src/Html2Pdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
use Spipu\Html2Pdf\Parsing\Node;
use Spipu\Html2Pdf\Parsing\TagParser;
use Spipu\Html2Pdf\Parsing\TextParser;
use Spipu\Html2Pdf\Security\Security;
use Spipu\Html2Pdf\Security\SecurityInterface;
use Spipu\Html2Pdf\Tag\TagInterface;
use Spipu\Html2Pdf\Debug\DebugInterface;
use Spipu\Html2Pdf\Debug\Debug;
Expand Down Expand Up @@ -69,6 +71,11 @@ class Html2Pdf
*/
private $svgDrawer;

/**
* @var SecurityInterface
*/
private $security;

protected $_langue = 'fr'; // locale of the messages
protected $_orientation = 'P'; // page orientation : Portrait ou Landscape
protected $_format = 'A4'; // page format : A4, A3, ...
Expand Down Expand Up @@ -199,13 +206,18 @@ public function __construct(
// load the Locale
Locale::load($this->_langue);

// create the myPdf object
$this->security = new Security();
$this->pdf = new MyPdf($orientation, 'mm', $format, $unicode, $encoding, false, $pdfa);

// init the CSS parsing object
$this->cssConverter = new CssConverter();
$textParser = new TextParser($encoding);
$this->parsingCss = new Parsing\Css($this->pdf, new TagParser($textParser), $this->cssConverter);

$this->parsingCss = new Parsing\Css(
$this->pdf,
new TagParser($textParser),
$this->cssConverter,
$this->security
);
$this->parsingCss->fontSet();
$this->_defList = array();

Expand Down Expand Up @@ -247,7 +259,7 @@ public function getVersionAsArray()
return array(
'major' => 5,
'minor' => 3,
'revision' => 0
'revision' => 1,
);
}

Expand Down Expand Up @@ -275,6 +287,19 @@ public function __clone()
$this->parsingCss->setPdfParent($this->pdf);
}

/**
* Use a specific security interface
* @param SecurityInterface $security
* @return $this
*/
public function setSecurityService(SecurityInterface $security): self
{
$this->security = $security;
$this->parsingCss->setSecurityService($security);

return $this;
}

/**
* Set the max number of lines for a sentence
*
Expand Down Expand Up @@ -1509,14 +1534,14 @@ protected function _makeBreakLine($h, $curr = null)
protected function _drawImage($src, $subLi = false)
{
// get the size of the image
// WARNING : if URL, "allow_url_fopen" must turned to "on" in php.ini
// WARNING : if URL, "allow_url_fopen" must turn to "on" in php.ini

if (strpos($src,'data:') === 0) {
$src = base64_decode( preg_replace('#^data:image/[^;]+;base64,#', '', $src) );
$infos = @getimagesizefromstring($src);
$src = "@{$src}";
} else {
$this->parsingCss->checkValidPath($src);
$this->security->checkValidPath((string) $src);
$infos = @getimagesize($src);
}

Expand Down Expand Up @@ -5806,13 +5831,15 @@ protected function _tag_open_CERT($param)
}

// set certificate file
$certificate = $param['src'];
$certificate = (string) $param['src'];
$this->security->checkValidPath($certificate);
if(!file_exists($certificate)) {
return true;
}

// Set private key
$privkey = $param['privkey'];
$privkey = (string) $param['privkey'];
$this->security->checkValidPath($privkey);
if(strlen($privkey)==0 || !file_exists($privkey)) {
$privkey = $certificate;
}
Expand Down
Loading

0 comments on commit f93e818

Please sign in to comment.