C++ Security: Protection Against SQL Injections and XSS in 2024

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

When C++ Meets the Web: Why Security is Your Biggest Headache

\n\n

Have you ever wondered why hackers love C++ applications so much? No, it's not because the code is complex. It's because in the pursuit of performance, developers often forget about C++ security. And they pay for it with user data, reputation, and money.

\n\n

Imagine: you wrote a cool C++ server that processes requests faster than lightning. But one unescaped input — and an attacker dumps the entire database. Or, even worse, injects a script that steals the sessions of all website visitors. Sound familiar? If not — great, that means you're reading this article just in time.

\n\n

In this material, we will break down the two most dangerous attacks on web applications — SQL injections and Cross-Site Scripting (XSS) — and show how to defend against them specifically in C++. No magic, just real code examples. Let's go.

\n\n

SQL Injections: How Hackers Turn Your Query into a Weapon

\n\n

An SQL injection is when an attacker inserts a piece of SQL code into an input field (e.g., a login or search query). If your application blindly substitutes this input into the query, instead of searching for a user by name, the database will execute something like DROP TABLE users. Or, even worse, it will output all passwords.

\n\n

Typical Beginner Mistake (and How to Avoid It)

\n\n

Look at this code. It looks harmless, but it's a ticking time bomb:

\n\n
// DANGEROUS! Never do this\nstd::string username = getUserInput(); // user entered: ' OR '1'='1\nstd::string query = "SELECT * FROM users WHERE username = '" + username + "'";\n// Result: SELECT * FROM users WHERE username = '' OR '1'='1'\n// Returns all users!
\n\n

See the problem? If the user enters ' OR '1'='1, the query returns the entire table. And if they enter '; DROP TABLE users; --, then goodbye, database.

\n\n

The Right Approach: Parameterized Queries

\n\n

The only reliable way to protect against SQL injections in C++ is to use parameterized queries. The database itself distinguishes code from data. Here's how it looks with the libpqxx library (for PostgreSQL) or MySQL Connector/C++:

\n\n
#include <iostream>\n#include <pqxx/pqxx> // libpqxx for PostgreSQL\n\nvoid safeQuery(const std::string& username) {\n    try {\n        pqxx::connection conn("dbname=mydb user=myuser password=mypass");\n        pqxx::work txn(conn);\n        \n        // Parameterized query: $1 is a parameter\n        std::string query = "SELECT * FROM users WHERE username = $1";\n        pqxx::result result = txn.exec_params(query, username);\n        \n        for (auto row : result) {\n            std::cout << "User: " << row["username"].c_str() << std::endl;\n        }\n        txn.commit();\n    } catch (const std::exception &e) {\n        std::cerr << "Error: " << e.what() << std::endl;\n    }\n}\n\nint main() {\n    std::string input;\n    std::cout << "Enter username: ";\n    std::getline(std::cin, input);\n    safeQuery(input);\n    return 0;\n}
\n\n

Notice: we use txn.exec_params instead of string concatenation. The database itself escapes special characters. Even if the user enters ' OR '1'='1, it will be treated as a string, not as part of an SQL command.

\n\n

What If You're Using Raw SQLite?

\n\n

Even with SQLite, you can work safely. Use sqlite3_prepare_v2 and sqlite3_bind_text:

\n\n
#include <sqlite3.h>\n#include <iostream>\n\nvoid safeSQLiteQuery(sqlite3* db, const std::string& username) {\n    sqlite3_stmt* stmt;\n    const char* sql = "SELECT * FROM users WHERE username = ?";\n    \n    if (sqlite3_prepare_v2                

Blogs

Book Recommendations