{"id":"CVE-2026-53423","aliases":["EEF-CVE-2026-53423","EUVD-2026-36235","GHSA-43hj-fxwj-49qw"],"status":"published","title":"Unauthenticated denial-of-service via BEAM atom table exhaustion in membrane_mp4_plugin","description":"Allocation of Resources Without Limits or Throttling vulnerability in membraneframework membrane_mp4_plugin allows unauthenticated denial-of-service via BEAM atom table exhaustion.\n\nThe MP4 box header parser converts each 4-byte box name to an atom using String.to_atom/1 without validation. 'Elixir.Membrane.MP4.Container.Header':parse_box_name/1 in lib/membrane_mp4/container/header.ex interns every box name encountered while 'Elixir.Membrane.MP4.Container.Header':parse/1 walks the input. BEAM atoms are never garbage-collected, so each unique attacker-controlled 4-byte name is a permanent allocation. A crafted MP4 of approximately 8 MB containing roughly 1.1 million boxes with distinct non-standard names exhausts the atom table (default ceiling around 1,048,576 atoms), aborting the entire BEAM node and taking down all applications running on it.\n\nThis issue affects membrane_mp4_plugin from 0.3.0 before 0.36.7.","severity":{"version":"4.0","score":5.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00255,"percentile":0.17204,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-770"],"published":"2026-06-11T10:44:51Z","modified":"2026-10-28T02:30:56Z","fixes":[{"ecosystem":"Hex","package":"membrane_mp4_plugin","fixed_in":["0.36.7"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Hex","package":"membrane_mp4_plugin","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.36.7"}]}]},{"source":"osv","ecosystem":"Hex","package":"membrane_mp4_plugin","ranges":[{"type":"SEMVER","events":[{"introduced":"0.3.0"},{"fixed":"0.36.7"}]}],"versions":["0.10.0","0.11.0","0.12.0","0.12.1","0.13.0","0.14.0","0.15.0","0.16.0","0.16.1","0.16.2","0.17.0","0.18.0","0.18.1","0.19.0","0.20.0","0.21.0","0.22.0","0.22.1","0.22.2","0.22.3","0.23.0","0.24.0","0.24.1","0.25.0","0.26.0","0.26.1","0.27.0","0.28.0","0.28.1","0.29.0","0.29.1","0.3.0","0.30.0","0.30.1","0.30.2","0.31.0","0.32.0","0.33.0","0.33.1","0.34.0","0.34.1","0.34.2","0.35.0","0.35.1","0.35.2","0.35.3","0.36.0","0.36.1","0.36.2","0.36.3","0.36.4","0.36.5","0.36.6","0.4.0","0.5.0","0.6.0","0.7.0","0.8.0","0.9.0"]},{"source":"osv","ecosystem":"Hex","package":"membrane_mp4_plugin","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.36.7"}]}],"versions":["0.10.0","0.11.0","0.12.0","0.12.1","0.13.0","0.14.0","0.15.0","0.16.0","0.16.1","0.16.2","0.17.0","0.18.0","0.18.1","0.19.0","0.20.0","0.21.0","0.22.0","0.22.1","0.22.2","0.22.3","0.23.0","0.24.0","0.24.1","0.25.0","0.26.0","0.26.1","0.27.0","0.28.0","0.28.1","0.29.0","0.29.1","0.3.0","0.30.0","0.30.1","0.30.2","0.31.0","0.32.0","0.33.0","0.33.1","0.34.0","0.34.1","0.34.2","0.35.0","0.35.1","0.35.2","0.35.3","0.36.0","0.36.1","0.36.2","0.36.3","0.36.4","0.36.5","0.36.6","0.4.0","0.5.0","0.6.0","0.7.0","0.8.0","0.9.0"]}],"products":[{"vendor":"membraneframework","product":"membrane_mp4_plugin"}],"references":[{"url":"https://github.com/membraneframework/membrane_mp4_plugin/security/advisories/GHSA-43hj-fxwj-49qw","tags":["vendor-advisory","related","exploit","advisory","web"]},{"url":"https://cna.erlef.org/cves/CVE-2026-53423.html","tags":["related","web"]},{"url":"https://osv.dev/vulnerability/EEF-CVE-2026-53423","tags":["related","web"]},{"url":"https://github.com/membraneframework/membrane_mp4_plugin/commit/56373d1ddc86968e55fbde795c14eeba24357b57","tags":["patch","fix","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-53423","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-43hj-fxwj-49qw"},{"url":"https://github.com","tags":["web"]},{"url":"https://repo.hex.pm","tags":["web"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/53xxx/CVE-2026-53423.json","tags":["advisory"]},{"url":"https://github.com/membraneframework/membrane_mp4_plugin","tags":["package"]},{"url":"https://hex.pm/packages/membrane_mp4_plugin","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-53423","title":"Unauthenticated denial-of-service via BEAM atom table exhaustion in membrane_mp4_plugin","description":"Allocation of Resources Without Limits or Throttling vulnerability in membraneframework membrane_mp4_plugin allows unauthenticated denial-of-service via BEAM atom table exhaustion.\n\nThe MP4 box header parser converts each 4-byte box name to an atom using String.to_atom/1 without validation. 'Elixir.Membrane.MP4.Container.Header':parse_box_name/1 in lib/membrane_mp4/container/header.ex interns every box name encountered while 'Elixir.Membrane.MP4.Container.Header':parse/1 walks the input. BEAM atoms are never garbage-collected, so each unique attacker-controlled 4-byte name is a permanent allocation. A crafted MP4 of approximately 8 MB containing roughly 1.1 million boxes with distinct non-standard names exhausts the atom table (default ceiling around 1,048,576 atoms), aborting the entire BEAM node and taking down all applications running on it.\n\nThis issue affects membrane_mp4_plugin from 0.3.0 before 0.36.7.","status":"published","published":"2026-06-11T10:44:51.528Z","modified":"2026-06-12T04:45:33.275Z","cvss":[{"version":"4.0","score":5.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium","assessor":"cna"}],"cwes":["CWE-770"],"updated_at":"2026-11-02T14:20:00.11477Z"}],"euvd":[{"id":"EUVD-2026-36235","description":"Allocation of Resources Without Limits or Throttling vulnerability in membraneframework membrane_mp4_plugin allows unauthenticated denial-of-service via BEAM atom table exhaustion.\n\nThe MP4 box header parser converts each 4-byte box name to an atom using String.to_atom/1 without validation. 'Elixir.Membrane.MP4.Container.Header':parse_box_name/1 in lib/membrane_mp4/container/header.ex interns every box name encountered while 'Elixir.Membrane.MP4.Container.Header':parse/1 walks the input. BEAM atoms are never garbage-collected, so each unique attacker-controlled 4-byte name is a permanent allocation. A crafted MP4 of approximately 8 MB containing roughly 1.1 million boxes with distinct non-standard names exhausts the atom table (default ceiling around 1,048,576 atoms), aborting the entire BEAM node and taking down all applications running on it.\n\nThis issue affects membrane_mp4_plugin from 0.3.0 before 0.36.7.","status":"published","published":"2026-06-11T10:44:51Z","modified":"2026-06-12T04:45:33Z","cvss":[{"version":"4.0","score":5.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"updated_at":"2026-11-02T18:20:43.577088Z"}],"ghsa":[{"id":"GHSA-43hj-fxwj-49qw","title":"membrane_mp4_plugin has an unauthenticated denial-of-service via BEAM atom table exhaustion","description":"### Summary\n\n`membrane_mp4_plugin` interns every 4-byte MP4 box name as a BEAM atom while parsing container headers, with no validation against an allow-list. Any code path that calls `Membrane.MP4.Container.parse/1` (or the bang variant) on attacker-controlled MP4 bytes can be made to exhaust the BEAM atom table, which is uncapped at the source but bounded by the runtime ceiling (around 1,048,576 atoms) and never garbage-collected. Once the ceiling is hit, the entire BEAM node aborts.\n\n### Details\n\nThe MP4 container parser walks the input stream box-by-box. For each box, `Membrane.MP4.Container.Header.parse/1` in `lib/membrane_mp4/container/header.ex` extracts the 4-byte name field and delegates to the private helper `parse_box_name/1`, which trims trailing spaces and passes the bytes through `String.to_atom/1`. Because `String.to_atom/1` creates a new atom unconditionally, every distinct attacker-chosen 4-byte sequence becomes a permanent allocation in the global atom table. Atoms are not subject to garbage collection, so unique names accumulate for the lifetime of the node.\n\nThe fix replaces the unsafe interning with `String.to_existing_atom/1` and treats unknown names as the `:unknown` atom downstream (with related plumbing in `parse_helper.ex`, `serialize_helper.ex`, and the ISOM/CMAF demuxer engines so the new error variant flows through cleanly).\n\n### PoC\n\n1. Generate an MP4-shaped payload of roughly 1.1 million minimal box headers, each 8 bytes long (4-byte size of 8, followed by a unique 4-byte ASCII name produced by enumerating combinations in the printable range).\n2. Concatenate them into a single binary (~8 MB total).\n3. Call `Membrane.MP4.Container.parse!/1` on the binary inside any process running under the target BEAM node.\n4. The node aborts once the atom table ceiling is reached.\n\n### Impact\n\nAn attacker who can get a single crafted MP4 file in front of any system that demuxes user-supplied media with `membrane_mp4_plugin` can crash the entire BEAM node hosting that pipeline, taking down every Erlang/Elixir application sharing the runtime. No authentication, network position, or user interaction is required beyond delivering the file to whatever processing path eventually calls the parser.\n\n### References\n\n* Introduction commit: https://github.com/membraneframework/membrane_mp4_plugin/commit/ae4bf04c393aa1562f3df3d33e20bc5cb8130de2\n* Patch commit: https://github.com/membraneframework/membrane_mp4_plugin/commit/56373d1ddc86968e55fbde795c14eeba24357b57","status":"published","published":"2026-08-18T20:16:29Z","modified":"2026-08-18T20:16:30Z","cvss":[{"version":"4.0","score":5.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-770"],"updated_at":"2026-11-02T14:41:03.602876Z"}],"nvd":[{"id":"CVE-2026-53423","description":"Allocation of Resources Without Limits or Throttling vulnerability in membraneframework membrane_mp4_plugin allows unauthenticated denial-of-service via BEAM atom table exhaustion.\n\nThe MP4 box header parser converts each 4-byte box name to an atom using String.to_atom/1 without validation. 'Elixir.Membrane.MP4.Container.Header':parse_box_name/1 in lib/membrane_mp4/container/header.ex interns every box name encountered while 'Elixir.Membrane.MP4.Container.Header':parse/1 walks the input. BEAM atoms are never garbage-collected, so each unique attacker-controlled 4-byte name is a permanent allocation. A crafted MP4 of approximately 8 MB containing roughly 1.1 million boxes with distinct non-standard names exhausts the atom table (default ceiling around 1,048,576 atoms), aborting the entire BEAM node and taking down all applications running on it.\n\nThis issue affects membrane_mp4_plugin from 0.3.0 before 0.36.7.","status":"published","published":"2026-06-11T12:16:31.81Z","modified":"2026-10-25T23:10:00.167Z","cvss":[{"version":"4.0","score":5.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"medium","assessor":"secondary"}],"cwes":["CWE-770"],"updated_at":"2026-11-02T14:12:23.485267Z"}],"osv":[{"id":"CVE-2026-53423","title":"Unauthenticated denial-of-service via BEAM atom table exhaustion in membrane_mp4_plugin","description":"Allocation of Resources Without Limits or Throttling vulnerability in membraneframework membrane_mp4_plugin allows unauthenticated denial-of-service via BEAM atom table exhaustion.\n\nThe MP4 box header parser converts each 4-byte box name to an atom using String.to_atom/1 without validation. 'Elixir.Membrane.MP4.Container.Header':parse_box_name/1 in lib/membrane_mp4/container/header.ex interns every box name encountered while 'Elixir.Membrane.MP4.Container.Header':parse/1 walks the input. BEAM atoms are never garbage-collected, so each unique attacker-controlled 4-byte name is a permanent allocation. A crafted MP4 of approximately 8 MB containing roughly 1.1 million boxes with distinct non-standard names exhausts the atom table (default ceiling around 1,048,576 atoms), aborting the entire BEAM node and taking down all applications running on it.\n\nThis issue affects membrane_mp4_plugin from 0.3.0 before 0.36.7.","status":"published","published":"2026-06-11T10:44:51.528Z","modified":"2026-10-28T02:30:56.012863444Z","cvss":[{"version":"4.0","score":5.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-770"],"updated_at":"2026-11-02T15:45:07.787185Z"},{"id":"EEF-CVE-2026-53423","title":"Unauthenticated denial-of-service via BEAM atom table exhaustion in membrane_mp4_plugin","description":"## Summary\n\nAllocation of Resources Without Limits or Throttling vulnerability in membraneframework membrane\\_mp4\\_plugin allows unauthenticated denial-of-service via BEAM atom table exhaustion.\n\nThe MP4 box header parser converts each 4-byte box name to an atom using String.to\\_atom/1 without validation. 'Elixir.Membrane.MP4.Container.Header':parse\\_box\\_name/1 in lib/membrane\\_mp4/container/header.ex interns every box name encountered while 'Elixir.Membrane.MP4.Container.Header':parse/1 walks the input. BEAM atoms are never garbage-collected, so each unique attacker-controlled 4-byte name is a permanent allocation. A crafted MP4 of approximately 8 MB containing roughly 1.1 million boxes with distinct non-standard names exhausts the atom table (default ceiling around 1,048,576 atoms), aborting the entire BEAM node and taking down all applications running on it.\n\nThis issue affects membrane\\_mp4\\_plugin from 0.3.0 before 0.36.7.","status":"published","published":"2026-06-11T10:44:51.528Z","modified":"2026-07-30T18:22:08.190143Z","cvss":[{"version":"4.0","score":5.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-770"],"updated_at":"2026-11-02T15:46:33.520522Z"},{"id":"GHSA-43hj-fxwj-49qw","title":"membrane_mp4_plugin has an unauthenticated denial-of-service via BEAM atom table exhaustion","description":"### Summary\n\n`membrane_mp4_plugin` interns every 4-byte MP4 box name as a BEAM atom while parsing container headers, with no validation against an allow-list. Any code path that calls `Membrane.MP4.Container.parse/1` (or the bang variant) on attacker-controlled MP4 bytes can be made to exhaust the BEAM atom table, which is uncapped at the source but bounded by the runtime ceiling (around 1,048,576 atoms) and never garbage-collected. Once the ceiling is hit, the entire BEAM node aborts.\n\n### Details\n\nThe MP4 container parser walks the input stream box-by-box. For each box, `Membrane.MP4.Container.Header.parse/1` in `lib/membrane_mp4/container/header.ex` extracts the 4-byte name field and delegates to the private helper `parse_box_name/1`, which trims trailing spaces and passes the bytes through `String.to_atom/1`. Because `String.to_atom/1` creates a new atom unconditionally, every distinct attacker-chosen 4-byte sequence becomes a permanent allocation in the global atom table. Atoms are not subject to garbage collection, so unique names accumulate for the lifetime of the node.\n\nThe fix replaces the unsafe interning with `String.to_existing_atom/1` and treats unknown names as the `:unknown` atom downstream (with related plumbing in `parse_helper.ex`, `serialize_helper.ex`, and the ISOM/CMAF demuxer engines so the new error variant flows through cleanly).\n\n### PoC\n\n1. Generate an MP4-shaped payload of roughly 1.1 million minimal box headers, each 8 bytes long (4-byte size of 8, followed by a unique 4-byte ASCII name produced by enumerating combinations in the printable range).\n2. Concatenate them into a single binary (~8 MB total).\n3. Call `Membrane.MP4.Container.parse!/1` on the binary inside any process running under the target BEAM node.\n4. The node aborts once the atom table ceiling is reached.\n\n### Impact\n\nAn attacker who can get a single crafted MP4 file in front of any system that demuxes user-supplied media with `membrane_mp4_plugin` can crash the entire BEAM node hosting that pipeline, taking down every Erlang/Elixir application sharing the runtime. No authentication, network position, or user interaction is required beyond delivering the file to whatever processing path eventually calls the parser.\n\n### References\n\n* Introduction commit: https://github.com/membraneframework/membrane_mp4_plugin/commit/ae4bf04c393aa1562f3df3d33e20bc5cb8130de2\n* Patch commit: https://github.com/membraneframework/membrane_mp4_plugin/commit/56373d1ddc86968e55fbde795c14eeba24357b57","status":"published","published":"2026-08-18T20:16:29Z","modified":"2026-08-18T20:30:07.373842846Z","cvss":[{"version":"4.0","score":5.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-770"],"updated_at":"2026-11-02T15:46:36.434231Z"}]}}
