Skip to content

Commit 026105e

Browse files
committed
Prevent String.to_atom/1 calls
1 parent 41127fa commit 026105e

File tree

4 files changed

+31
-4
lines changed

4 files changed

+31
-4
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## v0.4.4 (TBA)
4+
5+
* [`PowAssent.Plug`] Now uses `String.to_existing_atom/1` in `PowAssent.Plug.providers_for_current_user/1`
6+
* [`PowAssent.Plug`] Fixed security issue by removing `String.to_atom/1` for user provided binary in `PowAssent.Plug.authorize_url/3` and `PowAssent.Plug.callback/4`
7+
* [`PowAssent.Config`] `PowAssent.Config.get_provider_config/2` now accepts binary provider
8+
39
## v0.4.3 (2019-11-20)
410

511
* Removed `:phoenix_html` dependency requirement

lib/pow_assent/config.ex

+14-2
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,27 @@ defmodule PowAssent.Config do
5050
@doc """
5151
Gets the provider configuration from the provided configuration.
5252
"""
53-
@spec get_provider_config(t(), atom()) :: t() | no_return
53+
@spec get_provider_config(t(), atom() | binary()) :: t() | no_return
5454
def get_provider_config(config, provider) do
5555
config
5656
|> get_providers()
57-
|> get(provider)
57+
|> get_for_provider(provider)
5858
|> Kernel.||(raise_error("No provider configuration available for #{provider}."))
5959
|> add_global_config(config)
6060
end
6161

62+
defp get_for_provider(providers_config, provider) when is_atom(provider) do
63+
get(providers_config, provider)
64+
end
65+
defp get_for_provider(providers_config, provider) when is_binary(provider) do
66+
Enum.find_value(providers_config, fn {key, value} ->
67+
case Atom.to_string(key) do
68+
^provider -> value
69+
_any -> false
70+
end
71+
end)
72+
end
73+
6274
defp add_global_config(provider_config, config) do
6375
[
6476
:http_adapter,

lib/pow_assent/plug.ex

+1-2
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ defmodule PowAssent.Plug do
197197
conn
198198
|> Pow.Plug.current_user()
199199
|> get_all_providers_for_user(config)
200-
|> Enum.map(&String.to_atom(&1.provider))
200+
|> Enum.map(&String.to_existing_atom(&1.provider))
201201
end
202202

203203
defp get_all_providers_for_user(nil, _config), do: []
@@ -232,7 +232,6 @@ defmodule PowAssent.Plug do
232232
|> get_provider_config(provider, redirect_uri)
233233
end
234234
defp get_provider_config(config, provider, redirect_uri) do
235-
provider = String.to_atom(provider)
236235
config = Config.get_provider_config(config, provider)
237236
strategy = config[:strategy]
238237
provider_config =

test/pow_assent/config_test.exs

+10
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,14 @@ defmodule PowAssent.ConfigTest do
2828
assert Config.get_provider_config([http_adapter: HTTPAdapater, json_adapter: JSONAdapter, jwt_adapter: JWTAdapter], :provider1) ==
2929
[http_adapter: HTTPAdapater, json_adapter: JSONAdapter, jwt_adapter: JWTAdapter, a: 1]
3030
end
31+
32+
test "get_provider_config/2 with binary provider" do
33+
config = [providers: [provider1: [a: 1], provider2: [b: 2]]]
34+
35+
assert Config.get_provider_config(config, "provider1") == [a: 1]
36+
37+
assert_raise PowAssent.Config.ConfigError, "No provider configuration available for non_existent.", fn ->
38+
refute Config.get_provider_config(config, "non_existent")
39+
end
40+
end
3141
end

0 commit comments

Comments
 (0)