أمان تطبيقات Swift: أهم 10 ثغرات أمنية للمبتدئين
\n\nيتطلب التطوير باستخدام Swift لنظامي iOS وmacOS اهتمامًا خاصًا بالأمان. حتى الأخطاء الصغيرة يمكن أن تؤدي إلى تسرب البيانات أو اختراق التطبيق. في هذه المقالة، سنستعرض 10 من أكثر الثغرات الأمنية شيوعًا التي يواجهها المطورون المبتدئون، وسنوضح كيفية تجنبها.
\n\n1. تخزين البيانات غير الآمن في UserDefaults
\nيقوم العديد من المبتدئين بحفظ البيانات الحساسة (كلمات المرور، الرموز المميزة) في UserDefaults. هذه منطقة مشتركة، ويتم تخزين البيانات بنص واضح.
// ❌ خطير\nUserDefaults.standard.set("secret_password", forKey: "userPass")\n\n// ✅ آمن — نستخدم Keychain\nimport Security\nlet query: [String: Any] = [\n kSecClass as String: kSecClassGenericPassword,\n kSecAttrAccount as String: "userPass",\n kSecValueData as String: "secret_password".data(using: .utf8)!\n]\nSecItemAdd(query as CFDictionary, nil)\n\n\n2. حقن SQL في Core Data
\nاستخدام المسندات النصية مع إدخال المستخدم يفتح الباب أمام حقن SQL.
\n// ❌ ضعيف\nlet input = "admin' OR '1'='1"\nlet predicate = NSPredicate(format: "name == %@", input)\n\n// ✅ آمن — نستخدم استعلامات ذات معلمات\nlet safePredicate = NSPredicate(format: "name == %@", input)\n\n\n3. عدم التحقق من صحة الإدخال
\nالثقة في إدخال المستخدم هي أحد الأخطاء الرئيسية. يمكن للمهاجم إرسال بيانات ضارة عبر حقول النص.
\nfunc processUserInput(_ text: String) {\n // ❌ نمرر أي إدخال\n let url = URL(string: "https://api.example.com/search?q=\\(text)")\n \n // ✅ نتحقق ونقوم بالترميز\n guard let encoded = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return }\n let safeUrl = URL(string: "https://api.example.com/search?q=\\(encoded)")\n}\n\n\n4. اتصال شبكة غير آمن (HTTP بدلاً من HTTPS)
\nاستخدام HTTP يجعل البيانات عرضة للاعتراض. استخدم دائمًا HTTPS.
\n// ❌ خطير\nlet config = URLSessionConfiguration.default\nconfig.waitsForConnectivity = false\n\n// ✅ آمن — فرض HTTPS\nlet config = URLSessionConfiguration.default\nconfig.connectionProxyDictionary?.removeAll()\nconfig.tlsMinimumSupportedProtocolVersion = .TLSv12\n\n\n5. تسرب البيانات عبر السجلات
\nغالبًا ما يترك المطورون print() مع بيانات حساسة في الإصدار النهائي.
// ❌ خطير\nprint("User token: \\(token)")\n\n// ✅ آمن — نستخدم التجميع الشرطي\n#if DEBUG\nprint("Debug: token length = \\(token.count)")\n#endif\n\n\n6. إدارة غير صحيحة للذاكرة (دورات الاحتفاظ)
\nيمكن أن تؤدي تسريبات الذاكرة إلى هجمات حجب الخدمة (DoS). استخدم المراجع الضعيفة في الإغلاقات.
\n// ❌ تسريب ذاكرة\nclass ViewController: UIViewController {\n var handler: (() -> Void)?\n override func viewDidLoad() {\n handler = {\n self.view.backgroundColor = .red // مرجع قوي\n }\n }\n}\n\n// ✅ آمن — مرجع ضعيف\nhandler = { [weak self] in\n self?.view.backgroundColor = .red\n}\n\n\n7. عدم التحقق من صحة مخططات URL
\nيمكن للتطبيقات الاحتيالية اعتراض مخططات URL الخاصة بتطبيقك.
\n// ❌ ضعيف\nfunc application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {\n // معالجة أي URL\n return true\n}\n\n// ✅ آمن — نتحقق من المصدر\nfunc application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {\n guard let sourceApp = options[.sourceApplication] as? String,\n sourceApp == "com.trusted.app" else {\n return false\n }\n // معالجة URL\n return true\n}\n\n\n