game engines/web frameworks: 27 CWE-407 defects + 3 CLEAN; 194 sites, 78 ecosystems

This commit is contained in:
russell@unturf.com 2026-03-27 14:14:49 -04:00
parent 547a9f5738
commit 4d3fcc8e73
76 changed files with 6216 additions and 17 deletions

View file

@ -0,0 +1,29 @@
From 2db25de Phoenix HEAD (2026-03-27)
Subject: [PATCH phoenix-0001] Fix CWE-407: store event_intercepts as MapSet for O(1) dispatch lookup
The fastlane tuple stores event_intercepts as a plain list (the result of
channel.__intercepts__(), which returns @phoenix_intercepts — a list).
In dispatch/3, `event in event_intercepts` is called once per subscriber per
broadcast. With N subscribers and K intercepted events this is O(N*K) list
scans. Storing as MapSet at subscribe time makes the per-dispatch check O(1).
No change to the `event in event_intercepts` expression is needed — Elixir's
`in` operator dispatches to Enumerable.member?/2, which for MapSet is O(1).
CWE-407: Algorithmic Complexity (Inefficient Algorithmic Complexity)
---
lib/phoenix/channel/server.ex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/phoenix/channel/server.ex b/lib/phoenix/channel/server.ex
index xxxxxxx..yyyyyyy 100644
--- a/lib/phoenix/channel/server.ex
+++ b/lib/phoenix/channel/server.ex
@@ -440,7 +440,7 @@ defmodule Phoenix.Channel.Server do
Process.monitor(transport_pid)
- fastlane = {:fastlane, transport_pid, serializer, channel.__intercepts__()}
+ fastlane = {:fastlane, transport_pid, serializer, MapSet.new(channel.__intercepts__())}
PubSub.subscribe(pubsub_server, topic, metadata: fastlane)
{:noreply, %{socket | joined: true}}

View file

@ -0,0 +1,46 @@
From 2db25de Phoenix HEAD (2026-03-27)
Subject: [PATCH phoenix-0002] Fix CWE-407: use MapSet for router scope pipes accumulation
The Scope struct's `pipes` field is a plain list. `pipe_through/2` does
`Enum.find(new_pipes, &(&1 in pipes))` — O(n*m) — for duplicate detection,
then `pipes ++ new_pipes` — O(n) — for accumulation.
Change the `pipes` field default to `MapSet.new()`. Use `MapSet.member?/2`
for the duplicate check and `Enum.reduce/MapSet.put` for accumulation.
This is compile-time only so the practical impact is small, but the pattern
is wrong and MapSet is the correct data structure.
CWE-407: Algorithmic Complexity (Inefficient Algorithmic Complexity)
---
lib/phoenix/router/scope.ex | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/phoenix/router/scope.ex b/lib/phoenix/router/scope.ex
index xxxxxxx..yyyyyyy 100644
--- a/lib/phoenix/router/scope.ex
+++ b/lib/phoenix/router/scope.ex
@@ -9,7 +9,7 @@ defmodule Phoenix.Router.Scope do
defstruct path: [],
alias: [],
as: [],
- pipes: [],
+ pipes: MapSet.new(),
hosts: [],
private: %{},
assigns: %{},
@@ -121,10 +121,12 @@ defmodule Phoenix.Router.Scope do
def pipe_through(module, new_pipes) do
new_pipes = List.wrap(new_pipes)
%{pipes: pipes} = top = get_top(module)
- if pipe = Enum.find(new_pipes, &(&1 in pipes)) do
+ if pipe = Enum.find(new_pipes, &MapSet.member?(pipes, &1)) do
raise ArgumentError,
"duplicate pipe_through for #{inspect(pipe)}. " <>
"A plug may only be used once inside a scoped pipe_through"
end
- put_top(module, %{top | pipes: pipes ++ new_pipes})
+ put_top(module, %{top | pipes: Enum.reduce(new_pipes, pipes, &MapSet.put(&2, &1))})
end