{"items":[{"id":"NVI-00004826","kind":"vulnerability","title":"Sylius has a Promotion Usage Limit Bypass via Race Condition","revision":3,"unknowns":["Customer inventory, deployment, reachability and exploitation have not been inspected.","NVD lastModified does not establish freshness of every associated CPE record."],"lifecycle":"active","identifiers":["GHSA-7mp4-25j8-hp5q","CVE-2026-31824"],"plain_summary":"OSV carries this publisher advisory for sylius/sylius, sylius/sylius, sylius/sylius, sylius/sylius, sylius/sylius. This is an aggregated source copy; consult the original publisher and compare update dates.","review_status":"source_listed","control_topics":[],"public_actions":[{"summary":"The original advisory lists fixed boundaries 1.9.12 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.10.16 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.11.17 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.12.23 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.13.15 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.14.18 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.0.16 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.1.12 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.2.3 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"Identify the exact component and deployed version, examine the linked publisher’s conditions, and retain evidence of any mitigation.","source_ids":["sr-253a76342883bb84c3723dc01ac04a45"],"action_type":"investigate","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null}],"schema_version":"1.1.0","source_metrics":[{"kind":"CVSS","as_of":"2026-06-17T10:34:31.610Z","value":"8.2 HIGH (3.1)","meaning":"security-advisories@github.com severity; no combined Null risk score.","source_id":"sr-3250d786fb149e4196733a121f93089a"},{"kind":"CVSS","as_of":"2026-06-17T10:34:31.610Z","value":"5.9 MEDIUM (3.1)","meaning":"nvd@nist.gov severity; no combined Null risk score.","source_id":"sr-3250d786fb149e4196733a121f93089a"},{"kind":"EPSS","as_of":"2026-11-03T12:00:27.000Z","value":"0.190%","meaning":"FIRST EPSS model v2026.06.15; exploitation probability over 30 days, percentile 0.0872. Missing scores are unknown.","source_id":"sr-253a76342883bb84c3723dc01ac04a45"}],"why_it_matters":"Published affected context helps an owner decide what evidence to gather. This report has not examined your application.","related_sources":[{"id":"sr-74f6db5565a1c1ed250c5ccea17b9285","url":"https://github.com/advisories/GHSA-7mp4-25j8-hp5q","basis":"vendor_advisory","notes":"GitHub-origin advisory, CC-BY-4.0; OSV is an aggregate copy, not independent corroboration.","title":"GHSA-7mp4-25j8-hp5q","publisher":"GitHub Advisory Database via OSV","observed_at":"2026-10-31T21:41:59.952Z"},{"id":"sr-3250d786fb149e4196733a121f93089a","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-31824","basis":"official_catalog","notes":"This product uses data from the NVD API but is not endorsed or certified by the NVD.","title":"CVE-2026-31824","publisher":"NIST National Vulnerability Database","observed_at":"2026-11-01T01:40:56.268Z"},{"id":"sr-253a76342883bb84c3723dc01ac04a45","url":"https://www.first.org/epss/data.html","basis":"official_catalog","notes":"FIRST EPSS; probability of exploitation in the next 30 days, not local compromise. Dataset date/model retained; FIRST services terms apply.","title":"CVE-2026-31824","publisher":"FIRST EPSS","observed_at":"2026-11-03T17:44:07.782Z"}],"affected_context":[{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 0; fixed 1.9.12"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.10.0; fixed 1.10.16"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.11.0; fixed 1.11.17"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.12.0; fixed 1.12.23"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.13.0; fixed 1.13.15"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.14.0; fixed 1.14.18"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 2.0.0; fixed 2.0.16"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 2.1.0; fixed 2.1.12"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 2.2.0; fixed 2.2.3"]}],"null_published_at":"2026-11-08T19:53:33.553Z","source_updated_at":"2026-03-13T10:56:24.798Z","source_disclosed_at":"2026-03-11T00:13:29.000Z","is_synthetic_fixture":false,"null_last_reviewed_at":null,"public_change_summary":"Dated EPSS estimate updated; this is not a new disclosure or proof of exploitation.","null_first_observed_at":"2026-10-31T21:41:59.952Z"},{"id":"NVI-00004826","kind":"vulnerability","title":"Sylius has a Promotion Usage Limit Bypass via Race Condition","revision":2,"unknowns":["Customer inventory, deployment, reachability and exploitation have not been inspected.","NVD lastModified does not establish freshness of every associated CPE record."],"lifecycle":"active","identifiers":["GHSA-7mp4-25j8-hp5q","CVE-2026-31824"],"plain_summary":"OSV carries this publisher advisory for sylius/sylius, sylius/sylius, sylius/sylius, sylius/sylius, sylius/sylius. This is an aggregated source copy; consult the original publisher and compare update dates.","review_status":"source_listed","control_topics":[],"public_actions":[{"summary":"The original advisory lists fixed boundaries 1.9.12 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.10.16 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.11.17 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.12.23 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.13.15 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.14.18 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.0.16 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.1.12 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.2.3 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"Identify the exact component and deployed version, examine the linked publisher’s conditions, and retain evidence of any mitigation.","source_ids":["sr-3250d786fb149e4196733a121f93089a"],"action_type":"investigate","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null}],"schema_version":"1.1.0","source_metrics":[{"kind":"CVSS","as_of":"2026-06-17T10:34:31.610Z","value":"8.2 HIGH (3.1)","meaning":"security-advisories@github.com severity; no combined Null risk score.","source_id":"sr-3250d786fb149e4196733a121f93089a"},{"kind":"CVSS","as_of":"2026-06-17T10:34:31.610Z","value":"5.9 MEDIUM (3.1)","meaning":"nvd@nist.gov severity; no combined Null risk score.","source_id":"sr-3250d786fb149e4196733a121f93089a"}],"why_it_matters":"Published affected context helps an owner decide what evidence to gather. This report has not examined your application.","related_sources":[{"id":"sr-74f6db5565a1c1ed250c5ccea17b9285","url":"https://github.com/advisories/GHSA-7mp4-25j8-hp5q","basis":"vendor_advisory","notes":"GitHub-origin advisory, CC-BY-4.0; OSV is an aggregate copy, not independent corroboration.","title":"GHSA-7mp4-25j8-hp5q","publisher":"GitHub Advisory Database via OSV","observed_at":"2026-10-31T21:41:59.952Z"},{"id":"sr-3250d786fb149e4196733a121f93089a","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-31824","basis":"official_catalog","notes":"This product uses data from the NVD API but is not endorsed or certified by the NVD.","title":"CVE-2026-31824","publisher":"NIST National Vulnerability Database","observed_at":"2026-11-01T01:40:56.268Z"}],"affected_context":[{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 0; fixed 1.9.12"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.10.0; fixed 1.10.16"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.11.0; fixed 1.11.17"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.12.0; fixed 1.12.23"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.13.0; fixed 1.13.15"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.14.0; fixed 1.14.18"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 2.0.0; fixed 2.0.16"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 2.1.0; fixed 2.1.12"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 2.2.0; fixed 2.2.3"]}],"null_published_at":"2026-11-01T14:34:07.617Z","source_updated_at":"2026-03-13T10:56:24.798Z","source_disclosed_at":"2026-03-11T00:13:29.000Z","is_synthetic_fixture":false,"null_last_reviewed_at":null,"public_change_summary":"Source facts changed; compare the preserved prior revision.","null_first_observed_at":"2026-10-31T21:41:59.952Z"},{"id":"NVI-00004826","kind":"vulnerability","title":"Sylius has a Promotion Usage Limit Bypass via Race Condition","revision":1,"unknowns":["Customer inventory, deployment, reachability and exploitation have not been inspected."],"lifecycle":"active","identifiers":["GHSA-7mp4-25j8-hp5q","CVE-2026-31824"],"plain_summary":"OSV carries this publisher advisory for sylius/sylius, sylius/sylius, sylius/sylius, sylius/sylius, sylius/sylius. This is an aggregated source copy; consult the original publisher and compare update dates.","review_status":"source_listed","control_topics":[],"public_actions":[{"summary":"The original advisory lists fixed boundaries 1.9.12 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.10.16 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.11.17 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.12.23 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.13.15 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 1.14.18 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.0.16 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.1.12 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null},{"summary":"The original advisory lists fixed boundaries 2.2.3 for sylius/sylius. Confirm the publisher’s latest guidance.","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"action_type":"vendor_patch","limitations":"Confirm current vendor support, compatibility and deployment evidence. This report has not tested a fix in your system.","current_supported_target":null}],"schema_version":"1.1.0","source_metrics":[],"why_it_matters":"Published affected context helps an owner decide what evidence to gather. This report has not examined your application.","related_sources":[{"id":"sr-74f6db5565a1c1ed250c5ccea17b9285","url":"https://github.com/advisories/GHSA-7mp4-25j8-hp5q","basis":"vendor_advisory","notes":"GitHub-origin advisory, CC-BY-4.0; OSV is an aggregate copy, not independent corroboration.","title":"GHSA-7mp4-25j8-hp5q","publisher":"GitHub Advisory Database via OSV","observed_at":"2026-10-31T21:41:59.952Z"}],"affected_context":[{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 0; fixed 1.9.12"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.10.0; fixed 1.10.16"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.11.0; fixed 1.11.17"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.12.0; fixed 1.12.23"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.13.0; fixed 1.13.15"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 1.14.0; fixed 1.14.18"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 2.0.0; fixed 2.0.16"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 2.1.0; fixed 2.1.12"]},{"certainty":"source_listed","source_ids":["sr-74f6db5565a1c1ed250c5ccea17b9285"],"technology":"sylius/sylius","known_exclusions":[],"conditions_summary":"### Impact\nA Time-of-Check To Time-of-Use (TOCTOU) race condition was discovered in the promotion usage limit enforcement. The same class of vulnerability affects three independent limits:\n\n1. **Promotion usage limit** - the global `used` counter on `Promotion` entities\n2. **Coupon usage limit** - the global `used` counter on `PromotionCoupon` entities\n3. **Coupon per-customer usage limit** - the per-customer redemption count on `PromotionCoupon` entities\n\nIn all three cases, the eligibility check reads the `used` counter (or order count) from an in-memory Doctrine entity during validation, while the actual usage increment in `OrderPromotionsUsageModifier` happens later during order completion — with no database-level locking or atomic operations between the two phases.\n\nBecause Doctrine flushes an absolute value (`SET used = 1`) rather than an atomic increment (`SET used = used + 1`), and because the affected entities lack optimistic locking, concurrent requests all read the same stale usage counts and pass the eligibility checks simultaneously.\n\nAn attacker can exploit this by preparing multiple carts with the same limited-use promotion or coupon and firing simultaneous `PATCH /a","public_affected_ranges":["ECOSYSTEM: introduced 2.2.0; fixed 2.2.3"]}],"null_published_at":"2026-10-31T22:12:57.144Z","source_updated_at":"2026-03-13T10:56:24.798Z","source_disclosed_at":"2026-03-11T00:13:29.000Z","is_synthetic_fixture":false,"null_last_reviewed_at":null,"public_change_summary":"First indexed by Null; source disclosure date is shown separately.","null_first_observed_at":"2026-10-31T21:41:59.952Z"}],"next_cursor":null,"snapshot_revision":"42594"}