Skip to content

Security vulnerabilities and runtime bugs in mosip-data upgrade scripts #406

Description

@GOKULRAJ136

Short Summary of the Bug

A review of the data upgrade scripts under mosip_master/data_upgrade/ identified multiple security vulnerabilities and runtime issues. The findings include SQL injection, command injection, infinite loop conditions, and several runtime exceptions that can cause upgrade failures.

Description

The following issues were identified during a review of the data migration and upgrade utilities.

1. SQL Injection in get_seed_value()

Severity: High

The table name supplied through args.table is directly concatenated into a SQL query without validation or parameterization:

cursor.execute(
"select id from master." + args.table + " order by id desc limit 20"
)

A malicious or malformed value passed through --table could inject arbitrary SQL statements and potentially compromise the database.

Location : mosip_master/data_upgrade/1.1.5.5_to_1.2.0.1/data-uploader.py (around line 50)

2. Runtime Exceptions in get_seed_value()

Severity: Medium

Two runtime issues exist in the same function and are present in both upgrade versions.

2.1 UnboundLocalError

seed_value is not initialized before entering the loop. If the query returns an empty result set, or no row satisfies the expected condition, seed_value is referenced before assignment.

if seed_value == None:
seed_value = 1000

This results in:
UnboundLocalError: local variable 'seed_value' referenced before assignment

2.2 AttributeError

The code assumes that id_value is a string and directly invokes .isdigit():

if id_value.isdigit():

However, database drivers such as psycopg2 may return integer values. In such cases the script fails with:

AttributeError: 'int' object has no attribute 'isdigit'

Locations
mosip_master/data_upgrade/1.1.5.5_to_1.2.0.1/data-uploader.py
mosip_master/data_upgrade/1.2.0.1_to_1.3.0/data-uploader.py

3. Infinite Loop in getSupportedAgeGroups()

Severity: Medium

The following loop can become infinite when bioAttributes is absent (None) or an empty list ([]):

modalities = []
while not modalities:
modalities = agegroup_config_json.get(ageGroup).get("bioAttributes")

When the value remains empty, the loop condition never changes and execution hangs indefinitely.

Location : mosip_master/data_upgrade/1.1.5.5_to_1.2.0.1/migration-ui_spec.py (around lines 53–55)

4. Command Injection via eval in Property Loader

Severity: High

Property keys and values are passed directly to eval:

key=$(echo $key | tr '.' '_')
eval ${key}=${value}

A specially crafted properties file containing shell metacharacters in either the key or value can execute arbitrary shell commands with the privileges of the running process.

Examples include command substitution, shell expansion, or malicious payloads embedded in configuration values.

Locations
mosip_master/data_upgrade/1.1.5.5_to_1.2.0.1/upgrade.sh
mosip_master/data_upgrade/1.2.0.1_to_1.3.0/upgrade.sh

5. Runtime Bugs in fill_series()

Severity: Medium

5.1 Unreachable Empty-Sheet Guard

start_row is hardcoded to 2, making the following condition impossible to satisfy:

start_row = 2
end_row = find_last_data_row(sheet)

if start_row is None and end_row is None:

When find_last_data_row() returns None for an empty worksheet, execution falls through to:

range(start_row, end_row + 1)

which results in:

TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

5.2 Off-by-One ID Generation

The generated ID values are based on the worksheet row number rather than the iteration index:

for i, value in enumerate(range(start_row, end_row + 1), start=1):
column[i].value = int(seed_value) + value

As a result:

First data row receives seed_value + 2
Expected value should be seed_value + 1
All subsequent generated IDs are shifted by one

Location: mosip_master/data_upgrade/1.2.0.1_to_1.3.0/data-uploader.py (around lines 93–104)

Affected Files
mosip_master/data_upgrade/1.1.5.5_to_1.2.0.1/data-uploader.py
mosip_master/data_upgrade/1.1.5.5_to_1.2.0.1/migration-ui_spec.py
mosip_master/data_upgrade/1.1.5.5_to_1.2.0.1/upgrade.sh
mosip_master/data_upgrade/1.2.0.1_to_1.3.0/data-uploader.py
mosip_master/data_upgrade/1.2.0.1_to_1.3.0/upgrade.sh

Impact
These issues can lead to:

Arbitrary SQL execution
Arbitrary shell command execution
Upgrade script failures
Infinite hangs during migration
Incorrect data generation
Failed upgrade and deployment workflows

It is recommended that these issues be addressed before the upgrade scripts are used in production or CI/CD environments.

Attachments / Evidence / Links

These issues were identified from CodeRabbit review comments on the following PR:

#403

Based on the review findings and the potential security/runtime impact, this issue has been created to track and address the identified vulnerabilities and bugs in the data upgrade scripts.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions