Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions python/tester.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

26 changes: 26 additions & 0 deletions python/tester1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# sql_injection.py
import sqlite3
from flask import Flask, request

app = Flask(__name__)
DB = "test.db"

def init_db():
conn = sqlite3.connect(DB)
conn.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, username TEXT, password TEXT)")
conn.execute("INSERT OR IGNORE INTO users (id, username, password) VALUES (1, 'alice', 'passw0rd')")
conn.commit()
conn.close()

@app.route("/user")
def user():
init_db()
username = request.args.get("username", "")
# WARNING: vulnerable to SQL injection
query1 = "SELECT id, username FROM users WHERE username = '%s'" % username
Comment on lines +18 to +20
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Static Code Analysis Risk: Injection - Tainted SQL string

User-controlled input from Flask request data or route parameters is concatenated directly into a SQL query string using string formatting operations such as +, %, .format(), or f-strings. This allows an attacker to inject arbitrary SQL commands by crafting malicious input values. Successful exploitation can lead to unauthorized reading, modification, or deletion of database contents, and in some cases, full compromise of the underlying server.

Recommendation: Use parameterized queries instead of string concatenation to build SQL statements. With SQLAlchemy, pass user input as bound parameters using sqlalchemy.text() with :param placeholders (e.g., db.execute(text("SELECT * FROM users WHERE id = :user_id"), {"user_id": user_input})). Alternatively, use SQLAlchemy's ORM query interface, which handles parameterization automatically.

Severity: Medium ⚠️
Status: Open 🔴

References:

  1. https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql
  2. https://www.tutorialspoint.com/sqlalchemy/sqlalchemy_quick_guide.htm
  3. https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-more-specific-text-with-table-expression-literal-column-and-expression-column

More details:

🌻 View in Arnica


Take action by replying with an [arnica] command 💬

Actions

Use [arnica] or [a] to interact with the Arnica bot to acknowledge or dismiss code risks.

To acknowledge the finding as a valid code risk: [arnica] ack <acknowledge additional details>

To dismiss the risk with a reason: [arnica] dismiss <fp|accept|capacity> <dismissal reason>

Examples

  • [arnica] ack This is a valid risk and I'm looking into it

  • [arnica] dismiss fp Dismissed - Risk Not Accurate: (i.e. False Positive)

  • [arnica] dismiss accept Dismiss - Risk Accepted: Allow the risk to exist in the system

  • [arnica] dismiss capacity Dismiss - No Capacity: This will need to wait for a future sprint

Comment on lines +18 to +20
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Static Code Analysis Risk: Software and Data Integrity Failures - Tainted SQL string

User-controlled input from a Django request object is concatenated or interpolated directly into a string that begins with a SQL keyword (such as SELECT, INSERT, UPDATE, DELETE, DROP, etc.). This constructs a raw SQL query using untrusted data without parameterization, creating a SQL injection vulnerability. An attacker can craft malicious input to manipulate the query logic, potentially reading, modifying, or deleting arbitrary data in the database, bypassing authentication, or executing administrative operations.

Recommendation: Use parameterized queries instead of string concatenation or formatting to include user input in SQL statements. When using Django's cursor.execute(), pass user-supplied values as the second argument (e.g., cursor.execute("SELECT * FROM table WHERE id = %s", [user_id])). Preferably, use the Django ORM (e.g., MyModel.objects.filter(...)) to avoid writing raw SQL entirely. If raw SQL is necessary, never use +, %, .format(), or f-strings to embed request data into the query string.

Severity: Low ⬇️
Status: Open 🔴

References:

  1. https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection

More details:

🌻 View in Arnica


Take action by replying with an [arnica] command 💬

Actions

Use [arnica] or [a] to interact with the Arnica bot to acknowledge or dismiss code risks.

To acknowledge the finding as a valid code risk: [arnica] ack <acknowledge additional details>

To dismiss the risk with a reason: [arnica] dismiss <fp|accept|capacity> <dismissal reason>

Examples

  • [arnica] ack This is a valid risk and I'm looking into it

  • [arnica] dismiss fp Dismissed - Risk Not Accurate: (i.e. False Positive)

  • [arnica] dismiss accept Dismiss - Risk Accepted: Allow the risk to exist in the system

  • [arnica] dismiss capacity Dismiss - No Capacity: This will need to wait for a future sprint

