During a penetration test for one of my clients, I managed to discover my first CVE in TCPDF a popular PHP library used to generate PDFs.
The library includes an Error
function designed to handle and display error messages when issues arise during PDF generation.
However, in versions prior to 6.8.0
this function does not adequately sanitize error messages before rendering them.
public function Error($msg) {
// unset all class variables
$this->_destroy(true);
if (defined('K_TCPDF_THROW_EXCEPTION_ERROR') AND !K_TCPDF_THROW_EXCEPTION_ERROR) {
die('TCPDF ERROR: '.$msg); // No sanitization
} else {
throw new Exception('TCPDF ERROR: '.$msg);
}
}
This is a serious problem because if a user is able to trigger an error containing their input it could lead to an XSS
vulnerability.
For example, suppose that an attacker is able to choose the font of their PDF.
If the attacker inserts something like <script>alert(1)</script>
as the font, the setFont function will throw an error (since the font does not exist) and will consequently call the Error function, which will insecurely display the error containing the name of the non-existent font.
Example of a vulnerable code:
require_once('tcpdf.php');
$font = $_GET['font'];
$pdf = new TCPDF();
$pdf->SetFont($font, '', 12);
$pdf->Output('output.pdf', 'I');
The vulnerability has been fixed in version 6.8.0 by sanitizing the data with the htmlspecialchars()
function.
public function Error($msg) {
// unset all class variables
$this->_destroy(true);
$msg = htmlspecialchars($msg, ENT_QUOTES, 'UTF-8');
if (defined('K_TCPDF_THROW_EXCEPTION_ERROR') AND !K_TCPDF_THROW_EXCEPTION_ERROR) {
die('TCPDF ERROR: '.$msg);
} else {
throw new Exception('TCPDF ERROR: '.$msg);
}
}