Packages
metastatic
0.14.1
0.26.0
0.25.0
0.24.1
0.24.0
0.23.0
0.22.2
0.22.1
0.22.0
0.21.3
0.21.2
0.21.1
0.21.0
0.20.3
0.20.2
0.20.1
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.1
0.15.0
0.14.2
0.14.1
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.0
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.2
0.9.1
0.9.0
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.2
0.4.1
0.4.0
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
Cross-language code meta-model library using unified MetaAST representation. Parse, transform, and translate code across Python, Elixir, Ruby, Erlang, Haskell, and more via a shared three-tuple AST format.
Current section
Files
Jump to
Current section
Files
lib/metastatic/analysis/business_logic/inline_javascript.ex
defmodule Metastatic.Analysis.BusinessLogic.InlineJavascript do
@moduledoc """
Detects inline executable code in templates/strings (XSS/injection risk).
Universal pattern: embedding code directly in strings/templates without sanitization.
## Examples
**Python (Django template with unsafe JS):**
```python
html = f'<script>var userId = {user_id};</script>' # XSS risk - unescaped data
```
**JavaScript (React with dangerouslySetInnerHTML):**
```javascript
return <div dangerouslySetInnerHTML={{__html: userContent}} />; # XSS vulnerability
```
**Elixir (Phoenix template with raw JS):**
```elixir
~H\"\"\"
<script>
window.userId = <%= @user_id %>; # Should use Phoenix.HTML.Tag or json encode
</script>
\"\"\"
```
**C# (ASP.NET with Html.Raw):**
```csharp
@Html.Raw($\"<script>var userId = {userId};</script>\") # XSS risk
```
**Go (template with unescaped JS):**
```go
tmpl := template.Must(template.New(\"page\").Parse(
`<script>var userId = {{.UserID}};</script>` # Should use JS escaping
))
```
**Java (JSP with script tag):**
```java
out.println(\"<script>var userId = \" + userId + \";</script>\"); # XSS vulnerability
```
**Ruby (Rails with javascript_tag):**
```ruby
javascript_tag "var userId = " + user_id.to_s # Should use escape_javascript
```
**PHP (inline script without escaping):**
```php
echo \"<script>var userId = $userId;</script>\"; # XSS risk - use htmlspecialchars
```
"""
@behaviour Metastatic.Analysis.Analyzer
alias Metastatic.Analysis.Analyzer
@dangerous_patterns [
"<script>",
"</script>",
"dangerouslysetinnerhtml",
"html.raw",
"javascript:",
"onclick=",
"onerror="
]
@impl true
def info do
%{
name: :inline_javascript,
category: :security,
description: "Detects inline JavaScript/code in strings (XSS risk)",
severity: :error,
explanation: "Avoid inline scripts - use CSP-compliant external scripts or proper escaping",
configurable: true
}
end
@impl true
def analyze({:literal, meta, content} = node, _context)
when is_list(meta) and is_binary(content) do
# Check if this is a string literal in 3-tuple format
if Keyword.get(meta, :subtype) == :string do
content_lower = String.downcase(content)
if Enum.any?(@dangerous_patterns, &String.contains?(content_lower, &1)) do
[
Analyzer.issue(
analyzer: __MODULE__,
category: :security,
severity: :error,
message: "Inline JavaScript in string literal - XSS vulnerability",
node: node,
metadata: %{
pattern: "inline_script",
suggestion: "Use external scripts, CSP, or proper escaping/sanitization"
}
)
]
else
[]
end
else
[]
end
end
def analyze({:function_call, meta, args} = node, _context) when is_list(meta) do
fn_name = Keyword.get(meta, :name, "")
fn_lower = String.downcase(fn_name)
# Check for dangerous functions
if String.contains?(fn_lower, [
"dangerouslysetinnerhtml",
"html.raw",
"javascript_tag"
]) do
[
Analyzer.issue(
analyzer: __MODULE__,
category: :security,
severity: :error,
message: "Using '#{fn_name}' to inject HTML/JS - potential XSS vulnerability",
node: node,
metadata: %{
function: fn_name,
suggestion: "Sanitize content or use framework's safe rendering methods"
}
)
]
else
# Check if args contain script tags
if has_script_in_args?(args) do
[
Analyzer.issue(
analyzer: __MODULE__,
category: :security,
severity: :warning,
message: "Function call contains inline script - verify proper escaping",
node: node,
metadata: %{
suggestion: "Ensure all user data is properly escaped"
}
)
]
else
[]
end
end
end
def analyze(_node, _context), do: []
defp has_script_in_args?(args) when is_list(args) do
Enum.any?(args, fn
{:literal, meta, content} when is_list(meta) and is_binary(content) ->
Keyword.get(meta, :subtype) == :string and
String.contains?(String.downcase(content), ["<script>", "</script>"])
_ ->
false
end)
end
defp has_script_in_args?(_), do: false
end