أمان تطبيقات Swift: أهم 10 ثغرات للمبتدئين
تطوير تطبيقات الجوال وسطح المكتب باستخدام Swift لا يتطلب فقط معرفة بناء الجملة والأطر (frameworks)، بل أيضاً فهم أساسيات الأمن السيبراني. حتى الخطأ البسيط في الكود قد يؤدي إلى تسرب بيانات المستخدم أو اختراق الجهاز. في هذه المقالة، سنستعرض أهم 10 ثغرات شائعة في تطبيقات Swift التي يواجهها المطورون المبتدئون، ونوضح كيفية تجنبها.
1. تخزين البيانات غير الآمن (Insecure Data Storage)
من أكثر الأخطاء شيوعاً حفظ المعلومات الحساسة (كلمات المرور، الرموز المميزة (tokens)، مفاتيح API) في UserDefaults أو في ملفات نصية عادية. يمكن استخراج هذه البيانات بسهولة على الأجهزة المخترقة (jailbroken).
// خطأ: تخزين كلمة المرور في UserDefaultsUserDefaults.standard.set("mySecretPassword", forKey: "userPassword")
// صحيح: استخدام Keychainimport Securitylet password = "mySecretPassword"let keychainItem = [ kSecClass: kSecClassGenericPassword, kSecAttrAccount: "userPassword", kSecValueData: password.data(using: .utf8)!] as CFDictionarySecItemAdd(keychainItem, nil)2. الحقن عبر SQLite و Core Data
استخدام السلاسل النصية غير المعالجة في استعلامات قاعدة البيانات يفتح الباب أمام هجمات الحقن (SQL injections). حتى إذا كنت تستخدم Core Data، فإن المسندات (predicates) غير الآمنة قد تتعرض للهجوم.
// خطأ: الإدراج المباشرlet username = "admin' OR '1'='1"let query = "SELECT * FROM users WHERE name = '\\(username)'"
// صحيح: استخدام الاستعلامات المعلمة (FMDB)let query = "SELECT * FROM users WHERE name = ?"db.executeQuery(query, withArgumentsIn: [username])3. غياب HTTPS و SSL Pinning
استخدام HTTP بدلاً من HTTPS يجعل التطبيق عرضة لهجمات "الرجل في المنتصف" (MITM). حتى مع HTTPS، يُنصح باستخدام SSL Pinning لمزيد من الحماية.
// إعداد HTTPS في Info.plist// <key>NSAppTransportSecurity</key>// <dict>// <key>NSAllowsArbitraryLoads</key>// <false/>// </dict>
// تنفيذ SSL Pinning باستخدام URLSessionlet pinnedKeys = ["yourPublicKeyHash"]let delegate = URLSessionPinningDelegate(pinnedKeys: pinnedKeys)let session = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil)4. خوارزميات التشفير الضعيفة
استخدام خوارزميات التشفير القديمة (MD5, SHA1) أو دوال التشفير المصنوعة يدوياً يجعل البيانات عرضة للخطر. استخدم دائماً المكتبات الحديثة.
// خطأ: MD5let hash = MD5(string: "password")
// صحيح: استخدام CommonCrypto مع SHA256import CommonCryptofunc sha256(_ data: Data) -> Data { var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH)) data.withUnsafeBytes { _ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &hash) } return Data(hash)}5. عدم كفاية التحقق من الإدخال (Input Validation)
غياب التحقق من صحة إدخال المستخدم قد يؤدي إلى هجمات XSS (في WebView) أو تلف البيانات. تحقق من جميع البيانات المدخلة من حيث الطول والتنسيق والمحتوى.
// خطأ: الثقة في الإدخالlet userInput = textField.textwebView.loadHTMLString(userInput!, baseURL: nil)
// صحيح: تعقيم الإدخالfunc sanitizeInput(_ input: String) -> String { return input .replacingOccurrences(of: "&", with: "&") .replacingOccurrences(of: "<", with: "<") .replacingOccurrences(of: ">", with: ">")}6. تسرب البيانات عبر السجلات والتصحيح
ترك print() أو NSLog في الإصدار النهائي (production) قد يكشف بيانات حساسة. استخدم التجميع الشرطي للرسائل التصحيحية.
// خطأ: تسجيل في الإصدار النهائي