Skip to main content

Python CVE-2026-33545

MEDIUM
SQL Injection (CWE-89)
2026-03-24 https://github.com/MobSF/Mobile-Security-Framework-MobSF
5.3
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
5.3 MEDIUM
AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:N/A:H

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:N/A:H
Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
Required
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

Lifecycle Timeline

3
Analysis Generated
Mar 24, 2026 - 19:31 vuln.today
Patch released
Mar 24, 2026 - 19:31 nvd
Patch available
CVE Published
Mar 24, 2026 - 19:23 nvd
MEDIUM 5.3

DescriptionGitHub Advisory

Description

MobSF's read_sqlite() function in mobsf/MobSF/utils.py (lines 542-566) uses Python string formatting (%) to construct SQL queries with table names read from a SQLite database's sqlite_master table. When a security analyst uses MobSF to analyze a malicious mobile application containing a crafted SQLite database, attacker-controlled table names are interpolated directly into SQL queries without parameterization or escaping.

This allows an attacker to:

  1. Cause Denial of Service -- A malicious table name causes the database viewer to crash, preventing the analyst from viewing ANY data in the SQLite database. A malicious app can use this to hide sensitive data (C2 server URLs, stolen credentials, API keys) from MobSF's analysis.
  2. Achieve SQL Injection -- The SELECT * FROM query on line 557 is provably injectable via UNION SELECT, allowing attacker-controlled data to be returned in query results. The current code structure (a PRAGMA statement that runs first on line 553) limits the full exploitation chain, but the underlying code is verifiably injectable.

Root Cause

The vulnerable code in mobsf/MobSF/utils.py:542-566:

python
def read_sqlite(sqlite_file):
    """Sqlite Dump - Readable Text."""
    table_dict = {}
    try:
        con = sqlite3.connect(sqlite_file)
        cur = con.cursor()
        cur.execute('SELECT name FROM sqlite_master WHERE type=\'table\';')
        tables = cur.fetchall()
        for table in tables:
            table_dict[table[0]] = {'head': [], 'data': []}
            cur.execute('PRAGMA table_info(\'%s\')' % table)
# <-- INJECTION POINT 1
            rows = cur.fetchall()
            for sq_row in rows:
                table_dict[table[0]]['head'].append(sq_row[1])
            cur.execute('SELECT * FROM \'%s\'' % table)
# <-- INJECTION POINT 2
            rows = cur.fetchall()
            for sq_row in rows:
                tmp_row = []
                for each_row in sq_row:
                    tmp_row.append(str(each_row))
                table_dict[table[0]]['data'].append(tmp_row)
    except Exception:
        logger.exception('Reading SQLite db')
    return table_dict

Lines 553 and 557 use % string formatting to interpolate table (a tuple from sqlite_master) directly into SQL strings. The table value is attacker-controlled when the SQLite database originates from a malicious application being analyzed.

Attack Vector

The read_sqlite() function is called from two locations:

  1. Dynamic Analysis File Viewer (mobsf/DynamicAnalyzer/views/common/device.py:64):
  • Triggered when an analyst clicks to view a .db file in device data
  • Applies to both Android and iOS dynamic analysis
  1. iOS Static Analysis File Viewer (mobsf/StaticAnalyzer/views/ios/views/view_source.py:123):
  • Triggered when an analyst clicks to view a .db file during iOS static analysis

Attack Scenario

  1. Attacker creates a malicious Android APK (or iOS IPA) containing a SQLite database with a crafted table name in the assets/ directory
  2. The SQLite database contains a table created with:
