All database operations must prevent SQL injection attacks.
Use SQLite parameterized queries with ? placeholders for all data values.
# ✅ Correct
db.fetchone("SELECT * FROM tracks WHERE parent_oid=?", (oid,))
# ❌ Wrong
db.fetchone(f"SELECT * FROM tracks WHERE parent_oid={oid}")Use only whitelisted tables from DBHandler.VALID_TABLES:
VALID_TABLES = {"config", "gme_library", "script_codes", "tracks"}_validate_table_name() rejects invalid tables.
Field names validated against database schema before use.
Methods:
_validate_field_names(table, fields)- Validates against schema_populate_valid_columns()- Caches valid columns fromPRAGMA table_info()
write_to_database() and update_table_entry() validate automatically.
Add tests in tests/test_sql_injection.py for new database operations:
def test_new_operation_field_injection(temp_db):
malicious_data = {"valid_field": "value", "'; DROP TABLE--": "attack"}
with pytest.raises(ValueError, match="Invalid field names"):
temp_db.new_operation(malicious_data)All inputs protected:
- Web frontend: Pydantic validation + field validation
- MP3 ID3 tags: Values parameterized automatically
- File names: Sanitized via
cleanup_filename()+ parameterized
| Security Method | Location |
|---|---|
| Table validation | DBHandler._validate_table_name() |
| Field validation | DBHandler._validate_field_names() |
| Value parameterization | with db.execute_context(query, params) as cursor: |
| Security tests | tests/test_sql_injection.py |
- ✅ Use
with db.execute_context(query, params):with parameterized queries - ✅ Use tables from
VALID_TABLES(or update whitelist) - ✅ Use
write_to_database()orupdate_table_entry()for dynamic fields - ✅ Add security tests
- ✅ Run CodeQL scanner before commit