Skip to content

Commit 04c6795

Browse files
committed
Flag a repository pinned to a subdomain the scan says it probably does not power
Developers do not always know which sites their code serves, so a repository gets pinned to a subdomain and the mapping is never corrected. When a scan reaches none of the routes a pinned repository declares, and the site's host is not written in that repository's code, the scan now says so on the code section, names the repository, and offers to un-pin it, which puts it back to being worked out automatically. It asks for the owner to confirm first, because a repository can still be behind a site it shares no reachable route with.
1 parent 53c7a72 commit 04c6795

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

‎app/core/external.py‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2998,8 +2998,23 @@ def code_behind(db, user, scan: ExternalDastScan, asset: ExternalAsset) -> dict:
29982998
out.append(dict(c, full_name=repo.full_name, linked=bool(link.get("linked")),
29992999
link_source=link.get("source") or "",
30003000
link_reasons=link.get("reasons") or []))
3001-
linked = [dict(l, full_name=visible[l["repo_id"]].full_name)
3002-
for l in data.get("linked") or [] if l.get("repo_id") in visible]
3001+
linked = []
3002+
for l in data.get("linked") or []:
3003+
rid = l.get("repo_id")
3004+
if rid not in visible:
3005+
continue
3006+
link = links.get(rid) or {}
3007+
src = link.get("source") or ""
3008+
total = int(l.get("routes_total") or 0)
3009+
reached = int(l.get("routes_reached") or 0)
3010+
# A repository pinned to this subdomain that declares routes none of
3011+
# which the scan reached, and whose link is not from the host being
3012+
# written in its code, is probably not what powers this site. Flag it
3013+
# so somebody can un-pin it: developers often do not know which sites
3014+
# their code serves, so the mapping drifts and nobody corrects it.
3015+
unlikely = total > 0 and reached == 0 and src != "code"
3016+
linked.append(dict(l, full_name=visible[rid].full_name, source=src,
3017+
unlikely=unlikely))
30033018
return {"counts": paths.get("counts") or {}, "control": paths.get("control") or {},
30043019
"candidates": out, "linked": linked, "indexed": data.get("indexed", 0),
30053020
"at": data.get("at", ""), "has_paths": bool(paths.get("paths"))}

‎app/web/templates/external_scan.html‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,27 @@
108108
{% if code.linked %}
109109
<div class="small" style="margin-bottom:.5rem">Linked code reached:
110110
{% for l in code.linked %}<span class="mono">{{ l.full_name }}</span> {{ l.routes_reached }} of {{ l.routes_total }} routes{{ ', ' if not loop.last }}{% endfor %}</div>
111+
{% set unlikely = code.linked | selectattr('unlikely') | list %}
112+
{% if unlikely %}
113+
<div class="notice warn" style="margin-bottom:.5rem">
114+
<div><strong>Pinned, but maybe not behind this subdomain.</strong>
115+
The scan reached none of the routes these repositories declare, and the site's host is not written in their code, so they may be pinned to <span class="mono">{{ asset.host }}</span> by mistake. Confirm with the owner before un-pinning; developers do not always know which sites their code powers.</div>
116+
{% for l in unlikely %}
117+
<div class="small" style="margin-top:.3rem">
118+
<span class="mono">{{ l.full_name }}</span>
119+
<span class="faint">0 of {{ l.routes_total }} routes reached</span>
120+
<form method="post" action="{{ base }}/external/{{ asset.id }}/repos" style="display:inline">
121+
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
122+
<input type="hidden" name="repository" value="{{ l.full_name }}">
123+
<input type="hidden" name="action" value="forget">
124+
<input type="hidden" name="back" value="/external/{{ asset.id }}/scans/{{ scan.id }}">
125+
<button class="btn sm" type="submit"
126+
data-confirm="Un-pin {{ l.full_name }} from {{ asset.host }}? It goes back to being worked out automatically.">Un-pin</button>
127+
</form>
128+
</div>
129+
{% endfor %}
130+
</div>
131+
{% endif %}
111132
{% endif %}
112133
{% if code.candidates %}
113134
<div class="table-scroll"><table>

0 commit comments

Comments
 (0)