Commit 367c79588a
367c79588a5dc38a15048727ad83f8e49480e445
parent: 11114e655e
Verified · cmc
cmc <hello@cleberg.net> · 2026-09-29 02:51 UTC
wiki, changelog: import-issues connects only to checked addresses
Closes #301
Layout: unified · split
.gitbay/wiki/Architecture/09-Controls.org
+1 −1
| @@ -75,7 +75,7 @@ chapter names of OWASP ASVS 4.0 where one fits. |
| 75 | 75 | |
| 76 | 76 | | Control | Status | Evidence | |
| 77 | 77 | |---------------------------------------------+----------+------------------------------------------------------------------| |
| 78 | | | SSRF protection on user-supplied URLs | partial | webhooks at save and connect; mirrors at save and sync, =repo import= before its fetch, git pinned to the checked address (=internal/gitpin=); =repo import-issues --api-base= checked once and fetched unpinned (#301) | |
| 78 | | SSRF protection on user-supplied URLs | in place | webhooks at save and connect; mirrors at save and sync, =repo import= and =repo import-issues= before they fetch, git and the import API client pinned to the checked address (=internal/gitpin=) | |
| 79 | 79 | | Webhook payload integrity | in place | HMAC-SHA256 header | |
| 80 | 80 | | SMTP credentials protected in transit | in place | STARTTLS required for non-local relays, implicit TLS optional (=internal/mail/mail.go=) | |
| 81 | 81 | | Upload size limits | in place | per-owner storage quota at push (=internal/sshd/sshd.go=); API body 1 MiB | |
.gitbay/wiki/Architecture/10-Known-Gaps.org
−1
| @@ -13,7 +13,6 @@ what the 2026-09-27 review found; remove a row when its issue closes. |
| 13 | 13 | | #259 | Recovery | No restore has been exercised; the drill is written (Admin wiki) and not yet run | high | |
| 14 | 14 | | #260 | CI network | Builds share the runner's source address; no egress policy | medium | |
| 15 | 15 | | #261 | Various | Migration foreign-key check after commit; three web writes bypass dispatch; documentation drift | medium | |
| 16 | | | #301 | SSRF | =repo import-issues --api-base= checks the address once; fetches unpinned | medium | |
| 17 | 16 | |
| 18 | 17 | * Not filed |
| 19 | 18 | |
.gitbay/wiki/Threat-Model.org
+9 −6
| @@ -98,16 +98,19 @@ connection to a user-supplied address, pass the same SSRF guard: the |
| 98 | 98 | scheme must be http/https and, unless =webhooks.allow_local= is set, |
| 99 | 99 | the resolved address must not be loopback, private, shared |
| 100 | 100 | (100.64.0.0/10), link-local, or multicast. The webhook dialer re-checks |
| 101 | | at connect time, and mirror sync and =repo import= resolve and check |
| 102 | | immediately before running git and pin it to the checked addresses |
| 103 | | (=internal/gitpin=), so a DNS answer that changes after validation |
| 104 | | still cannot reach private space. Redirects are never followed. |
| 101 | at connect time, and mirror sync, =repo import= and =repo |
| 102 | import-issues= resolve and check immediately before running git and pin |
| 103 | it to the checked addresses (=internal/gitpin=), so a DNS answer that |
| 104 | changes after validation still cannot reach private space; |
| 105 | =import-issues= holds its API client to the API host's checked |
| 106 | addresses the same way, with no proxy taken from the environment. |
| 107 | Redirects are never followed. |
| 105 | 108 | =repo import= refuses =git://=, which cannot be pinned. Mirror sync |
| 106 | 109 | and =repo import= refuse a host written as a bare number or in |
| 107 | 110 | hex/octal (=0x7f.1=, =2130706433=, =127.1=) rather than dotted |
| 108 | 111 | decimal, since that form resolves differently across parsers; =repo |
| 109 | | mirror add= refuses it when the mirror is saved. GitHub-history import (=repo |
| 110 | | import-issues --api-base=) is not yet pinned (#301). |
| 112 | mirror add= refuses it when the mirror is saved, and =repo |
| 113 | import-issues= refuses it in =--api-base=. |
| 111 | 114 | |
| 112 | 115 | * Rendering pushed markup |
| 113 | 116 | |
CHANGELOG.org
+7
| @@ -19,6 +19,13 @@ anything beyond "replace the binary and restart" is needed. |
| 19 | 19 | global gitconfig are ignored. A source that redirects (a renamed |
| 20 | 20 | repository) fails; import from the URL it redirects to. Needs git |
| 21 | 21 | 2.37 or later on the server (#298). |
| 22 | - =repo import-issues= resolves and checks the API host and the git |
| 23 | host once and connects only to the checked addresses: the API client |
| 24 | dials them with no proxy from the environment and follows no |
| 25 | redirect, and the pull-head fetch runs git pinned, with redirects |
| 26 | off and without the system and global gitconfig. =--api-base= refuses |
| 27 | credentials, a query or a fragment. An API that redirects (a renamed |
| 28 | repository) fails; import under the new name (#301). |
| 22 | 29 | - =repo mirror add= refuses a host written numerically (=127.1=, |
| 23 | 30 | =2130706433=, =0x7f.1=) when the mirror is added, rather than at its |
| 24 | 31 | first sync (#298). |