zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

leaky_environment.ex (2001B)


      1 defmodule Credo.Check.Warning.LeakyEnvironment do
      2   use Credo.Check,
      3     base_priority: :high,
      4     tags: [:controversial],
      5     category: :warning,
      6     explanations: [
      7       check: """
      8       OS child processes inherit the environment of their parent process. This
      9       includes sensitive configuration parameters, such as credentials. To
     10       minimize the risk of such values leaking, clear or overwrite them when
     11       spawning executables.
     12 
     13       The functions `System.cmd/2` and `System.cmd/3` allow environment variables be cleared by
     14       setting their value to `nil`:
     15 
     16           System.cmd("env", [], env: %{"DB_PASSWORD" => nil})
     17 
     18       """
     19     ]
     20 
     21   @doc false
     22   @impl true
     23   def run(%SourceFile{} = source_file, params \\ []) do
     24     issue_meta = IssueMeta.for(source_file, params)
     25 
     26     Credo.Code.prewalk(source_file, &traverse(&1, &2, issue_meta))
     27   end
     28 
     29   defp traverse({{:., _loc, call}, meta, args} = ast, issues, issue_meta) do
     30     case get_forbidden_call(call, args) do
     31       nil ->
     32         {ast, issues}
     33 
     34       bad ->
     35         {ast, issues_for_call(bad, meta, issue_meta, issues)}
     36     end
     37   end
     38 
     39   defp traverse(ast, issues, _issue_meta) do
     40     {ast, issues}
     41   end
     42 
     43   defp get_forbidden_call([{:__aliases__, _, [:System]}, :cmd], [_, _]) do
     44     "System.cmd/2"
     45   end
     46 
     47   defp get_forbidden_call([{:__aliases__, _, [:System]}, :cmd], [_, _, opts])
     48        when is_list(opts) do
     49     if Keyword.has_key?(opts, :env) do
     50       nil
     51     else
     52       "System.cmd/3"
     53     end
     54   end
     55 
     56   defp get_forbidden_call([:erlang, :open_port], [_, opts])
     57        when is_list(opts) do
     58     if Keyword.has_key?(opts, :env) do
     59       nil
     60     else
     61       ":erlang.open_port/2"
     62     end
     63   end
     64 
     65   defp get_forbidden_call(_, _) do
     66     nil
     67   end
     68 
     69   defp issues_for_call(call, meta, issue_meta, issues) do
     70     options = [
     71       message: "When using #{call}, clear or overwrite sensitive environment variables",
     72       trigger: call,
     73       line_no: meta[:line]
     74     ]
     75 
     76     [format_issue(issue_meta, options) | issues]
     77   end
     78 end