sql
   CREATE TABLE "x' UNION SELECT 'SQL_INJECTION_PROOF'--" (id INTEGER);
  1. Security analyst uploads the application to MobSF for analysis
  2. Analyst browses the extracted files and clicks to view the SQLite database
  3. MobSF's read_sqlite() reads table names from sqlite_master, including the malicious name x' UNION SELECT 'SQL_INJECTION_PROOF'--
  4. The table name is interpolated into SQL queries via string formatting:
  • PRAGMA table_info('x' UNION SELECT 'SQL_INJECTION_PROOF'--') -- causes syntax error (DoS)
  • SELECT * FROM 'x' UNION SELECT 'SQL_INJECTION_PROOF'--' -- SQL injection (UNION SELECT returns attacker data)

Impact

Denial of Service (Confirmed)

When the malicious table name is the first table in sqlite_master (i.e., created first in the database), the PRAGMA statement on line 553 raises a sqlite3.OperationalError, which is caught by the outer try/except. This causes read_sqlite() to return an empty or partial result, preventing the analyst from viewing any database content.

Security impact: A malicious app author can use this technique to hide incriminating data stored in SQLite databases from MobSF's analysis. This directly undermines MobSF's core purpose as a security analysis tool.

SQL Injection (Confirmed in Isolation)

The SELECT * FROM query on line 557 is demonstrably injectable. When the malicious table name x' UNION SELECT 'SQL_INJECTION_PROOF'-- is interpolated, the resulting query:

sql
SELECT * FROM 'x' UNION SELECT 'SQL_INJECTION_PROOF'--'

Successfully executes and returns attacker-controlled data via UNION SELECT. The -- comments out the trailing single quote. This is verified by the PoC script.

Note: In the current code structure, the PRAGMA table_info() statement on line 553 runs before the SELECT * FROM on line 557. The PRAGMA fails with a syntax error for injected payloads, which triggers the exception handler before the SELECT can execute. This limits the full exploitation chain. However, the code flaw is real and any future refactoring that changes the execution order or removes the PRAGMA would immediately expose the full SQL injection.

Proof of Concept

Files Provided(Gdrive)

FileDescription
poc_sqlite_injection.pyStandalone PoC demonstrating the vulnerability
malicious.dbCrafted SQLite database (generated by PoC)
create_malicious_apk.shScript to package the malicious DB into an APK
malicious_sqli.apkPre-built APK for testing against MobSF

https://drive.google.com/drive/folders/1mNGkFfNowkaZ5J018HFi4IQcnjKaWCym?usp=sharing

Running the PoC

bash
# Run the standalone PoC (no MobSF required)
python3 poc_sqlite_injection.py
# Build the malicious APK (requires Android SDK)
./create_malicious_apk.sh
# Test against MobSF
# 1. Start MobSF
# 2. Upload malicious_sqli.apk
# 3. Browse extracted files -> click app_data.db
# 4. Observe: database viewer fails (DoS)

PoC Output (Abbreviated)

[STEP 2] Running MobSF's read_sqlite() against malicious database...
    [!] EXCEPTION CAUGHT: OperationalError: near "UNION": syntax error
    [!] DoS CONFIRMED: read_sqlite() crashed

[STEP 3] Demonstrating SELECT * FROM injection in isolation...
    Query: SELECT * FROM 'x' UNION SELECT 'SQL_INJECTION_PROOF'--'
    [+] Query executed successfully!
    [+] Results: [('SQL_INJECTION_PROOF',), ('normal_data',)]
    [+] SQL INJECTION CONFIRMED

[STEP 4] Complete DoS (malicious table created first):
    Tables with data: NONE
    [!] COMPLETE DoS CONFIRMED

Suggested Fix

Replace string formatting with properly quoted identifiers. SQLite uses double quotes for identifiers:

python
def read_sqlite(sqlite_file):
    """Sqlite Dump - Readable Text."""
    table_dict = {}
    try:
        con = sqlite3.connect(sqlite_file)
        cur = con.cursor()
        cur.execute('SELECT name FROM sqlite_master WHERE type=\'table\';')
        tables = cur.fetchall()
        for table in tables:
            table_name = table[0]
# Properly escape table name as a double-quoted identifier
            safe_name = table_name.replace('"', '""')
            table_dict[table_name] = {'head': [], 'data': []}
            cur.execute(f'PRAGMA table_info("{safe_name}")')
            rows = cur.fetchall()
            for sq_row in rows:
                table_dict[table_name]['head'].append(sq_row[1])
            cur.execute(f'SELECT * FROM "{safe_name}"')
            rows = cur.fetchall()
            for sq_row in rows:
                tmp_row = []
                for each_row in sq_row:
                    tmp_row.append(str(each_row))
                table_dict[table_name]['data'].append(tmp_row)
    except Exception:
        logger.exception('Reading SQLite db')
    return table_dict

This escapes any double quotes within table names by doubling them ("""), which is the standard SQL mechanism for identifier quoting. This prevents breakout from the double-quoted identifier context.

Resources

  • CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
  • OWASP SQL Injection: https://owasp.org/www-community/attacks/SQL_Injection
  • Affected File: mobsf/MobSF/utils.py, lines 542-566

AnalysisAI

A SQL injection vulnerability (CVSS 5.3). Remediation should follow standard vulnerability management procedures. Vendor patch is available.

Technical ContextAI

CWE-89 (SQL Injection).

RemediationAI

Apply the vendor-supplied patch immediately. Implement input validation and WAF rules as interim mitigation.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2026-55255 HIGH POC
8.4 Jun 19

Cross-user flow execution in Langflow (< 1.9.1) lets any authenticated API-key holder run another user's flow by passing

Share

CVE-2026-33545 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy