Skip to content

Commit 60c064f

Browse files
committed
Report validity to GitHub when scanning tokens
GitHub supports[1] returning the validity (true or false positive) for Clojars deploy tokens that it reports to us. This implements that response. Fixes #879. [1]: https://docs.github.com/en/enterprise-cloud@latest/code-security/secret-scanning/secret-scanning-partner-program#provide-feedback-for-false-positives
1 parent dbe8769 commit 60c064f

File tree

2 files changed

+56
-19
lines changed

2 files changed

+56
-19
lines changed

src/clojars/routes/token_breach.clj

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,35 @@
3636
(base64/decode key-sig)
3737
{:key key :alg :ecdsa+sha256}))))
3838

39-
;; - make emails async
4039
;; - add timing logs
4140

41+
(defn- token-response
42+
[{:keys [token type]} found?]
43+
{:token_raw token
44+
:token_type type
45+
:label (if found? "true_positive" "false_positive")})
46+
47+
(defn- check-token
48+
[db event-emitter {:as token-data :keys [token url]}]
49+
(if-some [{:as db-token :keys [id disabled user_id]}
50+
(db/find-token-by-value db token)]
51+
(do
52+
(when (not disabled)
53+
(db/disable-deploy-token db id))
54+
(event/emit event-emitter :token-breached
55+
{:user-id user_id
56+
:token-disabled? disabled
57+
:token-name (:name db-token)
58+
:commit-url url})
59+
(token-response token-data true))
60+
(token-response token-data false)))
61+
4262
(defn- handle-github-token-breach
4363
[db event-emitter {:as _request :keys [headers body]}]
4464
(let [body-str (slurp body)]
4565
(if (valid-github-request? headers body-str)
4666
(let [data (json/parse-string body-str true)]
47-
(doseq [{:keys [token url]} data]
48-
(when-let [{:as db-token :keys [id disabled user_id]}
49-
(db/find-token-by-value db token)]
50-
(when (not disabled)
51-
(db/disable-deploy-token db id))
52-
(event/emit event-emitter :token-breached
53-
{:user-id user_id
54-
:token-disabled? disabled
55-
:token-name (:name db-token)
56-
:commit-url url})))
57-
(response/status 200))
67+
(response/response (mapv (partial check-token db event-emitter) data)))
5868
(response/status 422))))
5969

6070
(defn routes [db event-emitter]

test/clojars/unit/web/token_breach_test.clj

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@
2828
:is_current true}]})
2929

3030
(defn- build-breach-request
31-
[token-value]
32-
(let [payload [{:token token-value
33-
:type "whatever"
34-
:url "https://github.com/foo/bar"}]
31+
[& token-values]
32+
(let [payload (mapv (fn [token-value]
33+
{:token token-value
34+
:type "whatever"
35+
:url "https://github.com/foo/bar"})
36+
token-values)
3537
payload-str (json/encode payload)
3638
sig (dsa/sign payload-str {:key privkey :alg :ecdsa+sha256})
3739
sig-b64 (String. (base64/encode sig))]
@@ -59,11 +61,16 @@
5961
(with-redefs [client/get (constantly {:body github-response})]
6062
(testing "when token is enabled"
6163
(let [token (db/add-deploy-token help/*db* "ham" "a token" nil nil false nil)
62-
res (app (build-breach-request (:token token)))
64+
token-str (:token token)
65+
res (app (build-breach-request token-str))
6366
db-token (find-token "ham" "a token")
6467
_ (is (true? (email/wait-for-mock-emails)))
6568
[to subject message] (first @email/mock-emails)]
6669
(is (= 200 (:status res)))
70+
(is (= [{:token_raw token-str
71+
:token_type "whatever"
72+
:label "true_positive"}]
73+
(:body res)))
6774
(is (:disabled db-token))
6875
(is (= "ham@biscuit.co" to))
6976
(is (= "Deploy token found on GitHub" subject))
@@ -73,15 +80,35 @@
7380

7481
(testing "when token is disabled"
7582
(let [token (db/add-deploy-token help/*db* "ham" "another token" nil nil false nil)
83+
token-str (:token token)
7684
db-token (find-token "ham" "another token")
7785
_ (db/disable-deploy-token help/*db* (:id db-token))
7886
_ (email/expect-mock-emails 1)
79-
res (app (build-breach-request (:token token)))
87+
res (app (build-breach-request token-str))
8088
_ (is (true? (email/wait-for-mock-emails)))
8189
[to subject message] (first @email/mock-emails)]
8290
(is (= 200 (:status res)))
91+
(is (= [{:token_raw token-str
92+
:token_type "whatever"
93+
:label "true_positive"}]
94+
(:body res)))
8395
(is (= "ham@biscuit.co" to))
8496
(is (= "Deploy token found on GitHub" subject))
8597
(is (re-find #"'another token'" message))
8698
(is (re-find #"https://github.com/foo/bar" message))
87-
(is (re-find #"was already disabled" message)))))))
99+
(is (re-find #"was already disabled" message))))
100+
101+
(testing "with existing and non-existent tokens"
102+
(let [token (db/add-deploy-token help/*db* "ham" "a token" nil nil false nil)
103+
token-str (:token token)
104+
res (app (build-breach-request token-str "non-existent-token"))
105+
db-token (find-token "ham" "a token")]
106+
(is (= 200 (:status res)))
107+
(is (= [{:token_raw token-str
108+
:token_type "whatever"
109+
:label "true_positive"}
110+
{:token_raw "non-existent-token"
111+
:token_type "whatever"
112+
:label "false_positive"}]
113+
(:body res)))
114+
(is (:disabled db-token)))))))

0 commit comments

Comments
 (0)