conn = sqlite3.connect(DB)
cursor = conn.cursor()
cursor.execute(query1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Static Code Analysis Risk: Injection - Sqlalchemy execute raw query

A raw SQL query is being constructed using string concatenation, format strings, percent formatting, or f-strings, and then passed to SQLAlchemy's execute() method. When untrusted input is incorporated into SQL queries through these string-building techniques, an attacker can inject arbitrary SQL commands, leading to unauthorized data access, data modification, or complete database compromise. This pattern bypasses any parameterization that SQLAlchemy would otherwise provide, making the application vulnerable to SQL injection attacks.

Recommendation: Use SQLAlchemy's text() construct with bound parameters (e.g., connection.execute(text("SELECT * FROM users WHERE id = :user_id"), {"user_id": value})) instead of building SQL strings through concatenation or formatting. For more complex queries, use SQLAlchemy's SQL Expression Language, Schema Definition Language, or the ORM query interface, all of which handle parameterization automatically.

Severity: Low ⬇️
Status: Open 🔴

References:

  1. https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-textual-sql
  2. https://www.tutorialspoint.com/sqlalchemy/sqlalchemy_quick_guide.htm
  3. https://docs.sqlalchemy.org/en/14/core/tutorial.html#using-more-specific-text-with-table-expression-literal-column-and-expression-column

More details:

🌻 View in Arnica


Take action by replying with an [arnica] command 💬

Actions

Use [arnica] or [a] to interact with the Arnica bot to acknowledge or dismiss code risks.

To acknowledge the finding as a valid code risk: [arnica] ack <acknowledge additional details>

To dismiss the risk with a reason: [arnica] dismiss <fp|accept|capacity> <dismissal reason>

Examples

  • [arnica] ack This is a valid risk and I'm looking into it

  • [arnica] dismiss fp Dismissed - Risk Not Accurate: (i.e. False Positive)

  • [arnica] dismiss accept Dismiss - Risk Accepted: Allow the risk to exist in the system

  • [arnica] dismiss capacity Dismiss - No Capacity: This will need to wait for a future sprint

Comment on lines +18 to +23
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Static Code Analysis Risk: Injection - SQL injection DB cursor execute

User-controlled data from a Django request object is being interpolated directly into a SQL query string passed to a database cursor's execute() method. When request data is embedded into SQL via string formatting (f-strings, str.format(), % operator, or string concatenation) rather than through parameterized queries, an attacker can inject arbitrary SQL commands. This can lead to unauthorized data access, data modification, data deletion, or in some cases full database server compromise.

Recommendation: Use Django's ORM QuerySets (e.g., Entry.objects.filter(field=value)) instead of raw SQL whenever possible. If raw SQL is necessary, pass user-supplied values as parameters to cursor.execute() using its second argument as a list or tuple — for example, cursor.execute("SELECT * FROM table WHERE col = %s", [user_input]) — rather than interpolating them into the query string. Never use string formatting, f-strings, % formatting, or concatenation to embed request data into SQL statements.

Severity: Medium ⚠️
Status: Open 🔴

References:

  1. https://docs.djangoproject.com/en/3.0/topics/security/#sql-injection-protection

More details:

🌻 View in Arnica


Take action by replying with an [arnica] command 💬

Actions

Use [arnica] or [a] to interact with the Arnica bot to acknowledge or dismiss code risks.

To acknowledge the finding as a valid code risk: [arnica] ack <acknowledge additional details>

To dismiss the risk with a reason: [arnica] dismiss <fp|accept|capacity> <dismissal reason>

Examples

  • [arnica] ack This is a valid risk and I'm looking into it

  • [arnica] dismiss fp Dismissed - Risk Not Accurate: (i.e. False Positive)

  • [arnica] dismiss accept Dismiss - Risk Accepted: Allow the risk to exist in the system

  • [arnica] dismiss capacity Dismiss - No Capacity: This will need to wait for a future sprint

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Static Code Analysis Risk: Injection - Formatted SQL query

This code constructs an SQL query by embedding external values directly into the query string using Python string formatting (the % operator, .format(), or f-strings) and then passes the resulting string to a database cursor's execute() method. Because the interpolated values are not treated as parameters by the database driver, an attacker who controls any of the interpolated inputs can inject arbitrary SQL commands. This can lead to unauthorized data access, data modification, or complete database compromise.

Recommendation: Use parameterized queries (also called prepared statements) by passing a tuple or dictionary of values as the second argument to execute(). For example, replace cursor.execute(f"SELECT * FROM users WHERE id = {user_id}") with cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) (for DB-API 2.0 drivers like psycopg2 or mysql-connector-python). This ensures the database driver properly escapes and binds all values, preventing SQL injection regardless of input content.

Severity: Low ⬇️
Status: Open 🔴

References:

  1. https://stackoverflow.com/questions/775296/mysql-parameterized-queries

More details:

🌻 View in Arnica


Take action by replying with an [arnica] command 💬

Actions

Use [arnica] or [a] to interact with the Arnica bot to acknowledge or dismiss code risks.

To acknowledge the finding as a valid code risk: [arnica] ack <acknowledge additional details>

To dismiss the risk with a reason: [arnica] dismiss <fp|accept|capacity> <dismissal reason>

Examples

  • [arnica] ack This is a valid risk and I'm looking into it

  • [arnica] dismiss fp Dismissed - Risk Not Accurate: (i.e. False Positive)

  • [arnica] dismiss accept Dismiss - Risk Accepted: Allow the risk to exist in the system

  • [arnica] dismiss capacity Dismiss - No Capacity: This will need to wait for a future sprint

row = cursor.fetchone()
conn.close()
return str(row)