Swift في الخط الأمامي: لماذا الأمان ليس خيارًا بل ضرورة
\nأنت تكتب بلغة Swift، وتفتخر بالأداء وجمال الكود. ولكن هل فكرت يومًا في مدى ضعف تطبيقك أمام الهجمات؟ حقن SQL وXSS (البرمجة النصية عبر المواقع) ليست مجرد قصص مخيفة من الكتب الدراسية. إنها تهديدات حقيقية قد تكلفك بيانات المستخدمين وسمعتك وأموالك.
\nفي هذه المقالة، سنشرح كيفية حماية تطبيق Swift (سواء كان عميل iOS أو جزء الخادم باستخدام Vapor) من أخطر نوعين من الهجمات. لا ماء — فقط أمثلة عملية، وحلول جاهزة، وكود حي. هيا بنا!
\n\nحقن SQL في Swift: كيف "يخدع" المخترقون قاعدة البيانات
\nتخيل: مستخدم يدخل في حقل النص '; DROP TABLE Users; --. إذا قمت بإدراج هذه السلسلة مباشرة في استعلام SQL، فستنفذ قاعدة البيانات أمر الحذف. كلاسيكيات المجال.
في Swift، تظهر هذه الثغرة غالبًا في أطر الخادم (Vapor, Kitura) أو عند العمل مع Core Data وSQLite من خلال أغلفة غير آمنة.
\n\nمثال خطير: كيف لا تفعل
\nimport SQLite\n\nlet username = userInput.text // "admin' OR '1'='1"\nlet query = "SELECT * FROM users WHERE name = '\\(username)'"\ntry db.execute(query) // تهديد! استعلام مخترق\n\nهذا الكود هو قطعة قماش حمراء للثور. يمكن للمهاجم الوصول إلى أي بيانات أو تدمير الجدول.
\n\nالنهج الصحيح: الاستعلامات المعلمة
\nالقاعدة الذهبية: لا تقم أبدًا بإدراج بيانات المستخدم مباشرة في سلسلة الاستعلام. استخدم التوسيم (parameterization).
\nimport SQLite\n\nlet db = try Connection("path/to/db.sqlite3")\nlet users = Table("users")\nlet name = Expression<String>("name")\n\nlet username = userInput.text // "admin' OR '1'='1"\nlet query = users.filter(name == username) // آمن\nlet result = try db.prepare(query)\n\nمكتبة SQLite.swift تقوم بتعقيم الأحرف الخاصة بنفسها. بالنسبة لـ Vapor مع Fluent، استخدم النموذج والمرشحات:
\nimport Fluent\nimport Vapor\n\nstruct UserController: RouteCollection {\n func login(req: Request) async throws -> String {\n let input = try req.content.decode(LoginRequest.self)\n // Fluent يقوم تلقائيًا بتوسيم الاستعلام\n let user = try await User.query(on: req.db)\n .filter(\\.$name == input.username)\n .first()\n return user?.name ?? "Not found"\n }\n}\n\nهام: حتى إذا كنت تستخدم SQL الخام (raw) في Vapor، استخدم SQLBind لربط المعاملات.
ORM وCore Data: وهم الأمان
\nيعتقد العديد من المطورين أن Core Data أو Fluent تحمي تلقائيًا من الحقن. هذا صحيح — إذا لم تستخدم NSExpression مع تنسيق السلاسل أو SQL الخام. لكن تذكر: أي NSPredicate مبني عبر استيفاء السلاسل (string interpolation) هو خطر.
// خطير\nlet predicate = NSPredicate(format: "name == %@", userInput) // آمن؟\n// لا! إذا كان userInput يحتوي على '%'، فقد يحدث حقن عبر الاستبدال.\n\nاستخدم دائمًا %@ مع المتغيرات، وليس %K مع المفاتيح، ولا تقم أبدًا بإدراج السلاسل عبر \\().
هجمات XSS في Swift: عندما يقوم المهاجم بحقن JavaScript
\nXSS هي هجوم يتم فيه تنفيذ سكريبت ضار في متصفح المستخدم. بالنسبة لتطبيقات iOS، يكون XSS ذا صلة عند استخدام WKWebView لعرض محتوى HTML (مثل في خلاصة الأخبار أو الدردشات).
سيناريو واقعي: دردشة مع تنسيق HTML
\nيكتب المستخدم: مرحبًا! <script>alert('XSS')</script>. إذا قمت بعرض هذه الرسالة في WebView دون معالجة — سيتم تنفيذ السكريبت.
// خطير\nlet html = "<div>\\(message.text)</div>"\nwebView.loadHTMLString(html, baseURL: nil)\n