Low severity3.1OSV Advisory· Published Nov 6, 2024· Updated Apr 15, 2026
CVE-2024-50343
CVE-2024-50343
Description
symfony/validator is a module for the Symphony PHP framework which provides tools to validate values. It is possible to trick a Validator configured with a regular expression using the $ metacharacters, with an input ending with \n. Symfony as of versions 5.4.43, 6.4.11, and 7.1.4 now uses the D regex modifier to match the entire input. Users are advised to upgrade. There are no known workarounds for this vulnerability.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
symfony/symfonyPackagist | < 5.4.43 | 5.4.43 |
symfony/symfonyPackagist | >= 6.0.0, < 6.4.11 | 6.4.11 |
symfony/symfonyPackagist | >= 7.0.0, < 7.1.4 | 7.1.4 |
symfony/validatorPackagist | < 5.4.43 | 5.4.43 |
symfony/validatorPackagist | >= 6.0.0, < 6.4.11 | 6.4.11 |
symfony/validatorPackagist | >= 7.0.0, < 7.1.4 | 7.1.4 |
Affected products
1- Range: v2.0.0, v2.0.0-RC1, v2.0.0-RC2, …
Patches
44a4c52e875f5658b70d9fecbc2eaf9ad7fc47d1032bbead9[Validator] Add `D` regex modifier in relevant validators
13 files changed · +162 −36
src/Symfony/Component/Validator/Constraints/CardSchemeValidator.php+19 −19 modified@@ -29,65 +29,65 @@ class CardSchemeValidator extends ConstraintValidator protected $schemes = [ // American Express card numbers start with 34 or 37 and have 15 digits. CardScheme::AMEX => [ - '/^3[47][0-9]{13}$/', + '/^3[47][0-9]{13}$/D', ], // China UnionPay cards start with 62 and have between 16 and 19 digits. // Please note that these cards do not follow Luhn Algorithm as a checksum. CardScheme::CHINA_UNIONPAY => [ - '/^62[0-9]{14,17}$/', + '/^62[0-9]{14,17}$/D', ], // Diners Club card numbers begin with 300 through 305, 36 or 38. All have 14 digits. // There are Diners Club cards that begin with 5 and have 16 digits. // These are a joint venture between Diners Club and MasterCard, and should be processed like a MasterCard. CardScheme::DINERS => [ - '/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/', + '/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/D', ], // Discover card numbers begin with 6011, 622126 through 622925, 644 through 649 or 65. // All have 16 digits. CardScheme::DISCOVER => [ - '/^6011[0-9]{12}$/', - '/^64[4-9][0-9]{13}$/', - '/^65[0-9]{14}$/', - '/^622(12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|91[0-9]|92[0-5])[0-9]{10}$/', + '/^6011[0-9]{12}$/D', + '/^64[4-9][0-9]{13}$/D', + '/^65[0-9]{14}$/D', + '/^622(12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|91[0-9]|92[0-5])[0-9]{10}$/D', ], // InstaPayment cards begin with 637 through 639 and have 16 digits. CardScheme::INSTAPAYMENT => [ - '/^63[7-9][0-9]{13}$/', + '/^63[7-9][0-9]{13}$/D', ], // JCB cards beginning with 2131 or 1800 have 15 digits. // JCB cards beginning with 35 have 16 digits. CardScheme::JCB => [ - '/^(?:2131|1800|35[0-9]{3})[0-9]{11}$/', + '/^(?:2131|1800|35[0-9]{3})[0-9]{11}$/D', ], // Laser cards begin with either 6304, 6706, 6709 or 6771 and have between 16 and 19 digits. CardScheme::LASER => [ - '/^(6304|670[69]|6771)[0-9]{12,15}$/', + '/^(6304|670[69]|6771)[0-9]{12,15}$/D', ], // Maestro international cards begin with 675900..675999 and have between 12 and 19 digits. // Maestro UK cards begin with either 500000..509999 or 560000..699999 and have between 12 and 19 digits. CardScheme::MAESTRO => [ - '/^(6759[0-9]{2})[0-9]{6,13}$/', - '/^(50[0-9]{4})[0-9]{6,13}$/', - '/^5[6-9][0-9]{10,17}$/', - '/^6[0-9]{11,18}$/', + '/^(6759[0-9]{2})[0-9]{6,13}$/D', + '/^(50[0-9]{4})[0-9]{6,13}$/D', + '/^5[6-9][0-9]{10,17}$/D', + '/^6[0-9]{11,18}$/D', ], // All MasterCard numbers start with the numbers 51 through 55. All have 16 digits. // October 2016 MasterCard numbers can also start with 222100 through 272099. CardScheme::MASTERCARD => [ - '/^5[1-5][0-9]{14}$/', - '/^2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12})$/', + '/^5[1-5][0-9]{14}$/D', + '/^2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12})$/D', ], // Payment system MIR numbers start with 220, then 1 digit from 0 to 4, then between 12 and 15 digits CardScheme::MIR => [ - '/^220[0-4][0-9]{12,15}$/', + '/^220[0-4][0-9]{12,15}$/D', ], // All UATP card numbers start with a 1 and have a length of 15 digits. CardScheme::UATP => [ - '/^1[0-9]{14}$/', + '/^1[0-9]{14}$/D', ], // All Visa card numbers start with a 4 and have a length of 13, 16, or 19 digits. CardScheme::VISA => [ - '/^4([0-9]{12}|[0-9]{15}|[0-9]{18})$/', + '/^4([0-9]{12}|[0-9]{15}|[0-9]{18})$/D', ], ];
src/Symfony/Component/Validator/Constraints/CssColorValidator.php+12 −12 modified@@ -21,21 +21,21 @@ */ class CssColorValidator extends ConstraintValidator { - private const PATTERN_HEX_LONG = '/^#[0-9a-f]{6}$/i'; - private const PATTERN_HEX_LONG_WITH_ALPHA = '/^#[0-9a-f]{8}$/i'; - private const PATTERN_HEX_SHORT = '/^#[0-9a-f]{3}$/i'; - private const PATTERN_HEX_SHORT_WITH_ALPHA = '/^#[0-9a-f]{4}$/i'; + private const PATTERN_HEX_LONG = '/^#[0-9a-f]{6}$/iD'; + private const PATTERN_HEX_LONG_WITH_ALPHA = '/^#[0-9a-f]{8}$/iD'; + private const PATTERN_HEX_SHORT = '/^#[0-9a-f]{3}$/iD'; + private const PATTERN_HEX_SHORT_WITH_ALPHA = '/^#[0-9a-f]{4}$/iD'; // List comes from https://www.w3.org/wiki/CSS/Properties/color/keywords#Basic_Colors - private const PATTERN_BASIC_NAMED_COLORS = '/^(black|silver|gray|white|maroon|red|purple|fuchsia|green|lime|olive|yellow|navy|blue|teal|aqua)$/i'; + private const PATTERN_BASIC_NAMED_COLORS = '/^(black|silver|gray|white|maroon|red|purple|fuchsia|green|lime|olive|yellow|navy|blue|teal|aqua)$/iD'; // List comes from https://www.w3.org/wiki/CSS/Properties/color/keywords#Extended_colors - private const PATTERN_EXTENDED_NAMED_COLORS = '/^(aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen)$/i'; + private const PATTERN_EXTENDED_NAMED_COLORS = '/^(aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen)$/iD'; // List comes from https://drafts.csswg.org/css-color/#css-system-colors - private const PATTERN_SYSTEM_COLORS = '/^(Canvas|CanvasText|LinkText|VisitedText|ActiveText|ButtonFace|ButtonText|ButtonBorder|Field|FieldText|Highlight|HighlightText|SelectedItem|SelectedItemText|Mark|MarkText|GrayText)$/i'; - private const PATTERN_KEYWORDS = '/^(transparent|currentColor)$/i'; - private const PATTERN_RGB = '/^rgb\(\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d)\s*\)$/i'; - private const PATTERN_RGBA = '/^rgba\(\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|0?\.\d+|1(\.0)?)\s*\)$/i'; - private const PATTERN_HSL = '/^hsl\(\s*(0|360|35\d|3[0-4]\d|[12]\d\d|0?\d?\d),\s*(0|100|\d{1,2})%,\s*(0|100|\d{1,2})%\s*\)$/i'; - private const PATTERN_HSLA = '/^hsla\(\s*(0|360|35\d|3[0-4]\d|[12]\d\d|0?\d?\d),\s*(0|100|\d{1,2})%,\s*(0|100|\d{1,2})%,\s*(0|0?\.\d+|1(\.0)?)\s*\)$/i'; + private const PATTERN_SYSTEM_COLORS = '/^(Canvas|CanvasText|LinkText|VisitedText|ActiveText|ButtonFace|ButtonText|ButtonBorder|Field|FieldText|Highlight|HighlightText|SelectedItem|SelectedItemText|Mark|MarkText|GrayText)$/iD'; + private const PATTERN_KEYWORDS = '/^(transparent|currentColor)$/iD'; + private const PATTERN_RGB = '/^rgb\(\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d)\s*\)$/iD'; + private const PATTERN_RGBA = '/^rgba\(\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|255|25[0-4]|2[0-4]\d|1\d\d|0?\d?\d),\s*(0|0?\.\d+|1(\.0)?)\s*\)$/iD'; + private const PATTERN_HSL = '/^hsl\(\s*(0|360|35\d|3[0-4]\d|[12]\d\d|0?\d?\d),\s*(0|100|\d{1,2})%,\s*(0|100|\d{1,2})%\s*\)$/iD'; + private const PATTERN_HSLA = '/^hsla\(\s*(0|360|35\d|3[0-4]\d|[12]\d\d|0?\d?\d),\s*(0|100|\d{1,2})%,\s*(0|100|\d{1,2})%,\s*(0|0?\.\d+|1(\.0)?)\s*\)$/iD'; private const COLOR_PATTERNS = [ CssColor::HEX_LONG => self::PATTERN_HEX_LONG,
src/Symfony/Component/Validator/Constraints/DateValidator.php+1 −1 modified@@ -21,7 +21,7 @@ */ class DateValidator extends ConstraintValidator { - public const PATTERN = '/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/'; + public const PATTERN = '/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/D'; /** * Checks whether a date is valid.
src/Symfony/Component/Validator/Constraints/EmailValidator.php+2 −2 modified@@ -25,8 +25,8 @@ */ class EmailValidator extends ConstraintValidator { - private const PATTERN_HTML5 = '/^[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/'; - private const PATTERN_LOOSE = '/^.+\@\S+\.\S+$/'; + private const PATTERN_HTML5 = '/^[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/D'; + private const PATTERN_LOOSE = '/^.+\@\S+\.\S+$/D'; private const EMAIL_PATTERNS = [ Email::VALIDATION_MODE_LOOSE => self::PATTERN_LOOSE,
src/Symfony/Component/Validator/Constraints/TimeValidator.php+1 −1 modified@@ -21,7 +21,7 @@ */ class TimeValidator extends ConstraintValidator { - public const PATTERN = '/^(\d{2}):(\d{2}):(\d{2})$/'; + public const PATTERN = '/^(\d{2}):(\d{2}):(\d{2})$/D'; /** * Checks whether a time is valid.
src/Symfony/Component/Validator/Constraints/UrlValidator.php+1 −1 modified@@ -43,7 +43,7 @@ class UrlValidator extends ConstraintValidator (?:/ (?:[\pL\pN\pS\pM\-._\~!$&\'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path (?:\? (?:[\pL\pN\-._\~!$&\'\[\]()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a query (optional) (?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional) - $~ixu'; + $~ixuD'; /** * {@inheritdoc}
src/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php+30 −0 modified@@ -46,6 +46,36 @@ public function testValidNumbers($scheme, $number) $this->assertNoViolation(); } + /** + * @requires PHP 8 + * + * @dataProvider getValidNumbers + */ + public function testValidNumbersWithNewLine($scheme, $number) + { + $this->validator->validate($number."\n", new CardScheme(['schemes' => $scheme, 'message' => 'myMessage'])); + + $this->buildViolation('myMessage') + ->setParameter('{{ value }}', '"'.$number."\n\"") + ->setCode(CardScheme::INVALID_FORMAT_ERROR) + ->assertRaised(); + } + + /** + * @requires PHP < 8 + * + * @dataProvider getValidNumbers + */ + public function testValidNumbersWithNewLinePriorToPhp8($scheme, $number) + { + $this->validator->validate($number."\n", new CardScheme(['schemes' => $scheme, 'message' => 'myMessage'])); + + $this->buildViolation('myMessage') + ->setParameter('{{ value }}', '"'.$number."\n\"") + ->setCode(CardScheme::NOT_NUMERIC_ERROR) + ->assertRaised(); + } + public function testValidNumberWithOrderedArguments() { $this->validator->validate(
src/Symfony/Component/Validator/Tests/Constraints/CssColorValidatorTest.php+13 −0 modified@@ -52,6 +52,19 @@ public function testValidAnyColor($cssColor) $this->assertNoViolation(); } + /** + * @dataProvider getValidAnyColor + */ + public function testValidAnyColorWithNewLine($cssColor) + { + $this->validator->validate($cssColor."\n", new CssColor([], 'myMessage')); + + $this->buildViolation('myMessage') + ->setParameter('{{ value }}', '"'.$cssColor."\n\"") + ->setCode(CssColor::INVALID_FORMAT_ERROR) + ->assertRaised(); + } + public static function getValidAnyColor(): array { return [
src/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php+13 −0 modified@@ -53,6 +53,19 @@ public function testValidDates($date) $this->assertNoViolation(); } + /** + * @dataProvider getValidDates + */ + public function testValidDatesWithNewLine(string $date) + { + $this->validator->validate($date."\n", new Date(['message' => 'myMessage'])); + + $this->buildViolation('myMessage') + ->setParameter('{{ value }}', '"'.$date."\n\"") + ->setCode(Date::INVALID_FORMAT_ERROR) + ->assertRaised(); + } + public static function getValidDates() { return [
src/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php+13 −0 modified@@ -70,6 +70,19 @@ public function testValidEmails($email) $this->assertNoViolation(); } + /** + * @dataProvider getValidEmails + */ + public function testValidEmailsWithNewLine($email) + { + $this->validator->validate($email."\n", new Email()); + + $this->buildViolation('This value is not a valid email address.') + ->setParameter('{{ value }}', '"'.$email."\n\"") + ->setCode(Email::INVALID_FORMAT_ERROR) + ->assertRaised(); + } + public static function getValidEmails() { return [
src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php+13 −0 modified@@ -48,6 +48,19 @@ public function testValidIbans($iban) $this->assertNoViolation(); } + /** + * @dataProvider getValidIbans + */ + public function testValidIbansWithNewLine(string $iban) + { + $this->validator->validate($iban."\n", new Iban()); + + $this->buildViolation('This is not a valid International Bank Account Number (IBAN).') + ->setParameter('{{ value }}', '"'.$iban."\n\"") + ->setCode(Iban::INVALID_CHARACTERS_ERROR) + ->assertRaised(); + } + public static function getValidIbans() { return [
src/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php+13 −0 modified@@ -53,6 +53,19 @@ public function testValidTimes($time) $this->assertNoViolation(); } + /** + * @dataProvider getValidTimes + */ + public function testValidTimesWithNewLine(string $time) + { + $this->validator->validate($time."\n", new Time()); + + $this->buildViolation('This value is not a valid time.') + ->setParameter('{{ value }}', '"'.$time."\n".'"') + ->setCode(Time::INVALID_FORMAT_ERROR) + ->assertRaised(); + } + public static function getValidTimes() { return [
src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php+31 −0 modified@@ -60,6 +60,19 @@ public function testValidUrls($url) $this->assertNoViolation(); } + /** + * @dataProvider getValidUrls + */ + public function testValidUrlsWithNewLine($url) + { + $this->validator->validate($url."\n", new Url()); + + $this->buildViolation('This value is not a valid URL.') + ->setParameter('{{ value }}', '"'.$url."\n".'"') + ->setCode(Url::INVALID_URL_ERROR) + ->assertRaised(); + } + /** * @dataProvider getValidUrlsWithWhitespaces */ @@ -85,6 +98,24 @@ public function testValidRelativeUrl($url) $this->assertNoViolation(); } + /** + * @dataProvider getValidRelativeUrls + * @dataProvider getValidUrls + */ + public function testValidRelativeUrlWithNewLine(string $url) + { + $constraint = new Url([ + 'relativeProtocol' => true, + ]); + + $this->validator->validate($url."\n", $constraint); + + $this->buildViolation('This value is not a valid URL.') + ->setParameter('{{ value }}', '"'.$url."\n".'"') + ->setCode(Url::INVALID_URL_ERROR) + ->assertRaised(); + } + public static function getValidRelativeUrls() { return [
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-g3rh-rrhp-jhh9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-50343ghsaADVISORY
- github.com/FriendsOfPHP/security-advisories/blob/master/symfony/symfony/CVE-2024-50343.yamlghsaWEB
- github.com/FriendsOfPHP/security-advisories/blob/master/symfony/validator/CVE-2024-50343.yamlghsaWEB
- github.com/symfony/symfony/commit/7d1032bbead9a4229b32fa6ebca32681c80cb76fnvdWEB
- github.com/symfony/symfony/security/advisories/GHSA-g3rh-rrhp-jhh9nvdWEB
- lists.debian.org/debian-lts-announce/2025/05/msg00051.htmlnvdWEB
- symfony.com/cve-2024-50343ghsaWEB
News mentions
0No linked articles in our index yet.