User-provided inputs must be sanitized before being used to generate a SQL database query. An untrusted input can be intentionally built by an attacker in order to run unwanted query statements, possibly allowing the attacker to read, modify, or delete database content.
1#include <iostream>
2#include <sqlite3.h>
3
4int sqlInjectionNoncompliant(const std::string& username, const std::string& password) {
5 sqlite3* db;
6 sqlite3_open("users.db", &db);
7
8 std::string query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "';";
9
10 sqlite3_stmt* stmt;
11 // Noncompliant: This code takes a username and password from the user, constructs an SQL query, and tries to authenticate the user against an SQLite database.
12 if (sqlite3_prepare_v2(db, query.c_str(), -1, &stmt, nullptr) == SQLITE_OK) {
13 if (sqlite3_step(stmt) == SQLITE_ROW) {
14 std::cout << "Authentication successful.\n";
15 return 1;
16 }
17 }
18
19 std::cout << "Authentication failed.\n";
20 return 0;
21}
1#include <iostream>
2#include <sqlite3.h>
3
4int sqlInjectionCompliant(const std::string& username, const std::string& password) {
5 sqlite3* db;
6 sqlite3_open("users.db", &db);
7
8 std::string query = "SELECT * FROM users WHERE username = ? AND password = ?;";
9
10 sqlite3_stmt* stmt;
11 if (sqlite3_prepare_v2(db, query.c_str(), -1, &stmt, nullptr) == SQLITE_OK) {
12 // Compliant: Used parameterized queries or prepared statements to avoid sql injection
13 sqlite3_bind_text(stmt, 1, username.c_str(), -1, SQLITE_STATIC);
14 sqlite3_bind_text(stmt, 2, password.c_str(), -1, SQLITE_STATIC);
15 if (sqlite3_step(stmt) == SQLITE_ROW) {
16 std::cout << "Authentication successful.\n";
17 return 1;
18 }
19 }
20
21 std::cout << "Authentication failed.\n";
22 return 0;
23}