Skip to content

docs: update ALLOW_LOCALNETWORKS behavior after migration validation hardening #39224

Description

@dengbinbox

Gitea Version

1.27.3

What happened?

Description

The documentation for [migrations].ALLOW_LOCALNETWORKS is inconsistent with the current
implementation.

The configuration cheat sheet currently states:

Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291 (false by default).
If a domain is allowed by ALLOWED_DOMAINS, this option will be ignored.

Chinese documentation:

https://docs.gitea.com/zh-cn/administration/config-cheat-sheet/

The same outdated description is also present in custom/conf/app.example.ini.

However, since the migration validation hardening in #38324 / #38400, private and loopback addresses
are added to the block list when ALLOW_LOCALNETWORKS = false.

The migration URL validation resolves the hostname and rejects the request immediately if any
resolved address matches the block list. Therefore, an entry in ALLOWED_DOMAINS no longer
overrides ALLOW_LOCALNETWORKS = false.

Steps to reproduce

Configure Gitea as follows:

[migrations]
ALLOWED_DOMAINS = *.example.com
ALLOW_LOCALNETWORKS = false

Configure DNS:

git.internal.example.com -> 172.16.254.5

Attempt to migrate:

https://git.internal.example.com/owner/repository.git

### Actual behavior

The migration is rejected with:

You cannot import from disallowed hosts. Please ask the admin to check
ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS settings.

Adding either the exact hostname or the resolved IP address to
ALLOWED_DOMAINS does not help:

ALLOWED_DOMAINS = git.internal.example.com,172.16.254.5
ALLOW_LOCALNETWORKS = false

This happens because the private IP address matches the block list, and the
block-list result takes precedence over the hostname allow list.

### Documented behavior

Based on the current documentation, the migration would be expected to succeed
because git.internal.example.com matches ALLOWED_DOMAINS, causing
ALLOW_LOCALNETWORKS to be ignored.

This was also the behavior before #38324 / #38400.

### Current implementation

The current initialization logic adds private and loopback networks to the
block list when ALLOW_LOCALNETWORKS is disabled:

https://github.com/go-gitea/gitea/blob/main/services/migrations/migrate.go

The validation then returns immediately when the resolved IP matches that
block list.

The tests explicitly verify the new behavior: an allowed hostname resolving to
a private or loopback address must still be rejected when
ALLOW_LOCALNETWORKS = false.

### Suggested documentation

The documentation and custom/conf/app.example.ini could be updated to say
something similar to:

> Whether repository migrations may connect to private or loopback network
> addresses. When disabled, a migration URL resolving to such an address is
> rejected even if its hostname matches ALLOWED_DOMAINS.
> Enable this option to migrate repositories from internal network hosts.

It may also be useful to mention that enabling this option permits access to
private network destinations globally and should be considered carefully due
to SSRF risks.

### Version

Observed with Gitea 1.27.x after the migration validation changes introduced by
#38324 / #38400.

———

Assisted by Codex (GPT-5).

### How are you running Gitea?

docker-compose.yaml
```yaml
version: "3"

networks:
gitea:
  external: false

services:
gitea:
  image: gitea/gitea:1.27.3
  container_name: gitea
  extra_hosts:
    - "git.internal.example.com:172.16.254.5" # Gateway IP, gateway used for SSL offloading.
  environment:
    - USER_UID=1000
    - USER_GID=1000
    - GITEA__database__DB_TYPE=postgres
    - GITEA__database__HOST=postgres:5432
    - GITEA__database__NAME=gitea
    - GITEA__database__USER=gitea
    - GITEA__database__PASSWD=gitea
  restart: always
  networks:
    - gitea
  volumes:
    - ./gitea:/data
    - /etc/timezone:/etc/timezone:ro
    - /etc/localtime:/etc/localtime:ro
  ports:
    - "3000:3000"
    - "2222:22"
  depends_on:
    - postgres
    - redis

# Omit other configurations.....

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions