Packages
sobelow
0.10.5
0.14.1
0.14.0
0.13.0
0.12.2
0.12.1
0.12.0
0.11.1
0.11.0
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
Security-focused static analysis for Elixir & the Phoenix framework
Current section
Files
Jump to
Current section
Files
lib/sobelow/utils.ex
defmodule Sobelow.Utils do
@moduledoc false
alias Sobelow.Parse
def is_controller?(uses) do
has_use_type?(uses, :controller)
end
def is_router?(uses) do
has_use_type?(uses, :router)
end
def is_endpoint?([{:use, _, [{_, _, [:Phoenix, :Endpoint]}, _]} | _]), do: true
def is_endpoint?([_ | t]), do: is_endpoint?(t)
def is_endpoint?(_), do: false
def has_use_type?([{:use, _, [_, type]} | _], type), do: true
def has_use_type?([_ | t], type), do: has_use_type?(t, type)
def has_use_type?(_, _), do: false
def normalize_path(filename) do
filename
|> Path.expand("")
|> String.replace_prefix("/", "")
end
## File listing
## In normal situations, this shouldn't fail. However,
## if there is a failure in path or app_name, it could
## lead to an issue here. In these situations, the scan
## will now proceed normally, but print an error message
## for the user.
def all_files(filepath, _directory \\ "") do
if File.dir?(filepath) do
Path.wildcard(filepath <> "/**/*.ex")
|> Enum.reject(&String.contains?(&1, "/mix/tasks/"))
else
warning = """
WARNING: Web directory was not found in the expected location.
This may be a result of non-standard directory structure, or use
of an umbrella project. All files in the "lib" directory were
scanned for vulnerabilities.
"""
IO.puts(:stderr, warning)
[]
end
end
def template_files(filepath, _directory \\ "") do
if File.dir?(filepath) do
Path.wildcard(filepath <> "/**/*.html.eex")
else
[]
end
end
# Setup Utils
def get_app_name(filepath) do
if File.exists?(filepath) do
ast = Parse.ast(filepath)
{_, project_block} = Macro.prewalk(ast, [], &extract_project_block/2)
{_, app_name} = Macro.prewalk(project_block, [], &extract_app_name/2)
binarize_app_name(app_name, ast)
end
end
defp binarize_app_name(app_name, _) when is_binary(app_name), do: app_name
defp binarize_app_name(app_name, _) when is_atom(app_name), do: Atom.to_string(app_name)
defp binarize_app_name({:@, _, [{module_attribute, _, _}]}, ast) do
ast
|> Macro.prewalk([], fn
{:@, _, [{^module_attribute, _, [name]}]}, [] ->
{[], name}
ast, acc ->
{ast, acc}
end)
|> elem(1)
|> binarize_app_name(ast)
end
defp binarize_app_name(app_name, _), do: app_name
defp extract_project_block({:def, _, [{:project, _, _}, [do: block]]} = ast, _) do
{ast, block}
end
defp extract_project_block(ast, acc) do
{ast, acc}
end
defp extract_app_name(ast, acc) do
if Keyword.keyword?(ast) && Keyword.get(ast, :app) do
{ast, Keyword.get(ast, :app)}
else
{ast, acc}
end
end
def get_root() do
root = Sobelow.get_env(:root)
if is_nil(root), do: "", else: root
end
end