Sobelow만으로 충분한가요?
아니요. 테스트 앱에서 Sobelow는 코드·설정 취약점 13종 중 9종만 잡았습니다.
테스트 앱에서 Sobelow가 잡은 것과 놓친 것
저장소의 일부러 취약한 Phoenix 앱(test/fixtures/vulnerable_app)에 mix sobelow --format json --private를 실행한 결과, Sobelow는 코드·설정 ID 13종 중 9종을 잡았습니다. 놓친 4종은 ATOM-002, CMD-001, REDOS-001, SQLI-001이며 grep/Opengrep이 잡아야 합니다. 의존성 취약점(EXS-DEP-001)은 Sobelow가 아니라 mix_audit의 몫입니다.
측정 환경: Elixir 1.18.4 / OTP 27, phoenix 1.7.24, phoenix_live_view 1.2.13, ecto 3.14.2, sobelow 0.16.0, mix_audit 2.1.5. 출처: EXPECTED.md
| ID | 위치 (sink) | Sobelow | Sobelow 검사 (confidence) |
|---|---|---|---|
EXS-ATOM-001 | lib/vuln_app/catalog.ex:22 | 탐지 | DOS.StringToAtom (low) |
EXS-ATOM-002 | lib/vuln_app/importer.ex:6 | 놓침 | — |
EXS-DESER-001 | lib/vuln_app/preferences.ex:10 | 탐지 | Misc.BinToTerm (high) |
EXS-RCE-001 | lib/vuln_app/calculator.ex:6 | 탐지 | RCE.CodeModule (low) |
EXS-CMD-001 | lib/vuln_app/thumbnails.ex:6 | 놓침 | — (CI.System 미발동) |
EXS-SQLI-001 | priv/examples/sqli_fragment.exs:14 | 놓침 | — (컴파일 대상 아님) |
EXS-SQLI-002 | lib/vuln_app/reports.ex:8 | 탐지 | SQL.Query (low) |
EXS-XSS-001 | lib/vuln_app_web/components/comment_html.ex:13 | 탐지 | XSS.Raw (low) |
EXS-REDOS-001 | lib/vuln_app/search.ex:8 | 놓침 | — |
EXS-PATH-001 | lib/vuln_app/files.ex:8 | 탐지 | Traversal.FileModule (low) |
EXS-CFG-001 | config/prod.exs:8 | 탐지 | Config.Secrets (high) |
EXS-CFG-002 | lib/vuln_app_web/router.ex:5 | 탐지 | Config.Headers (high) |
EXS-CFG-003 | config/prod.exs:4 | 탐지 | Config.HTTPS (high) |
왜 놓쳤나요?
- EXS-ATOM-002
Jason.decode(payload, keys: :atoms): Sobelow의 atom 검사(DOS.StringToAtom등)는 JSON 디코더 옵션을 보지 않습니다. → String.to_atom이 왜 위험한가요? - EXS-CMD-001
System.cmd("sh", ["-c", "convert " <> filename ...]): 이 형태에서 Sobelow의CI.System이 발동하지 않았습니다. - EXS-REDOS-001
Regex.compile!(pattern): 동적 정규식에 대한 Sobelow 검사가 없습니다. - EXS-SQLI-001
fragment("... '#{name}'"): Ecto는 fragment 첫 인자의 문자열 보간을 컴파일 에러로 막기 때문에 이 인스턴스는 컴파일되지 않는priv/examples/*.exs에 있습니다. 정적 스캐너가priv/의*.exs까지 포함해야 잡힙니다.
또한 Sobelow는 함수 경계를 넘는 추적이 약합니다. 컨트롤러가 params를 컨텍스트 모듈 함수에 넘기고 그 안에서 위험 함수를 쓰면 Medium/Low로 보고되거나 아예 안 잡힐 수 있으므로 grep/Opengrep 결과와 교차 확인합니다.
Sobelow가 더 잡은 것: 오탐과 중복
같은 실행에서 Sobelow는 ID 집합 밖의 항목 2건을 더 보고했습니다.
Traversal.FileModuleonlib/vuln_app/files.ex:14: 오탐입니다. 경로를Path.safe_relative/2로 검증한 뒤 읽습니다.XSS.SendResp(medium) oncomment_controller.ex:12: EXS-XSS-001과 원인이 같으므로 분류 단계에서 하나로 합칩니다.
그래서 elixir-security-audit은 스캐너 결과를 그대로 믿지 않고, Claude가 해당 라인을 직접 읽어 외부 입력이 sink에 닿는지로 실제·오탐·불확실을 판정합니다.
그럼 Semgrep을 같이 돌리면 되나요?
Semgrep OSS는 languages: [elixir] 룰을 Pro 전용으로 건너뛰고 오류 없이 0건을 냅니다. 결과가 깨끗해 보여도 실제로는 아무 룰도 돌지 않은 것입니다.
오픈소스로 쓰려면 Semgrep 포크인 Opengrep을 설치하거나 semgrep --pro를 쓰세요. elixir-security-audit의 scan.sh는 이 경우 0건 대신 "건너뜀"으로 표시하고, 번들된 Opengrep 룰 17개(AST·taint·정규식, 일부 autofix)와 BEAM grep 검사를 함께 돌립니다.
| 소스 | 맡는 영역 |
|---|---|
| Sobelow | Phoenix 코드·설정 (위 표의 9종) |
mix_audit (mix deps.audit) | 의존성 권고 (EXS-DEP-001) |
mix hex.audit | retired 패키지(EXS-DEP-002)와 Hex 권고 |
| OSV-Scanner | mix.lock CVE 교차 확인 |
| Opengrep 룰 17개 + BEAM grep | Sobelow가 놓친 ATOM-002, CMD-001, REDOS-001, SQLI-001 등 |
의존성도 한 도구로는 부족합니다. 테스트 앱에서 plug_crypto 2.2.0 권고(EEF-CVE-2026-105963)는 OSV와 hex.audit만 잡았고, sweet_xml 0.6.6(GHSA-qpmc-wprv-x746)은 mix_audit·OSV·hex.audit 셋 모두 잡았습니다.
자주 묻는 질문
Sobelow는 테스트 앱에서 몇 종을 잡았나요?
코드·설정 ID 13종 중 9종(ATOM-001, DESER-001, RCE-001, SQLI-002, XSS-001, PATH-001, CFG-001, CFG-002, CFG-003)을 잡았습니다. ATOM-002, CMD-001, REDOS-001, SQLI-001은 놓쳤습니다.
Semgrep OSS로 Elixir 룰을 돌리면 왜 0건인가요?
Semgrep OSS는 languages: [elixir] 룰을 Pro 전용으로 건너뛰고 오류 없이 0건을 냅니다. Opengrep을 설치하거나 semgrep --pro를 쓰세요.
Sobelow가 의존성 취약점도 보나요?
테스트 앱의 의존성 취약점(EXS-DEP-001)은 Sobelow가 아니라 mix_audit의 몫이었습니다. elixir-security-audit은 mix_audit, hex.audit, OSV-Scanner를 함께 실행합니다.