Packages
sobelow
0.10.1
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/xss/raw.ex
defmodule Sobelow.XSS.Raw do
use Sobelow.Finding
@finding_type "XSS.Raw: XSS"
def run(fun, meta_file, _, nil) do
confidence = if !meta_file.is_controller?, do: :low
Finding.init(@finding_type, meta_file.filename, confidence)
|> Finding.multi_from_def(fun, parse_raw_def(fun))
|> Enum.each(&Print.add_finding(&1))
end
def run(fun, meta_file, web_root, controller) do
{vars, _, {fun_name, line_no}} = parse_render_def(fun)
filename = meta_file.filename
templates = Sobelow.MetaLog.get_templates()
root =
if String.ends_with?(web_root, "/lib/") do
app_name = Sobelow.get_env(:app_name)
prc = web_root <> app_name <> "_web/"
rc = web_root <> app_name <> "/web/"
Enum.find([rc, prc], "", &File.exists?/1)
else
web_root
end
Enum.each(vars, fn {finding, {template, ref_vars, vars}} ->
template =
cond do
is_atom(template) -> Atom.to_string(template) <> ".html"
is_binary(template) -> template
true -> ""
end
template_path =
(root <> "templates/" <> controller <> "/" <> template <> ".eex")
|> Utils.normalize_path()
raw_funs = templates[template_path]
if raw_funs do
raw_vals = Parse.get_template_vars(raw_funs.raw)
Enum.each(ref_vars, fn var ->
var = "@#{var}"
if Enum.member?(raw_vals, var) do
Sobelow.MetaLog.delete_raw(var, template_path)
t_name = String.replace_prefix(Path.expand(template_path, ""), "/", "")
add_finding(t_name, line_no, filename, fun_name, fun, var, :high, finding)
end
end)
Enum.each(vars, fn var ->
var = "@#{var}"
if Enum.member?(raw_vals, var) do
Sobelow.MetaLog.delete_raw(var, template_path)
t_name = String.replace_prefix(Path.expand(template_path, ""), "/", "")
add_finding(t_name, line_no, filename, fun_name, fun, var, :medium, finding)
end
end)
end
end)
end
def parse_render_def(fun) do
{params, {fun_name, line_no}} = Parse.get_fun_declaration(fun)
pipefuns =
Parse.get_pipe_funs(fun)
|> Enum.map(fn {_, _, opts} -> Enum.at(opts, 1) end)
|> Enum.flat_map(&Parse.get_funs_of_type(&1, :render))
pipevars =
pipefuns
|> Enum.map(&{&1, Parse.parse_render_opts(&1, params, 0)})
|> List.flatten()
vars =
(Parse.get_funs_of_type(fun, :render) -- pipefuns)
|> Enum.map(&{&1, Parse.parse_render_opts(&1, params, 1)})
{vars ++ pipevars, params, {fun_name, line_no}}
end
def parse_raw_def(fun) do
Parse.get_fun_vars_and_meta(fun, 0, :raw, :HTML)
end
def details() do
Sobelow.XSS.details()
end
defp add_finding(t_name, line_no, filename, fun_name, fun, var, severity, finding) do
finding =
%Finding{
type: @finding_type,
filename: filename,
fun_source: fun,
vuln_source: finding,
vuln_variable: var,
vuln_line_no: Parse.get_fun_line(finding),
confidence: severity
}
|> Finding.fetch_fingerprint()
case Sobelow.format() do
"json" ->
json_finding = [
type: finding.type,
file: finding.filename,
variable: "#{finding.vuln_variable}",
template: "#{t_name}",
line: finding.vuln_line_no
]
Sobelow.log_finding(json_finding, finding)
"txt" ->
Sobelow.log_finding(finding)
Print.print_custom_finding_metadata(finding, [
Print.finding_file_name(filename),
Print.finding_line(finding.vuln_source),
Print.finding_fun_metadata(fun_name, line_no),
"Template: #{t_name} - #{var}"
])
"compact" ->
Print.log_compact_finding(finding)
_ ->
Sobelow.log_finding(finding)
end
end
end