From 05d79287bc74b59756b05fbf3331698e81c56e63 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Thu, 12 Mar 2026 16:03:08 -0500 Subject: [PATCH] chore: remove sobelow dependency --- .sobelow-skips | 26 ------------------- AGENTS.md | 1 - lib/snmpkit/snmp_lib/cache.ex | 1 - lib/snmpkit/snmp_lib/mib/compiler.ex | 1 - .../controllers/api/v1/mib_controller.ex | 4 --- mix.exs | 1 - mix.lock | 1 - 7 files changed, 35 deletions(-) delete mode 100644 .sobelow-skips diff --git a/.sobelow-skips b/.sobelow-skips deleted file mode 100644 index 4e498e63..00000000 --- a/.sobelow-skips +++ /dev/null @@ -1,26 +0,0 @@ -# Sobelow Skip Configuration -# This file documents security findings that have been reviewed and mitigated. -# See docs/security-analysis.md for detailed explanations. - -# Config.HTTPS is configured in config/runtime.exs, not config/prod.exs -# Sobelow only checks prod.exs, resulting in false positive -Config.HTTPS:0:config/prod.exs - -# Vendored SnmpKit library - binary_to_term used for trusted MIB compilation -# MIB files are only loaded from application-controlled directories -Misc.BinToTerm:203:lib/snmpkit/snmp_lib/mib/compiler.ex - -# MIB Controller - Directory traversal mitigated with validation -# vendor_dir is constructed from validated vendor name (alphanumeric + hyphen/underscore only) -# No path traversal characters (., /, \, :) allowed -Traversal.FileModule:141:lib/towerops_web/controllers/api/v1/mib_controller.ex - -# MIB Controller - File.cp with validated paths -# upload.path is Plug.Upload-controlled (safe) -# target_path uses Path.basename to strip directory components -# Filename validation rejects path traversal sequences -Traversal.FileModule:270:lib/towerops_web/controllers/api/v1/mib_controller.ex - -# SQL Query - False positive, uses parameterized queries -# Table names are constants, user input uses $1, $2 binding -Traversal.FileModule:166:lib/towerops_web/controllers/api/v1/mib_controller.ex diff --git a/AGENTS.md b/AGENTS.md index 4147c8f9..aab22685 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -47,7 +47,6 @@ This approach improves: - **IMPORTANT**: When you add or update a dependency run `mix deps.audit` and `mix hex.audit` to check for security issues - **IMPORTANT**: When you add or update a dependency run `mix hex.outdated` to check for outdated dependencies -- **IMPORTANT**: When you complete a task run `mix sobelow --config` to check for security issues and fix any issue ### Phoenix v1.8 guidelines diff --git a/lib/snmpkit/snmp_lib/cache.ex b/lib/snmpkit/snmp_lib/cache.ex index 004c85b5..c4f4017d 100644 --- a/lib/snmpkit/snmp_lib/cache.ex +++ b/lib/snmpkit/snmp_lib/cache.ex @@ -585,7 +585,6 @@ defmodule SnmpKit.SnmpLib.Cache do defp decompress_value(compressed_value) do # Use safe: true to prevent arbitrary code execution via malicious cached terms - # sobelow_skip ["Misc.BinToTerm"] compressed_value |> :zlib.uncompress() |> :erlang.binary_to_term([:safe]) diff --git a/lib/snmpkit/snmp_lib/mib/compiler.ex b/lib/snmpkit/snmp_lib/mib/compiler.ex index a12f4f6b..ece5dd9e 100644 --- a/lib/snmpkit/snmp_lib/mib/compiler.ex +++ b/lib/snmpkit/snmp_lib/mib/compiler.ex @@ -216,7 +216,6 @@ defmodule SnmpKit.SnmpLib.MIB.Compiler do case File.read(compiled_path) do {:ok, binary_data} -> # Use safe: true to prevent arbitrary code execution via malicious terms - # sobelow_skip ["Misc.BinToTerm"] case :erlang.binary_to_term(binary_data, [:safe]) do %{__type__: :compiled_mib} = compiled -> {:ok, compiled} diff --git a/lib/towerops_web/controllers/api/v1/mib_controller.ex b/lib/towerops_web/controllers/api/v1/mib_controller.ex index 88562154..5e52da87 100644 --- a/lib/towerops_web/controllers/api/v1/mib_controller.ex +++ b/lib/towerops_web/controllers/api/v1/mib_controller.ex @@ -141,7 +141,6 @@ defmodule ToweropsWeb.Api.V1.MibController do defp remove_vendor_directory(conn, vendor, vendor_dir) do # Vendor directory is safe - constructed from validated vendor name and base MIB directory # Validation ensures no path traversal characters (., /, \, :) are present - # sobelow_skip ["Traversal.FileModule"] case File.rm_rf(vendor_dir) do {:ok, _files} -> Logger.info("Deleted MIB files for vendor: #{vendor}") @@ -206,7 +205,6 @@ defmodule ToweropsWeb.Api.V1.MibController do :ok -> # Safe to copy to vendor directory - vendor_dir constructed from validated vendor name # and all paths in temp_dir have been validated by validate_extracted_paths/1 - # sobelow_skip ["Traversal.FileModule"] File.cp_r!(temp_dir, vendor_dir) files_count = count_files(vendor_dir) Logger.info("Extracted #{files_count} MIB files for vendor: #{vendor}") @@ -253,7 +251,6 @@ defmodule ToweropsWeb.Api.V1.MibController do :ok -> # Safe to copy to vendor directory - vendor_dir constructed from validated vendor name # and all paths in temp_dir have been validated by validate_extracted_paths/1 - # sobelow_skip ["Traversal.FileModule"] File.cp_r!(temp_dir, vendor_dir) files_count = count_files(vendor_dir) Logger.info("Extracted #{files_count} MIB files for vendor: #{vendor}") @@ -316,7 +313,6 @@ defmodule ToweropsWeb.Api.V1.MibController do |> json(%{error: "Cannot upload: filename conflicts with existing directory"}) else # upload.path is safe - it's controlled by Plug.Upload, not user input - # sobelow_skip ["Traversal.FileModule"] case File.cp(upload.path, target_path) do :ok -> Logger.info("Uploaded MIB file: #{upload.filename} for vendor: #{vendor}") diff --git a/mix.exs b/mix.exs index a780a71f..6412b150 100644 --- a/mix.exs +++ b/mix.exs @@ -90,7 +90,6 @@ defmodule Towerops.MixProject do {:mix_test_watch, "~> 1.0", only: [:dev, :test], runtime: false}, {:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false}, {:credo, "~> 1.7", only: [:dev, :test], runtime: false}, - {:sobelow, "~> 0.14.1", only: [:dev, :test], runtime: false}, {:mix_audit, "~> 2.1", only: [:dev, :test], runtime: false}, {:hammer, "~> 7.2.0"}, {:hammer_backend_redis, "~> 7.1"}, diff --git a/mix.lock b/mix.lock index 589b7e0c..ac0b63a9 100644 --- a/mix.lock +++ b/mix.lock @@ -80,7 +80,6 @@ "ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"}, "redix": {:hex, :redix, "1.5.3", "4eaae29c75e3285c0ff9957046b7c209aa7f72a023a17f0a9ea51c2a50ab5b0f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:nimble_options, "~> 0.5.0 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7b06fb5246373af41f5826b03334dfa3f636347d4d5d98b4d455b699d425ae7e"}, "req": {:hex, :req, "0.5.17", "0096ddd5b0ed6f576a03dde4b158a0c727215b15d2795e59e0916c6971066ede", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0b8bc6ffdfebbc07968e59d3ff96d52f2202d0536f10fef4dc11dc02a2a43e39"}, - "sobelow": {:hex, :sobelow, "0.14.1", "2f81e8632f15574cba2402bcddff5497b413c01e6f094bc0ab94e83c2f74db81", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8fac9a2bd90fdc4b15d6fca6e1608efb7f7c600fa75800813b794ee9364c87f2"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "stream_data": {:hex, :stream_data, "1.2.0", "58dd3f9e88afe27dc38bef26fce0c84a9e7a96772b2925c7b32cd2435697a52b", [:mix], [], "hexpm", "eb5c546ee3466920314643edf68943a5b14b32d1da9fe01698dc92b73f89a9ed"}, "styler": {:hex, :styler, "1.11.0", "35010d970689a23c2bcc8e97bd8bf7d20e3561d60c49be84654df5c37d051a9c", [:mix], [], "hexpm", "70f36165d0cf238a32b7a456fdef6a9c72e77e657d7ac4a0ace33aeba3f2b8c0"},