From 0b8f0f44b733a1fdf01bb9c7b5ceaf9cbd3a6ffd Mon Sep 17 00:00:00 2001 From: Jose Alvarez Date: Tue, 9 Apr 2024 12:41:37 -0600 Subject: [PATCH] Enable https check in runtime --- lib/sobelow/config/https.ex | 36 ++++++++++++++-------- test/config/https_test.exs | 36 ++++++++++++++++++++++ test/fixtures/https/prod.exs | 4 +++ test/fixtures/https/prod_without_https.exs | 4 +++ test/fixtures/https/runtime.exs | 4 +++ 5 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 test/config/https_test.exs create mode 100644 test/fixtures/https/prod.exs create mode 100644 test/fixtures/https/prod_without_https.exs create mode 100644 test/fixtures/https/runtime.exs diff --git a/lib/sobelow/config/https.ex b/lib/sobelow/config/https.ex index 457aaed..ead7986 100644 --- a/lib/sobelow/config/https.ex +++ b/lib/sobelow/config/https.ex @@ -16,28 +16,40 @@ defmodule Sobelow.Config.HTTPS do @uid 9 @finding_type "Config.HTTPS: HTTPS Not Enabled" + @files_to_check ["prod.exs", "runtime.exs"] use Sobelow.Finding - def run(dir_path, configs) do - path = dir_path <> "prod.exs" + def run(dir_path, configs, files_to_check \\ @files_to_check) do + configs_in_files = configs_in_files(dir_path, configs, files_to_check) - if File.exists?(path) && Enum.member?(configs, "prod.exs") do - https = Config.get_configs_by_file(:https, path) - - (Config.get_configs_by_file(:force_ssl, path) ++ https) - |> handle_https(path) + if !Enum.empty?(configs_in_files) && Enum.all?(configs_in_files, &https_config_missing?/1) do + Enum.each(configs_in_files, fn {path, _} -> + add_finding(path) + end) end end - defp handle_https(opts, path) do - if Enum.empty?(opts) do - add_finding(path) - end + defp configs_in_files(dir_path, configs, files) do + files + |> Enum.map(fn file_path -> + path = dir_path <> file_path + exists = File.exists?(path) && Enum.member?(configs, file_path) + {path, exists} + end) + |> Enum.filter(fn {_path, exists} -> exists end) + |> Enum.map(fn {path, _exists} -> + https = Config.get_configs_by_file(:https, path) + {path, Config.get_configs_by_file(:force_ssl, path) ++ https} + end) + end + + defp https_config_missing?({_path, opts}) do + Enum.empty?(opts) end defp add_finding(file) do - reason = "HTTPS configuration details could not be found in `prod.exs`." + reason = "HTTPS configuration details could not be found in `prod.exs` nor `runtime.exs`." finding = %Finding{ diff --git a/test/config/https_test.exs b/test/config/https_test.exs new file mode 100644 index 0000000..b9311b5 --- /dev/null +++ b/test/config/https_test.exs @@ -0,0 +1,36 @@ +defmodule SobelowTest.Config.HttpsTest do + use ExUnit.Case + alias Sobelow.Config.HTTPS + + setup do + Application.put_env(:sobelow, :format, "json") + Sobelow.Fingerprint.start_link() + Sobelow.FindingLog.start_link() + + :ok + end + + test "does not log when force_ssl is present in prod.exs" do + refute HTTPS.run("./test/fixtures/https/", ["prod.exs"]) + end + + test "does not log when force_ssl is present in runtime.exs" do + refute HTTPS.run("./test/fixtures/https/", ["runtime.exs"]) + end + + test "does not log when files don't exist" do + refute HTTPS.run("./test/fixtures/https/", ["prod.exs"], ["prod_does_not_exist.exs"]) + end + + test "does not log when one of the files has the https enabled" do + refute HTTPS.run("./test/fixtures/https/", ["prod.exs"], [ + "prod_without_https.exs", + "prod.exs" + ]) + end + + test "logs when config files exist but https in not found any of them" do + HTTPS.run("./test/fixtures/https/", ["prod_without_https.exs"], ["prod_without_https.exs"]) + assert Sobelow.FindingLog.json("1") =~ "Config.HTTPS: HTTPS Not Enabled" + end +end diff --git a/test/fixtures/https/prod.exs b/test/fixtures/https/prod.exs new file mode 100644 index 0000000..201bd26 --- /dev/null +++ b/test/fixtures/https/prod.exs @@ -0,0 +1,4 @@ +use Config + +config :phoenix_app, + force_ssl: [hsts: true] diff --git a/test/fixtures/https/prod_without_https.exs b/test/fixtures/https/prod_without_https.exs new file mode 100644 index 0000000..1c27798 --- /dev/null +++ b/test/fixtures/https/prod_without_https.exs @@ -0,0 +1,4 @@ +use Config + +config :phoenix_app, + logger: :info diff --git a/test/fixtures/https/runtime.exs b/test/fixtures/https/runtime.exs new file mode 100644 index 0000000..201bd26 --- /dev/null +++ b/test/fixtures/https/runtime.exs @@ -0,0 +1,4 @@ +use Config + +config :phoenix_app, + force_ssl: [hsts: true]