@@ -31,7 +31,7 @@ class PHPMailer
3131 * The PHPMailer Version number.
3232 * @var string
3333 */
34- public $ Version = '5.2.21 ' ;
34+ public $ Version = '5.2.22 ' ;
3535
3636 /**
3737 * Email priority.
@@ -2493,6 +2493,7 @@ public function textLine($value)
24932493
24942494 /**
24952495 * Add an attachment from a path on the filesystem.
2496+ * Never use a user-supplied path to a file!
24962497 * Returns false if the file could not be found or read.
24972498 * @param string $path Path to the attachment.
24982499 * @param string $name Overrides the attachment name.
@@ -3018,6 +3019,7 @@ public function addStringAttachment(
30183019 * displayed inline with the message, not just attached for download.
30193020 * This is used in HTML messages that embed the images
30203021 * the HTML refers to using the $cid value.
3022+ * Never use a user-supplied path to a file!
30213023 * @param string $path Path to the attachment.
30223024 * @param string $cid Content ID of the attachment; Use this to reference
30233025 * the content when using an embedded image in HTML.
@@ -3381,12 +3383,14 @@ public function getCustomHeaders()
33813383 * Create a message body from an HTML string.
33823384 * Automatically inlines images and creates a plain-text version by converting the HTML,
33833385 * overwriting any existing values in Body and AltBody.
3384- * $basedir is used when handling relative image paths, e.g. <img src="images/a.png">
3386+ * Do not source $message content from user input!
3387+ * $basedir is prepended when handling relative URLs, e.g. <img src="/images/a.png"> and must not be empty
33853388 * will look for an image file in $basedir/images/a.png and convert it to inline.
3386- * If you don't want to apply these transformations to your HTML, just set Body and AltBody yourself.
3389+ * If you don't provide a $basedir, relative paths will be left untouched (and thus probably break in email)
3390+ * If you don't want to apply these transformations to your HTML, just set Body and AltBody directly.
33873391 * @access public
33883392 * @param string $message HTML message string
3389- * @param string $basedir base directory for relative paths to images
3393+ * @param string $basedir Absolute path to a base directory to prepend to relative paths to images
33903394 * @param boolean|callable $advanced Whether to use the internal HTML to text converter
33913395 * or your own custom converter @see PHPMailer::html2text()
33923396 * @return string $message The transformed message Body
@@ -3395,6 +3399,10 @@ public function msgHTML($message, $basedir = '', $advanced = false)
33953399 {
33963400 preg_match_all ('/(src|background)=[" \'](.*)[" \']/Ui ' , $ message , $ images );
33973401 if (array_key_exists (2 , $ images )) {
3402+ if (strlen ($ basedir ) > 1 && substr ($ basedir , -1 ) != '/ ' ) {
3403+ // Ensure $basedir has a trailing /
3404+ $ basedir .= '/ ' ;
3405+ }
33983406 foreach ($ images [2 ] as $ imgindex => $ url ) {
33993407 // Convert data URIs into embedded images
34003408 if (preg_match ('#^data:(image[^;,]*)(;base64)?,# ' , $ url , $ match )) {
@@ -3412,18 +3420,24 @@ public function msgHTML($message, $basedir = '', $advanced = false)
34123420 $ message
34133421 );
34143422 }
3415- } elseif (substr ($ url , 0 , 4 ) !== 'cid: ' && !preg_match ('#^[a-z][a-z0-9+.-]*://#i ' , $ url )) {
3416- // Do not change urls for absolute images (thanks to corvuscorax)
3423+ continue ;
3424+ }
3425+ if (
3426+ // Only process relative URLs if a basedir is provided (i.e. no absolute local paths)
3427+ !empty ($ basedir )
3428+ // Ignore URLs containing parent dir traversal (..)
3429+ && (strpos ($ url , '.. ' ) === false )
34173430 // Do not change urls that are already inline images
3431+ && substr ($ url , 0 , 4 ) !== 'cid: '
3432+ // Do not change absolute URLs, including anonymous protocol
3433+ && !preg_match ('#^[a-z][a-z0-9+.-]*:?//#i ' , $ url )
3434+ ) {
34183435 $ filename = basename ($ url );
34193436 $ directory = dirname ($ url );
34203437 if ($ directory == '. ' ) {
34213438 $ directory = '' ;
34223439 }
34233440 $ cid = md5 ($ url ) . '@phpmailer.0 ' ; // RFC2392 S 2
3424- if (strlen ($ basedir ) > 1 && substr ($ basedir , -1 ) != '/ ' ) {
3425- $ basedir .= '/ ' ;
3426- }
34273441 if (strlen ($ directory ) > 1 && substr ($ directory , -1 ) != '/ ' ) {
34283442 $ directory .= '/ ' ;
34293443 }
0 commit comments