|
|
|
|
@@ -406,6 +406,13 @@ elif mode == "comment-url-wrong-repo":
|
|
|
|
|
elif mode == "comment-url-suffix-injection":
|
|
|
|
|
# Prefix-injected: a bare endswith("/<slug>/pulls/123") test would ACCEPT it.
|
|
|
|
|
pr_url = f"{_origin}/deceptive{_slug}/pulls/123"
|
|
|
|
|
elif mode == "comment-mixed-case-slug":
|
|
|
|
|
# #875: EXPECTED_REPO_SLUG is taken verbatim from GITEA_API_BASE and can be
|
|
|
|
|
# mixed-case (e.g. "USC/uconnect"), but Gitea canonicalizes the returned
|
|
|
|
|
# pull_request_url's owner/repo segment to LOWERCASE. Model that here by
|
|
|
|
|
# lowercasing only the slug path, independent of the (possibly mixed-case)
|
|
|
|
|
# web_base the wrapper was configured with.
|
|
|
|
|
pr_url = f"{_origin}{_slug.lower()}/pulls/123"
|
|
|
|
|
record = {
|
|
|
|
|
"id": 456,
|
|
|
|
|
"body": body,
|
|
|
|
|
@@ -868,6 +875,19 @@ for bad_mode in comment-url-wrong-host comment-url-wrong-owner comment-url-wrong
|
|
|
|
|
assert_no_temp_leak "$bad_mode"
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# Case 15b (#875): a MIXED-CASE repo slug (as embedded verbatim in
|
|
|
|
|
# GITEA_API_BASE, e.g. "USC/uconnect") must still verify when Gitea returns the
|
|
|
|
|
# comment's pull_request_url with its owner/repo segment canonicalized to
|
|
|
|
|
# LOWERCASE ("usc/uconnect"). This is a legitimate, unforged provider response —
|
|
|
|
|
# not a spoof — so `_belongs` must accept it (case-insensitive slug compare)
|
|
|
|
|
# while still requiring the origin (scheme+host+port) and the rest of the path
|
|
|
|
|
# to match in full. Pre-#875-fix this fails closed on a real success
|
|
|
|
|
# (false-negative); post-fix it verifies.
|
|
|
|
|
run_review comment-mixed-case-slug comment durable-body https://git.mosaicstack.dev \
|
|
|
|
|
https://git.mosaicstack.dev/USC/uconnect.git USC/uconnect
|
|
|
|
|
grep -q 'Added and verified comment on Gitea PR #123' "$OUTPUT_FILE"
|
|
|
|
|
assert_no_temp_leak "comment-mixed-case-slug"
|
|
|
|
|
|
|
|
|
|
# Case 16 (#865 ITEM 1, current-head TOCTOU): the PR head advances between the
|
|
|
|
|
# pre-submit head read (which pins the review) and the post-verify re-read. The
|
|
|
|
|
# review is genuinely created and verified as pinned to the OLD head, but the
|
|
|
|
|
|