-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:clj-holmes/clj-watson
- Loading branch information
Showing
16 changed files
with
240 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{:linters {:unresolved-symbol {:exclude []} | ||
:refer-all {:exclude [clojure.test]}} | ||
:output {:show-rule-name-in-message true}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
patreon: mthbernardes | ||
ko_fi: mthbernardes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,38 @@ on: | |
workflow_dispatch: | ||
|
||
jobs: | ||
tests: | ||
strategy: | ||
matrix: | ||
namespace: [ unit ] | ||
operating-system: [ubuntu-latest] | ||
|
||
runs-on: ${{ matrix.operating-system }} | ||
|
||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
|
||
- name: Prepare java | ||
uses: actions/setup-java@v3 | ||
with: | ||
distribution: 'adopt' | ||
java-version: '11' | ||
|
||
- name: Install clojure tools-deps | ||
uses: DeLaGuardo/setup-clojure@master | ||
with: | ||
tools-deps: 1.11.1.1113 | ||
|
||
- name: Cache Maven packages | ||
uses: actions/[email protected] | ||
with: | ||
path: ~/.m2 | ||
key: ${{ runner.os }}-m2-tests-${{ hashFiles('**/deps.edn') }} | ||
restore-keys: ${{ runner.os }}-m2-pr | ||
|
||
- name: Execute ${{ matrix.namespace }} Test | ||
run: clojure -M:test ${{ matrix.namespace }} | ||
|
||
check-lint: | ||
|
||
|
@@ -65,4 +97,4 @@ jobs: | |
uses: clj-holmes/clj-holmes-action@main | ||
with: | ||
output-type: 'stdout' | ||
fail-on-result: 'true' | ||
fail-on-result: 'true' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,6 @@ pom.xml.asc | |
.idea/ | ||
.cpcache/ | ||
*.iml | ||
.clj-kondo/ | ||
.clj-kondo/*/ | ||
target/ | ||
.lsp/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
{:allow-list {:cves [{:cve-label "CVE-0000" | ||
:expires "2000-01-01"}]}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
(ns clj-watson.adapter.config | ||
(:require | ||
[clj-time.format :as time.format])) | ||
|
||
(def time-parser (time.format/formatters :date)) | ||
|
||
(defn ->allow-config | ||
[{:keys [cve-label expires]}] | ||
{cve-label (time.format/parse time-parser expires)}) | ||
|
||
(defn config->allow-config-map | ||
[config] | ||
(->> config | ||
:allow-list | ||
:cves | ||
(map ->allow-config) | ||
(into {}))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,43 @@ | ||
(ns clj-watson.controller.github.vulnerability | ||
(:require | ||
[clj-time.core :as time] | ||
[clj-watson.diplomat.dependency :as diplomat.dependency] | ||
[clj-watson.diplomat.github.advisory :as diplomat.gh.advisory] | ||
[clj-watson.logic.github.vulnerability :as logic.gh.vulnerability])) | ||
[clj-watson.logic.github.vulnerability :as logic.gh.vulnerability] | ||
[clj-watson.logic.rules.allowlist :as logic.rules.allowlist])) | ||
|
||
(def ^:private dependency-rename | ||
{'org.jdom/jdom2 'org.jdom/jdom}) | ||
|
||
(defn ^:private latest-dependency-version [dependency all-dependency-vulnerabilities repositories] | ||
(defn ^:private latest-dependency-version | ||
[dependency all-dependency-vulnerabilities repositories] | ||
(let [latest-version (diplomat.dependency/get-latest-version! dependency repositories) | ||
vulnerabilities (filterv #(logic.gh.vulnerability/is-version-vulnerable? latest-version %) all-dependency-vulnerabilities)] | ||
vulnerabilities (filterv (partial logic.gh.vulnerability/is-version-vulnerable? latest-version) all-dependency-vulnerabilities)] | ||
(when (not (seq vulnerabilities)) | ||
latest-version))) | ||
|
||
(defn ^:private scan-dependency [{:keys [dependency] :as dependency-info} repositories] | ||
(defn ^:private scan-dependency | ||
[repositories allow-list {:keys [dependency] :as dependency-info}] | ||
(let [dependency-name-for-github (or (get dependency-rename dependency) dependency) | ||
all-dependency-vulnerabilities (diplomat.gh.advisory/vulnerabilities-by-package dependency-name-for-github) | ||
filtered-vulnerabilities (filterv #(logic.gh.vulnerability/is-version-vulnerable? dependency-info %) all-dependency-vulnerabilities) | ||
all-dependency-vulnerabilities (diplomat.gh.advisory/vulnerabilities-by-package dependency-name-for-github) | ||
reported-vulnerabilities (filterv (partial logic.gh.vulnerability/is-version-vulnerable? dependency-info) all-dependency-vulnerabilities) | ||
; not sure how to use it here and avoid always recommend the latest version (logic.gh.vulnerability/version-not-vulnerable all-dependency-vulnerabilities) | ||
filtered-vulnerabilities (remove (partial logic.rules.allowlist/by-pass? allow-list (time/today)) reported-vulnerabilities) | ||
latest-secure-version (latest-dependency-version dependency all-dependency-vulnerabilities repositories)] | ||
(if (seq filtered-vulnerabilities) | ||
(assoc dependency-info :vulnerabilities filtered-vulnerabilities :secure-version latest-secure-version) | ||
dependency-info))) | ||
|
||
(defn scan-dependencies [dependencies repositories] | ||
(defn scan-dependencies | ||
[dependencies repositories allow-list] | ||
(->> dependencies | ||
(pmap #(scan-dependency % repositories)) | ||
(pmap (partial scan-dependency repositories allow-list)) | ||
(filterv :vulnerabilities))) | ||
|
||
(comment | ||
(def repositories {:mvn/repos {"central" {:url "https://repo1.maven.org/maven2/"} | ||
"clojars" {:url "https://repo.clojars.org/"}}}) | ||
|
||
(scan-dependencies [{:dependency 'org.jdom/jdom2 :mvn/version "2.0.6"}] repositories) | ||
(scan-dependencies [{:dependency 'org.jdom/jdom2 :mvn/version "2.0.6"}] repositories {}) | ||
|
||
(scan-dependencies [{:dependency 'org.postgresql/postgresql :mvn/version "42.2.10"}] repositories)) | ||
(scan-dependencies [{:dependency 'org.postgresql/postgresql :mvn/version "42.2.10"}] repositories {})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
(ns clj-watson.logic.rules.allowlist | ||
(:require | ||
[clj-time.core :as time])) | ||
|
||
(defn match-cve? | ||
([allowed-cves as-of] | ||
(partial match-cve? allowed-cves as-of)) | ||
([allowed-cves | ||
as-of | ||
{identifier :value}] | ||
(when-let [expire-date (allowed-cves identifier)] | ||
(time/after? expire-date as-of)))) | ||
|
||
(defn by-pass? | ||
[allowed-cves | ||
as-of | ||
vulnerability] | ||
(let [allowed? (comp seq (partial filter (match-cve? allowed-cves as-of)) :identifiers :advisory)] | ||
(->> vulnerability | ||
:vulnerabilities | ||
(remove allowed?) | ||
empty?))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
(ns clj-watson.unit.adapter.config-test | ||
(:require | ||
[clj-time.core :as time] | ||
[clj-watson.adapter.config :as adapter.config] | ||
[clojure.test :refer :all])) | ||
|
||
(deftest ->allow-config | ||
(testing "Allow Parsing" | ||
(is (= {"CVE-1234" (time/date-time 2021 5 12)} | ||
(adapter.config/->allow-config {:cve-label "CVE-1234" :expires "2021-05-12"}))) | ||
(is (thrown? IllegalArgumentException | ||
(adapter.config/->allow-config {:cve-label "CVE-1234" :expires "wrong date"}))))) | ||
|
||
(deftest config->allow-list | ||
(testing "Configs Parsing" | ||
(is (= {"CVE-1234" (time/date-time 2021 5 12) | ||
"CVE-5678" (time/date-time 2025 5 12)} | ||
(adapter.config/config->allow-config-map {:allow-list {:cves [{:cve-label "CVE-1234" :expires "2021-05-12"} | ||
{:cve-label "CVE-5678" :expires "2025-05-12"}]}}))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
(ns clj-watson.unit.logic.allowlist-test | ||
(:require | ||
[clj-time.core :as time] | ||
[clj-watson.logic.rules.allowlist :as logic.rules.allowlist] | ||
[clojure.test :refer :all])) | ||
|
||
(deftest by-pass? | ||
(let [expired-date (time/local-date 2020 2 1) | ||
as-of (time/local-date 2022 7 12) | ||
valid-date (time/local-date 2022 7 14)] | ||
(testing "matching CVEs" | ||
(is (= true (logic.rules.allowlist/by-pass? {"CVE-2022-2047" valid-date} | ||
as-of | ||
{:vulnerabilities | ||
[{:advisory | ||
{:identifiers | ||
[{:value "GHSA-cj7v-27pg-wf7q"} | ||
{:value "CVE-2022-2047"}]}}]}))) | ||
(is (= false (logic.rules.allowlist/by-pass? {"CVE-2022-2042" valid-date} | ||
as-of | ||
{:vulnerabilities | ||
[{:advisory | ||
{:identifiers | ||
[{:value "GHSA-cj7v-27pg-wf7q"} | ||
{:value "CVE-DO-NOT-BYPASS"}]}}]})))) | ||
(testing "Multiple vulnerabilities on a single report" | ||
(testing "all CVEs must be allowed" | ||
(is (= true (logic.rules.allowlist/by-pass? {"CVE-2022-2047" valid-date | ||
"CVE-1234-56789" valid-date} | ||
as-of | ||
{:vulnerabilities | ||
[{:advisory | ||
{:identifiers | ||
[{:value "CVE-1234-56789"}]}} | ||
{:advisory | ||
{:identifiers | ||
[{:value "GHSA-cj7v-27pg-wf7q"} | ||
{:value "CVE-2022-2047"}]}}]}))) | ||
(is (= false (logic.rules.allowlist/by-pass? {"CVE-2022-2047" valid-date} | ||
as-of | ||
{:vulnerabilities | ||
[{:advisory | ||
{:identifiers | ||
[{:value "CVE-1234-56789"}]}} | ||
{:advisory | ||
{:identifiers | ||
[{:value "GHSA-cj7v-27pg-wf7q"} | ||
{:value "CVE-2022-2047"}]}}]}))))) | ||
(testing "expired allowlist" | ||
(is (= false (logic.rules.allowlist/by-pass? {"CVE-2022-2047" expired-date} | ||
as-of | ||
{:vulnerabilities | ||
[{:advisory | ||
{:identifiers | ||
[{:value "GHSA-cj7v-27pg-wf7q"} | ||
{:value "CVE-2022-2047"}]}}]}))) | ||
(is (= false (logic.rules.allowlist/by-pass? {"CVE-2022-2042" expired-date} | ||
as-of | ||
{:vulnerabilities | ||
[{:advisory | ||
{:identifiers | ||
[{:value "GHSA-cj7v-27pg-wf7q"} | ||
{:value "CVE-DO-NOT-BYPASS"}]}}]})))))) |
Oops, something went wrong.