CVE-2017-20187: Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection') (CWE-74)
value: ** UNSUPPORTED WHEN ASSIGNED ** A vulnerability was found in Magnesium-PHP up to 0.3.0. It has been classified as problematic. Affected is the function formatEmailString of the file src/Magnesium/Message/Base.php. The manipulation of the argument email/name leads to injection. Upgrading to version 0.3.1 is able to address this issue. The patch is identified as 500d340e1f6421007413cc08a8383475221c2604. It is recommended to upgrade the affected component. VDB-244482 is the identifier assigned to this vulnerability. NOTE: This vulnerability only affects products that are no longer supported by the maintainer.
CWE description: The product constructs all or part of a command, data structure, or record using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify how it is parsed or interpreted when it is sent to a downstream component.
CVSS v3 base score: 9.8
Published: 2023-11-05T21:15Z
Repository: https://github.com/floriangaerber/Magnesium-PHP
Language: PHP
Files changed: src/Magnesium/Message/Base.php
Commit date: 2017-05-26 13:19:47 +0200
Commit message: Fix exploit of user's names/emails breaking "To"

Before being added to the "To" string, emails and names are cleared of <
> , and names are additionally cleared of @. See
Magnesium\Message\Base::removeToStringBreakingSymbols() DocBlock for
more details.

Diff: diff --git a/src/Magnesium/Message/Base.php b/src/Magnesium/Message/Base.php
index 8aa3b29..82f280f 100644
--- a/src/Magnesium/Message/Base.php
+++ b/src/Magnesium/Message/Base.php
@@ -225,12 +225,39 @@ class Base
      * @return string
      */
     protected function formatEmailString(string $email, string $name = null)
     {
         return $name
-        ? sprintf('%s <%s>', $name, $email)
-        : $email;
+        ? sprintf(
+            '%s <%s>',
+            $this->removeToStringBreakingSymbols($name, false),
+            $this->removeToStringBreakingSymbols($email, true))
+        : $this->removeToStringBreakingSymbols($email, true);
+    }
+
+    /**
+     *
+     * Should a user have chosen a name like "no1@example.com, Not Okay <no2@example.com>, Sherbert",
+     * Mailgun would accept the following to: "user@example.com, user2@example.com, no1@example.com, Not Okay <no2@example.com>, Sherbert <hello@example.com>"
+     * and would send it accordingly, which is unwanted behavior.
+     * Removing only "," breaks the To-string, sending the message to
+     * "user@example.com, user2@example.com, no1@example.com Not Okay <no2@example.com> Sherbert" hello@example.com,
+     * revealing email addresses of other users.
+     * Removing only either of "<,>" or "@," breaks the string the same way.
+     * Only removing "<>@," from the string prevents breaking (as far as I know).
+     *
+     * Also use an input validation library like Respect/Validation or find
+     * another way to prevent emails and names from containing "<>,"!
+     *
+     * @param string $string
+     * @param bool   $isEmail
+     *
+     * @return string
+     */
+    protected function removeToStringBreakingSymbols(string $string, bool $isEmail)
+    {
+        return str_replace($isEmail ? ['>', '<', ','] : ['>', '<', ',', '@'], '', $string);
     }
 
     /**
      * Sets the "Reply-To" address.
      *

Vulnerable code:         ? sprintf('%s <%s>', $name, $email)
        : $email;
Fixed code:         ? sprintf(
            '%s <%s>',
            $this->removeToStringBreakingSymbols($name, false),
            $this->removeToStringBreakingSymbols($email, true))
        : $this->removeToStringBreakingSymbols($email, true);
    }

    /**
     *
     * Should a user have chosen a name like "no1@example.com, Not Okay <no2@example.com>, Sherbert",
     * Mailgun would accept the following to: "user@example.com, user2@example.com, no1@example.com, Not Okay <no2@example.com>, Sherbert <hello@example.com>"
     * and would send it accordingly, which is unwanted behavior.
     * Removing only "," breaks the To-string, sending the message to
     * "user@example.com, user2@example.com, no1@example.com Not Okay <no2@example.com> Sherbert" hello@example.com,
     * revealing email addresses of other users.
     * Removing only either of "<,>" or "@," breaks the string the same way.
     * Only removing "<>@," from the string prevents breaking (as far as I know).
     *
     * Also use an input validation library like Respect/Validation or find
     * another way to prevent emails and names from containing "<>,"!
     *
     * @param string $string
     * @param bool   $isEmail
     *
     * @return string
     */
    protected function removeToStringBreakingSymbols(string $string, bool $isEmail)
    {
        return str_replace($isEmail ? ['>', '<', ','] : ['>', '<', ',', '@'], '', $string);