Packages

HTTP Security Headers for Phoenix or Plug

Current section

Files

Jump to
secure_headers lib headers x_xss_protection.ex
Raw

lib/headers/x_xss_protection.ex

defmodule SecureHeaders.XXssProtection do
@moduledoc '''
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 0]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 1]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 1, mode: "block"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 1, report: "http://google.com/"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 1, mode: "block", report: "http://google.com/report"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 1, mode: "block", report: "/report/"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "0"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "0;"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "1"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "1;"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "1;mode=block"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "1; mode=block"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "1; report=http://google.com/"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "1; report=/google.com/"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "1; mode=block; report=/google.com/"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: "1; mode=block; report=http://google.com/"])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 0, mode: "block"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 0, report: "http://google.com/"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 0, mode: "block", report: "http://google.com/"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 0, mode: "block", report: "/report/"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 1, mode: "allow"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 1, mode: "allow", report: "http://google.com/"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 2, mode: "block"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 2, modes: "block"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 2, mode: "allow"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 2, report: "google.com"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 2, mode: "allow", report: "http://google.com/"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 2, mode: "block", report: "google.com"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [values: 2]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [value: 2, reportz: "google.com"]])
IO.inspect( SecureHeaders.XXssProtection.validate [x_xss_protection: [valuez: 2, mode: "block", reportz: "google.com"]])
'''
@error_msg "Invalid configuration for x-xss-protection"
@secure_config [
value: 0,
mode: "block",
report: ""
]
def validate(options) when is_list(options) do
case Keyword.has_key?(options, :config) do
false -> {:ok, options}
true ->
case Keyword.has_key?(options[:config], :x_xss_protection) do
# No x-xss-protection configuration found - return config
false -> {:ok, options}
true ->
case validate_config(options[:config][:x_xss_protection]) do
false -> {:error, @error_msg}
true -> {:ok, config_to_string(options, options[:config][:x_xss_protection])}
end
end
end
end
def validate(_), do: {:error, @error_msg}
defp config_to_string(options, xss_config) when xss_config |> is_list do
config = Keyword.drop(options[:config], [:x_xss_protection])
config = config ++ [x_xss_protection: make_string(xss_config)]
Keyword.drop(options, [:config]) ++ [config: config]
end
defp config_to_string(options, xss_config) when xss_config |> is_bitstring do
options
end
defp validate_config(xss_config) when is_list(xss_config) do
case validate_keys(xss_config) do
false -> false
true -> validate_config(make_string(xss_config))
end
end
defp validate_config(xss_config) when xss_config |> is_bitstring do
v = ~r/^[01](;)?\z/i
vm = ~r/^[1](;|; ){1,1}mode=block\z/i
vr= ~r/^[1](;|; ){1,1}report=.+\z/i
vmr = ~r/^[1](;|; ){1,1}mode=block(;|; ){1,1}report=.+\z/i
Regex.match?(v, xss_config) || Regex.match?(vm, xss_config)|| Regex.match?(vr, xss_config) || Regex.match?(vmr, xss_config)
end
defp validate_config(_), do: {:error, @error_msg}
defp validate_keys(xss_config) when xss_config |> is_list do
List.foldl( Keyword.keys(xss_config), true, fn (key,acc) -> List.keymember?(@secure_config,key,0) && acc end)
end
defp make_string(xss_config) do
result = ""
if Keyword.get(xss_config, :value), do: result = result <> Integer.to_string(xss_config[:value])
if Keyword.get(xss_config, :mode), do: result = result <> "; mode=" <> xss_config[:mode]
if Keyword.get(xss_config, :report), do: result = result <> "; report=" <> xss_config[:report]
result
end
end