Rust ضد هجمات SQL injection و XSS: كتابة تطبيقات ويب آمنة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

لماذا Rust هو المعيار الجديد للأمان في الويب؟

\n

عندما يتعلق الأمر بأمان الويب، يتذكر العديد من المطورين فوراً ORM والاستعلامات المُعدة وترميز HTML. ولكن ماذا لو أخبرتك أن لغة البرمجة نفسها يمكنها تحمل الجزء الأكبر من هذا العمل؟ هذا بالضبط ما يفعله Rust - اللغة التي لا تغفر الأخطاء، ولكنها أيضاً لا تسمح بارتكابها.

\n\n

في هذه المقالة، سنشرح كيف يتجلى أمان Rust في اثنين من أكثر الهجمات خطورة على تطبيقات الويب: هجمات SQL injection و XSS (البرمجة النصية عبر المواقع). سترى أمثلة كود حقيقية، ومقارنة مع Python، وستفهم لماذا أصبح Rust الخيار الأول للمشاريع التي يكون فيها ثمن الخطأ هو أمان المستخدمين.

\n\n

كيف يمنع Rust هجمات SQL injection: من النظرية إلى التطبيق

\n

هجوم SQL injection هو أمر كلاسيكي. نعلم جميعاً أنه يجب استخدام الاستعلامات المُعدة. ولكن في Rust، هذا النمط مدمج في ثقافة اللغة على مستوى الأنواع ونظام borrow checker.

\n\n

مقارنة الأساليب: Python مقابل Rust

\n

انظر إلى كود Python النموذجي الذي قد يكون عرضة للخطر:

\n
# Python (خطير)\nuser_input = "'; DROP TABLE users; --"\nquery = f"SELECT * FROM users WHERE name = '{user_input}'"\ncursor.execute(query)\n
\n

حتى إذا كنت تستخدم psycopg2، فقد تنسى الترميز عن طريق الخطأ. Rust يجبرك على التفكير بطريقة مختلفة.

\n\n

في Rust مع مكتبة sqlx أو diesel، لا يمكنك ببساطة إدراج سلسلة نصية في الاستعلام - نظام الأنواع لن يسمح بذلك:

\n
// Rust مع sqlx (آمن)\nuse sqlx::PgPool;\n\nlet user_input = "'; DROP TABLE users; --";\nlet user: Option<User> = sqlx::query_as(\n    "SELECT * FROM users WHERE name = $1"\n)\n.bind(&user_input) // ربط آمن من حيث النوع\n.fetch_optional(&pool)\n.await?;\n
\n

لاحظ $1 و .bind(). Rust لا يسمح بإدراج القيمة مباشرة في سلسلة الاستعلام. هذه ليست مجرد اتفاقية - إنها شرط إلزامي للترجمة. أمان Rust يتجلى هنا في أنك لا تستطيع جسدياً إنشاء هجوم SQL injection إذا كنت تستخدم المكتبات الصحيحة.

\n\n

لماذا يعمل هذا على مستوى الأنواع؟

\n

في Rust، سلسلة الاستعلام والبيانات هما نوعان مختلفان. المكتبات مثل sqlx تتحقق من الاستعلامات في مرحلة الترجمة (compile-time checked queries). إذا حاولت القيام بشيء خطير، فإن الكود ببساطة لن يتم ترجمته:

\n
// هذا لن يتم ترجمته!\nlet query = format!("SELECT * FROM users WHERE name = '{}'", user_input);\nsqlx::query(&query); // خطأ: متوقع &str، وليس String مع استبدال\n
\n

نظام الملكية (ownership) والاقتراض (borrowing) لا يسمح لك بابتلاع البيانات الخطيرة عن طريق الخطأ. هذا ليس سحراً - إنه انضباط هندسي مدمج في اللغة.

\n\n

الحماية من XSS: الترميز والفحص التلقائي

\n

XSS هو عندما يقوم المهاجم بإدخال نصوص برمجية في HTML الخاص بك. في Rust، يمكنك الحماية على مستويات متعددة، حيث تحدث بعض الفحوصات حتى قبل تشغيل البرنامج.

\n\n

محركات القوالب ذات الترميز التلقائي

\n

في Python، تستخدم jinja2 مع autoescape=true. في Rust، يوجد askama أو maud، اللذان يفعلان نفس الشيء ولكن بأمان من حيث النوع. إليك مثال مع askama:

\n
// Rust مع askama (محرك قوالب)\nuse askama::Template;\n\n#[derive(Template)]\n#[template(source = "<h1>Hello, {{ name }}!</h1>", ext = "html")]\nstruct HelloTemplate {\n    name: String,\n}\n\nfn main() {\n    let t = HelloTemplate {\n        name: "<script>alert('XSS')</script>".to_string(),\n    };\n    let rendered = t.render().unwrap();\n    // الإخراج: <h1>Hello, &lt;script&gt;...</h1>\n    // تم ترميز الوسوم تلقائياً!\n}\n
\n

لاحظ في الأسفل

المدونات

توصيات الكتب