[breaking-change] Use a distinct scope for forge DNS allowlist authz.

Before this commit, a `_git-pages-repository.<host>` TXT record would
allow both forge DNS allowlist authorization, as well as normal DNS
allowlist authorization. This means that a site set up to have its
contents updated by a Forgejo Action could have its contents replaced
by the contents of the repository which contains the Forgejo Action,
which will effectively erase the site in most cases. This is a classic
confused deputy scenario.

To fix this, forge DNS allowlist authorization now uses a distinct
`_git-pages-forge-allowlist.<host>` TXT record, removing ambiguity
that allows this scenario to happen.

The issue was introduced in 27a6de792c
and existed in `main` for about a hour, so it is unlikely anybody
has been impacted by this.
This commit is contained in:
Catherine
2026-04-23 15:20:32 +00:00
parent 27a6de792c
commit c5c5306688
2 changed files with 6 additions and 6 deletions
+5 -5
View File
@@ -179,7 +179,7 @@ func authorizeDNSChallenge(r *http.Request) (*Authorization, error) {
}, nil
}
func authorizeDNSAllowlist(r *http.Request) (*Authorization, error) {
func authorizeDNSAllowlist(r *http.Request, scope string) (*Authorization, error) {
host, err := GetHost(r)
if err != nil {
return nil, err
@@ -190,7 +190,7 @@ func authorizeDNSAllowlist(r *http.Request) (*Authorization, error) {
return nil, err
}
allowlistHostname := fmt.Sprintf("_git-pages-repository.%s", host)
allowlistHostname := fmt.Sprintf("_%s.%s", scope, host)
records, err := net.LookupTXT(allowlistHostname)
if err != nil {
return nil, AuthError{http.StatusUnauthorized,
@@ -421,7 +421,7 @@ func AuthorizeUpdateFromRepository(r *http.Request) (*Authorization, error) {
// DNS allowlist gives authority to update but not delete.
if r.Method == http.MethodPut || r.Method == http.MethodPost {
auth, err = authorizeDNSAllowlist(r)
auth, err = authorizeDNSAllowlist(r, "git-pages-repository")
if err != nil && IsUnauthorized(err) {
causes = append(causes, err)
} else if err != nil { // bad request
@@ -741,7 +741,7 @@ func authorizeForgeWildcard(r *http.Request) (*Authorization, error) {
}
// Validates a provided forge token against a repository URL extracted from the DNS allowlist
// records of the target domain (`_git-pages-repository.*`).
// records of the target domain specified in `_git-pages-forge-authorization.*`.
func authorizeForgeDNSAllowlist(r *http.Request) (*Authorization, error) {
forgeToken := r.Header.Get("Forge-Authorization")
if forgeToken == "" {
@@ -749,7 +749,7 @@ func authorizeForgeDNSAllowlist(r *http.Request) (*Authorization, error) {
}
var errs []error
if dnsAuth, err := authorizeDNSAllowlist(r); err != nil {
if dnsAuth, err := authorizeDNSAllowlist(r, "git-pages-forge-allowlist"); err != nil {
errs = append(errs, err)
} else if dnsAuth != nil {
// DNS allows uploads from some repositories, but we don't know yet if the forge token