जब C++ वेब से मिलता है: क्यों सुरक्षा आपका सबसे बड़ा सिरदर्द है
\n\nक्या आपने कभी सोचा है कि हैकर्स C++ अनुप्रयोगों से इतना प्यार क्यों करते हैं? नहीं, इसलिए नहीं कि कोड जटिल है। बल्कि इसलिए कि प्रदर्शन की खोज में डेवलपर्स अक्सर C++ सुरक्षा के बारे में भूल जाते हैं। और वे इसकी कीमत उपयोगकर्ता डेटा, प्रतिष्ठा और पैसे से चुकाते हैं।
\n\nकल्पना करें: आपने C++ में एक शानदार सर्वर लिखा है जो बिजली की गति से अनुरोधों को संसाधित करता है। लेकिन एक अनएस्केप्ड इनपुट — और हमलावर पूरे डेटाबेस को चुरा लेता है। या, इससे भी बुरा, एक स्क्रिप्ट डालता है जो साइट के सभी विज़िटरों के सत्र चुरा लेती है। परिचित लगता है? यदि नहीं — बढ़िया, इसका मतलब है कि आप समय पर यह लेख पढ़ रहे हैं।
\n\nइस सामग्री में, हम वेब अनुप्रयोगों पर दो सबसे खतरनाक हमलों — SQL इंजेक्शन और क्रॉस-साइट स्क्रिप्टिंग (XSS) — का विश्लेषण करेंगे और दिखाएंगे कि C++ में विशेष रूप से उनसे कैसे बचाव किया जाए। कोई जादू नहीं, वास्तविक कोड उदाहरणों के साथ। चलिए शुरू करते हैं।
\n\nSQL इंजेक्शन: कैसे हैकर्स आपकी क्वेरी को हथियार में बदल देते हैं
\n\nSQL इंजेक्शन तब होता है जब कोई हमलावर इनपुट फ़ील्ड (जैसे लॉगिन या खोज क्वेरी) में SQL कोड का एक टुकड़ा डालता है। यदि आपका एप्लिकेशन इस इनपुट को आँख मूंदकर क्वेरी में डालता है, तो उपयोगकर्ता को नाम से खोजने के बजाय, डेटाबेस कुछ ऐसा निष्पादित करेगा जैसे DROP TABLE users। या, इससे भी बुरा, सभी पासवर्ड दे देगा।
शुरुआती की विशिष्ट गलती (और इससे कैसे बचें)
\n\nइस कोड को देखें। यह हानिरहित लगता है, लेकिन यह एक टाइम बम है:
\n\n// खतरनाक! ऐसा कभी न करें\nstd::string username = getUserInput(); // उपयोगकर्ता ने दर्ज किया: ' OR '1'='1\nstd::string query = "SELECT * FROM users WHERE username = '" + username + "'";\n// परिणाम: SELECT * FROM users WHERE username = '' OR '1'='1'\n// सभी उपयोगकर्ताओं को लौटाएगा!\n\nसमस्या देखी? यदि उपयोगकर्ता ' OR '1'='1 दर्ज करता है, तो क्वेरी पूरी तालिका लौटाएगी। और यदि '; DROP TABLE users; -- दर्ज करता है, तो अलविदा, डेटाबेस।
सही दृष्टिकोण: पैरामीटरीकृत क्वेरी
\n\nC++ में SQL इंजेक्शन से बचाव का एकमात्र विश्वसनीय तरीका पैरामीटरीकृत क्वेरी का उपयोग करना है। डेटाबेस स्वयं कोड और डेटा के बीच अंतर करता है। यहाँ बताया गया है कि यह libpqxx (PostgreSQL के लिए) या MySQL Connector/C++ लाइब्रेरी के साथ कैसा दिखता है:
\n\n#include <iostream>\n#include <pqxx/pqxx> // PostgreSQL के लिए libpqxx\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 // पैरामीटरीकृत क्वेरी: $1 एक पैरामीटर है\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ध्यान दें: हम स्ट्रिंग संयोजन के बजाय txn.exec_params का उपयोग कर रहे हैं। डेटाबेस स्वयं विशेष वर्णों को एस्केप करता है। भले ही उपयोगकर्ता ' OR '1'='1 दर्ज करे, इसे SQL कमांड के भाग के रूप में नहीं, बल्कि एक स्ट्रिंग के रूप में माना जाएगा।
यदि आप रॉ SQLite का उपयोग कर रहे हैं तो क्या करें?
\n\nSQLite के साथ भी सुरक्षित रूप से काम किया जा सकता है। sqlite3_prepare_v2 और sqlite3_bind_text का उपयोग करें:
#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