Skip to content

fix(albums): sanitize image_ids and secure IN clause#629

Merged
rohan-pandeyy merged 4 commits into
AOSSIE-Org:mainfrom
g-k-s-03:Fix-SQL-injection-vulnerability
May 14, 2026
Merged

fix(albums): sanitize image_ids and secure IN clause#629
rohan-pandeyy merged 4 commits into
AOSSIE-Org:mainfrom
g-k-s-03:Fix-SQL-injection-vulnerability

Conversation

@g-k-s-03
Copy link
Copy Markdown
Contributor

@g-k-s-03 g-k-s-03 commented Nov 11, 2025

closes #608

Summary

Fix potential SQL injection in db_add_images_to_album by sanitizing image_ids and using parameterized IN clause safely.

Changes

  • Validate image_ids to be integers (skip invalid)
  • Construct IN clause with stable placeholders
  • Use executemany to insert rows safely
  • Added unit tests to cover invalid/malicious inputs

Tests

  • pytest passes locally
  • Manual testing: verified inserting valid IDs and rejecting invalid input

Summary by CodeRabbit

  • Bug Fixes
    • Improved stability when adding images to albums with enhanced validation and error handling.
    • Fixed potential issues by validating image IDs and checking their existence in the database before processing.
    • Added safeguards to prevent invalid or duplicate entries in album collections.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 11, 2025

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0c8f7ecb-a61d-4606-8b5c-0f8235f91d38

📥 Commits

Reviewing files that changed from the base of the PR and between e3ea331 and 617be0e.

📒 Files selected for processing (1)
  • backend/app/database/albums.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/app/database/albums.py

Walkthrough

The PR hardens db_add_images_to_album by adding input validation and sanitization for the image_ids parameter. The function now requires image_ids to be a list, sanitizes string entries by trimming whitespace and removing empty values, and raises ValueError if no valid IDs remain before executing the database query.

Changes

Image ID Validation and Sanitization

Layer / File(s) Summary
Image ID validation and sanitized IN-clause query
backend/app/database/albums.py
db_add_images_to_album adds docstring and runtime validation: requires image_ids as a list, strips whitespace, filters empty strings, raises ValueError if sanitized set is empty, executes parameterized existence check on sanitized IDs, raises on ID mismatch, and commits after INSERT OR IGNORE.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Suggested labels

Python

A function once vulnerable to injection's might,
Now guards its inputs with careful delight,
Strips whitespace, checks types with care,
And parameterized queries still reign fair,
Safety thrives when validation runs tight. 🐰✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: sanitizing image_ids and securing the IN clause to address SQL injection vulnerability.
Linked Issues check ✅ Passed The PR implements all coding requirements from issue #608: validates/sanitizes image_ids, uses parameterized queries safely, and includes unit tests for invalid/malicious inputs.
Out of Scope Changes check ✅ Passed All changes in the PR are directly related to fixing the SQL injection vulnerability in db_add_images_to_album as specified in issue #608.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added backend bug Something isn't working labels Nov 11, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
backend/app/database/albums.py (2)

199-207: Remove redundant commit.

Line 205's manual conn.commit() is unnecessary. The get_db_connection() context manager (line 189) automatically commits on successful exit, as shown in the connection.py snippet.

Apply this diff:

                 [(album_id, img_id) for img_id in valid_images],
             )
-            conn.commit()
         else:

209-209: Remove trailing whitespace.

Line 209 contains trailing whitespace.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cec1303 and 009f36f.

📒 Files selected for processing (1)
  • backend/app/database/albums.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/app/database/albums.py (1)
backend/app/database/connection.py (1)
  • get_db_connection (8-32)
🔇 Additional comments (1)
backend/app/database/albums.py (1)

172-177: Good input validation.

The type check ensures image_ids is a list before processing, preventing type-related errors early.

Comment thread backend/app/database/albums.py
Comment thread backend/app/database/albums.py Outdated
Comment thread backend/app/database/albums.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
backend/app/database/albums.py (3)

194-201: Optional: Simplify by removing unreachable else clause.

The if sanitized_ids: check is redundant because line 187-188 already raises ValueError if the list is empty. The else clause (lines 200-201) is unreachable dead code.

Apply this diff to simplify:

-        # Efficient single query with parameterized IN clause
-        if sanitized_ids:
-            # Generate placeholders safely based on list length
-            placeholders = ",".join(["?"] * len(sanitized_ids))
-            query = f"SELECT id FROM images WHERE id IN ({placeholders})"
-            cursor.execute(query, sanitized_ids)  # Pass string IDs directly
-            valid_images = [row[0] for row in cursor.fetchall()]
-        else:
-            valid_images = []
+        # Efficient single query with parameterized IN clause
+        # Generate placeholders safely based on list length
+        placeholders = ",".join(["?"] * len(sanitized_ids))
+        query = f"SELECT id FROM images WHERE id IN ({placeholders})"
+        cursor.execute(query, sanitized_ids)  # Pass string IDs directly
+        valid_images = [row[0] for row in cursor.fetchall()]

Note: The security approach is excellent - placeholders derived from sanitized list length and all values parameterized correctly prevents SQL injection.


206-211: Optional: Remove redundant explicit commit.

The executemany approach with parameterized query is secure and efficient. However, the explicit conn.commit() on line 211 is redundant because the get_db_connection() context manager already commits on successful exit (see connection.py line 28).

Apply this diff:

         # Insert into album_images using executemany
         cursor.executemany(
             "INSERT OR IGNORE INTO album_images (album_id, image_id) VALUES (?, ?)",
             [(album_id, img_id) for img_id in valid_images],
         )
-        conn.commit()

The context manager will handle the commit automatically, making the code cleaner and more consistent with other functions using get_db_connection() (like db_delete_album and db_remove_image_from_album).


213-213: Nitpick: Remove trailing whitespace.

This line appears to contain only whitespace characters.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 009f36f and e3ea331.

📒 Files selected for processing (1)
  • backend/app/database/albums.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
backend/app/database/albums.py (1)
backend/app/database/connection.py (1)
  • get_db_connection (8-32)
🔇 Additional comments (4)
backend/app/database/albums.py (4)

171-175: Excellent security documentation.

The docstring clearly communicates the security approach and UUID support, making the function's behavior transparent to other developers.


176-178: Good defensive validation.

Type checking the input prevents runtime errors downstream and provides clear feedback to callers.


180-188: Proper string sanitization that maintains UUID support.

The validation correctly keeps IDs as strings, strips whitespace, and raises a clear error when no valid IDs are provided. This addresses the past feedback about integer conversion breaking UUID functionality.


203-204: Clear error handling for non-existent IDs.

Explicitly raising an error when none of the IDs exist provides better feedback than silently succeeding with no changes.

@Theminacious
Copy link
Copy Markdown

Hey, this looks good. Let me know if you need help with fixing lint or writing additional tests.

@g-k-s-03
Copy link
Copy Markdown
Contributor Author

@rahulharpal1603, this issue is solved. Let me know if the issue needs any updates or not

@g-k-s-03
Copy link
Copy Markdown
Contributor Author

g-k-s-03 commented Jan 1, 2026

@rahulharpal1603,
All requested changes have been applied. Ready for review again. Feedback appreciated!

@rohan-pandeyy rohan-pandeyy merged commit e3ee7e6 into AOSSIE-Org:main May 14, 2026
7 checks passed
@rohan-pandeyy
Copy link
Copy Markdown
Contributor

Thank you for your contribution @g-k-s-03!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: SQL injection risk in db_add_images_to_album due to dynamic IN-clause constructio

3 participants