Во второй части этой серии, посвященной атакам Deep Link на iOS, мы рассмотрим, как выявлять различные уязвимости в iOS Deep Link, и продемонстрируем техническую демонстрацию их эксплуатации.
Сценарий – 1: Фишинг DeepLink
Фишинг с глубокими ссылками — это проблема, которую часто упускают из виду, когда речь идет об атаках/тестировании глубоких ссылок на iOS. Фишинг обычно происходит, когда кто-то создает поддельный веб-сайт или приложение, которое выглядит точно так же, как надежное, пытаясь обманом заставить людей выдать важную личную информацию.
Глубокие ссылки с использованием схем URL-адресов могут позволить двум разным приложениям зарегистрироваться и использовать один и тот же URL-адрес. Например, можно зарегистрировать ту же схему URL, которую Twitter использует для своего приложения. Таким образом, когда запускается глубокая ссылка, предназначенная для Twitter, их приложение может открываться вместе с приложением Twitter, если приложение Twitter не установлено на устройстве, тогда приложение можно открыть напрямую.
Представьте себе, что есть приложение для iOS под названием 8ksec, которое позволяет пользователям входить в систему. Это приложение имеет настраиваемую схему глубоких ссылок eightksec://login, которая напрямую ведет пользователей на панель входа в систему.
Злоумышленник может создать панель входа в систему, которая выглядит аналогично и может использовать ту же схему глубоких ссылок eightksec://login, как показано ниже.
Жертва предполагает, что, щелкнув схему глубокой ссылки, она откроет легитимное приложение.
Если подлинное приложение не установлено, откроется вредоносное приложение. Если установлено подлинное приложение, пользователю будет предложено два варианта на выбор, что позволит ему перейти либо к подлинному приложению, либо к вредоносному приложению.
Защита
Приоритет использования универсальных ссылок перед пользовательскими схемами URL-адресов может быть оптимальным средством предотвращения таких атак.
Сценарий 2: Недостаточная Проверка URL
Когда дело доходит до глубоких ссылок, неадекватная проверка URL-адреса обычно относится к ситуации, когда глубокая ссылка используется для загрузки веб-адреса в веб-представлении, но надлежащая проверка этого URL-адреса не выполняется. Многочисленные приложения реализуют схемы Deep Link для интеграции веб-представлений в свою функциональность, но они часто пренебрегают проверкой URL. Эта оплошность может привести к эксплуатации этих схем, в результате чего приложение будет загружать произвольные и потенциально небезопасные URL-адреса.
Мы наблюдали эту проблему, часто возникающую в приложениях iOS на основе React. В этих случаях сначала разрабатывается веб-приложение, а затем интегрируется в мобильное приложение с использованием различных SDK. Затем глубокие ссылки используются для загрузки этих веб-приложений в мобильное приложение.
Кроме того, еще одно возможное применение загрузки URL-адресов через глубокие ссылки — это контекст отображения разделов «Условия и положения», «Справка» и «Поддержка» в мобильном приложении. Это часто выгодно, поскольку эти разделы обычно уже определены и доступны в веб-приложении. Пример,
Мы внесли некоторые изменения в файл AppDelegate.swift DVIA-v2, чтобы поэкспериментировать с этим сценарием. Если вы планируете продолжить, замените файл AppDelegate.swift приведенным ниже кодом и снова запустите приложение.
import UIKit
import WebKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, WKUIDelegate {
var window: UIWindow?
var webView: WKWebView!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize the window
window = UIWindow(frame: UIScreen.main.bounds)
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: window!.bounds, configuration: webConfiguration)
webView.uiDelegate = self
// Load the initial URL
let initialURL = URL(string: "https://8ksec.io")
let initialRequest = URLRequest(url: initialURL!)
webView.load(initialRequest)
// Set the web view as the root view controller's view
let viewController = UIViewController()
viewController.view = webView
window?.rootViewController = viewController
window?.makeKeyAndVisible()
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "dvia", url.host == "openurl" {
if let urlString = url.queryParameters?["url"], let url = URL(string: urlString) {
let myRequest = URLRequest(url: url)
webView.load(myRequest)
return true
}
}
return false
}
}
extension URL {
var queryParameters: [String: String]? {
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else {
return nil
}
var parameters = [String: String]()
for item in queryItems {
parameters[item.name] = item.value
}
return parameters
}
}
Приведенный выше код содержит потенциальную проблему со слабой проверкой хоста. Это означает, что код не выполняет тщательную проверку или проверку хост-компонента URL-адреса ссылки на контент. Метод open url проверяет, является ли схема dvia, а хост — openurl, чтобы определить, должен ли он обрабатывать глубокую ссылку. Однако он не выполняет никакой дополнительной проверки значения хоста и не проверяет, соответствует ли оно доверенному или ожидаемому значению.
Чтобы эксплуатировать его, нам сначала нужно определить схему Deep Link для него, мы можем просмотреть его из файла Info.plist, чтобы идентифицировать его, пожалуйста, просмотрите наш предыдущий блог. Как только мы идентифицируем схему глубокой ссылки как dvia://, нам нужно перейти в файл AppDelegate.swift, чтобы определить оставшуюся часть схемы.
Приведенный выше код проверяет, является ли схема dvia, хостом является opeurl и параметром как url, если все эти три условия удовлетворены, он загружает созданный запрос в экземпляр webView, вызывая webView.load(myRequest), который инструктирует веб-представление для загрузки указанного URL-адреса, который делает нашу схему такой:
Назначение приложения — загрузить https://8ksec.io , что оно и делает при открытии приложения, но давайте попробуем открыть на нем произвольный URL-адрес через схему DeepLink.
Нажмите на ссылку выше.
Очевидно, что в приложении был загружен неограниченный URL-адрес. Точно так же эта уязвимость может быть использована для выполнения фишинговых атак.
Защита
Поддерживайте белый список доверенных доменов или URL-адресов, которые приложению разрешено загружать через глубокие ссылки. Проверяйте входящие URL-адреса по этому белому списку, чтобы убедиться, что они исходят из надежных источников.
Сценарий – 3: HTML-Инъекция
Внедрение HTML происходит, когда веб-приложение пренебрегает адекватной проверкой и очисткой ввода пользователя перед его представлением на веб-странице. Эта уязвимость системы безопасности позволяет злоумышленнику вставить и выполнить неавторизованный код на уязвимом веб-сайте или в приложении.
Когда значения параметров из прямой ссылки передаются в веб-представление, существует потенциальный риск внедрения HTML. Эта уязвимость позволяет злоумышленнику создавать определенные полезные нагрузки, которые могут перенаправлять пользователей на вредоносные веб-сайты или приложения.
Чтобы продемонстрировать этот сценарий, замените файл AppDelegate.swift приведенным ниже кодом.
import UIKit
import WebKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, WKUIDelegate {
var window: UIWindow?
var webView: WKWebView!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize the window
window = UIWindow(frame: UIScreen.main.bounds)
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: window!.bounds, configuration: webConfiguration)
webView.uiDelegate = self
// Load the initial URL
let initialURL = URL(string: "https://8ksec.io")
let initialRequest = URLRequest(url: initialURL!)
webView.load(initialRequest)
// Set the web view as the root view controller's view
let viewController = UIViewController()
viewController.view = webView
window?.rootViewController = viewController
window?.makeKeyAndVisible()
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "dvia", url.host == "display" {
if let urlString = url.queryParameters?["message"]?.removingPercentEncoding {
let webViewController = UIViewController()
let webView = WKWebView(frame: webViewController.view.bounds)
// Create a dummy baseURL with a file path
let dummyBaseURL = URL(fileURLWithPath: NSTemporaryDirectory())
webView.loadHTMLString(urlString, baseURL: dummyBaseURL)
webViewController.view.addSubview(webView)
// Add a "Close" button to dismiss the web view
let closeButton = UIBarButtonItem(barButtonSystemItem: .close, target: self, action: #selector(closeWebView))
webViewController.navigationItem.rightBarButtonItem = closeButton
// Create a navigation controller to embed the web view controller
let navigationController = UINavigationController(rootViewController: webViewController)
// Present the navigation controller
self.window?.rootViewController?.present(navigationController, animated: true, completion: nil)
return true
}
}
return false
}
@objc func closeWebView() {
self.window?.rootViewController?.dismiss(animated: true, completion: nil)
}
}
extension URL {
var queryParameters: [String: String]? {
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else {
return nil
}
var parameters = [String: String]()
for item in queryItems {
parameters[item.name] = item.value
}
return parameters
}
}
В приведенном выше коде параметр сообщения извлекается из глубокой ссылки и присваивается переменной urlString. Однако код не выполняет никакой проверки или очистки этих входных данных. Следовательно, если злоумышленник создаст глубокую ссылку с параметром вредоносного сообщения, содержащим код HTML или JavaScript, он будет напрямую загружен и выполнен в веб-представлении.
Чтобы воспользоваться этой уязвимостью, злоумышленник может создать специально созданную полезную нагрузку HTML, содержащую гиперссылку, предназначенную для перенаправления пользователей на вредоносное веб-приложение, как показано ниже:
dvia://display?message=%3Ca%20href%3D%22http%3A%2F%2Fdamnvulnerableiosapp.com%2F%22%3Eopen%3C%2Fa%3E
Нажмите на ссылку выше.
Когда жертва нажимает на ссылку, открывается вредоносный URL.
Защита
Прежде чем загружать HTML-контент в веб-представление, важно подумать о кодировании или очистке выходных данных для параметра «сообщение». Этот шаг включает в себя фильтрацию или экранирование тегов HTML или специальных символов, которые могут потенциально выполнять вредоносный код.
Сценарий – 4: Атаки CSRF
CSRF или подделка межсайтовых запросов — это брешь в системе безопасности, которая возникает, когда вредоносный веб-сайт обманом заставляет браузер пользователя неосознанно отправлять несанкционированные запросы на другой веб-сайт, на котором пользователь аутентифицирован. Эта уязвимость не ограничивается только веб-приложениями; его также можно использовать с помощью глубоких ссылок в iOS или других платформах.
В iOS-приложениях CSRF-атаки часто происходят, когда действия выполняются через глубокие ссылки. Похожий случай можно найти в этом отчете о хакероне - https://hackerone.com/reports/805073, где злоумышленник смог манипулировать пользователями, чтобы они следовали за ними через CSRF, предоставив схему глубоких ссылок.
Финансовые приложения, которые включают в себя функцию прямых ссылок для повторных платежных транзакций, могут служить еще одной потенциальной мишенью для этой уязвимости. В этом сценарии злоумышленники используют функцию глубоких ссылок, предоставляя жертвам схемы глубоких ссылок, что позволяет им выполнять несанкционированные и произвольные транзакции.
Чтобы продемонстрировать этот сценарий, замените файл AppDelegate.swift приведенным ниже кодом.
import UIKit
import WebKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, WKUIDelegate {
var window: UIWindow?
var webView: WKWebView!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize the window
window = UIWindow(frame: UIScreen.main.bounds)
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: window!.bounds, configuration: webConfiguration)
webView.uiDelegate = self
// Load the initial URL
let initialURL = URL(string: "https://8ksec.io")
let initialRequest = URLRequest(url: initialURL!)
webView.load(initialRequest)
// Set the web view as the root view controller's view
let viewController = UIViewController()
viewController.view = webView
window?.rootViewController = viewController
window?.makeKeyAndVisible()
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "dvia", url.host == "payment" {
if let urlString = url.queryParameters?["user"]?.removingPercentEncoding {
let message = "Payment has been sent to \(urlString)"
let alertController = UIAlertController(title: "Payment", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
window?.rootViewController?.present(alertController, animated: true, completion: nil)
return true
}
}
return false
}
@objc func closeWebView() {
self.window?.rootViewController?.dismiss(animated: true, completion: nil)
}
}
extension URL {
var queryParameters: [String: String]? {
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else {
return nil
}
var parameters = [String: String]()
for item in queryItems {
parameters[item.name] = item.value
}
return parameters
}
}
Приведенный выше код проверяет, является ли схема URL-адреса dvia и хостом является payment. Он принимает параметр для пользователя и инициирует платеж для этого пользователя. Злоумышленник может создать схемы deeplink, как показано ниже, при выполнении платеж будет выполнен для злоумышленника.
Предоставьте жертве приведенную выше схему deeplink.
Когда злоумышленник активирует схему, щелкнув по ней, произойдет выполнение, что приведет к завершению платежа.
Защита
Схемы Deeplink не должны реализовываться для выполнения конфиденциальных действий в приложении.
При необходимости важно проверить, были ли схемы deeplink активированы изнутри приложения или внешними компонентами.
Сценарий – 1: Фишинг DeepLink
Фишинг с глубокими ссылками — это проблема, которую часто упускают из виду, когда речь идет об атаках/тестировании глубоких ссылок на iOS. Фишинг обычно происходит, когда кто-то создает поддельный веб-сайт или приложение, которое выглядит точно так же, как надежное, пытаясь обманом заставить людей выдать важную личную информацию.
Глубокие ссылки с использованием схем URL-адресов могут позволить двум разным приложениям зарегистрироваться и использовать один и тот же URL-адрес. Например, можно зарегистрировать ту же схему URL, которую Twitter использует для своего приложения. Таким образом, когда запускается глубокая ссылка, предназначенная для Twitter, их приложение может открываться вместе с приложением Twitter, если приложение Twitter не установлено на устройстве, тогда приложение можно открыть напрямую.
Представьте себе, что есть приложение для iOS под названием 8ksec, которое позволяет пользователям входить в систему. Это приложение имеет настраиваемую схему глубоких ссылок eightksec://login, которая напрямую ведет пользователей на панель входа в систему.
Злоумышленник может создать панель входа в систему, которая выглядит аналогично и может использовать ту же схему глубоких ссылок eightksec://login, как показано ниже.
Жертва предполагает, что, щелкнув схему глубокой ссылки, она откроет легитимное приложение.
Если подлинное приложение не установлено, откроется вредоносное приложение. Если установлено подлинное приложение, пользователю будет предложено два варианта на выбор, что позволит ему перейти либо к подлинному приложению, либо к вредоносному приложению.
Защита
Приоритет использования универсальных ссылок перед пользовательскими схемами URL-адресов может быть оптимальным средством предотвращения таких атак.
Сценарий 2: Недостаточная Проверка URL
Когда дело доходит до глубоких ссылок, неадекватная проверка URL-адреса обычно относится к ситуации, когда глубокая ссылка используется для загрузки веб-адреса в веб-представлении, но надлежащая проверка этого URL-адреса не выполняется. Многочисленные приложения реализуют схемы Deep Link для интеграции веб-представлений в свою функциональность, но они часто пренебрегают проверкой URL. Эта оплошность может привести к эксплуатации этих схем, в результате чего приложение будет загружать произвольные и потенциально небезопасные URL-адреса.
Мы наблюдали эту проблему, часто возникающую в приложениях iOS на основе React. В этих случаях сначала разрабатывается веб-приложение, а затем интегрируется в мобильное приложение с использованием различных SDK. Затем глубокие ссылки используются для загрузки этих веб-приложений в мобильное приложение.
Кроме того, еще одно возможное применение загрузки URL-адресов через глубокие ссылки — это контекст отображения разделов «Условия и положения», «Справка» и «Поддержка» в мобильном приложении. Это часто выгодно, поскольку эти разделы обычно уже определены и доступны в веб-приложении. Пример,
Мы внесли некоторые изменения в файл AppDelegate.swift DVIA-v2, чтобы поэкспериментировать с этим сценарием. Если вы планируете продолжить, замените файл AppDelegate.swift приведенным ниже кодом и снова запустите приложение.
import UIKit
import WebKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, WKUIDelegate {
var window: UIWindow?
var webView: WKWebView!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize the window
window = UIWindow(frame: UIScreen.main.bounds)
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: window!.bounds, configuration: webConfiguration)
webView.uiDelegate = self
// Load the initial URL
let initialURL = URL(string: "https://8ksec.io")
let initialRequest = URLRequest(url: initialURL!)
webView.load(initialRequest)
// Set the web view as the root view controller's view
let viewController = UIViewController()
viewController.view = webView
window?.rootViewController = viewController
window?.makeKeyAndVisible()
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "dvia", url.host == "openurl" {
if let urlString = url.queryParameters?["url"], let url = URL(string: urlString) {
let myRequest = URLRequest(url: url)
webView.load(myRequest)
return true
}
}
return false
}
}
extension URL {
var queryParameters: [String: String]? {
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else {
return nil
}
var parameters = [String: String]()
for item in queryItems {
parameters[item.name] = item.value
}
return parameters
}
}
Приведенный выше код содержит потенциальную проблему со слабой проверкой хоста. Это означает, что код не выполняет тщательную проверку или проверку хост-компонента URL-адреса ссылки на контент. Метод open url проверяет, является ли схема dvia, а хост — openurl, чтобы определить, должен ли он обрабатывать глубокую ссылку. Однако он не выполняет никакой дополнительной проверки значения хоста и не проверяет, соответствует ли оно доверенному или ожидаемому значению.
Чтобы эксплуатировать его, нам сначала нужно определить схему Deep Link для него, мы можем просмотреть его из файла Info.plist, чтобы идентифицировать его, пожалуйста, просмотрите наш предыдущий блог. Как только мы идентифицируем схему глубокой ссылки как dvia://, нам нужно перейти в файл AppDelegate.swift, чтобы определить оставшуюся часть схемы.
Приведенный выше код проверяет, является ли схема dvia, хостом является opeurl и параметром как url, если все эти три условия удовлетворены, он загружает созданный запрос в экземпляр webView, вызывая webView.load(myRequest), который инструктирует веб-представление для загрузки указанного URL-адреса, который делает нашу схему такой:
Назначение приложения — загрузить https://8ksec.io , что оно и делает при открытии приложения, но давайте попробуем открыть на нем произвольный URL-адрес через схему DeepLink.
Нажмите на ссылку выше.
Очевидно, что в приложении был загружен неограниченный URL-адрес. Точно так же эта уязвимость может быть использована для выполнения фишинговых атак.
Защита
Поддерживайте белый список доверенных доменов или URL-адресов, которые приложению разрешено загружать через глубокие ссылки. Проверяйте входящие URL-адреса по этому белому списку, чтобы убедиться, что они исходят из надежных источников.
Сценарий – 3: HTML-Инъекция
Внедрение HTML происходит, когда веб-приложение пренебрегает адекватной проверкой и очисткой ввода пользователя перед его представлением на веб-странице. Эта уязвимость системы безопасности позволяет злоумышленнику вставить и выполнить неавторизованный код на уязвимом веб-сайте или в приложении.
Когда значения параметров из прямой ссылки передаются в веб-представление, существует потенциальный риск внедрения HTML. Эта уязвимость позволяет злоумышленнику создавать определенные полезные нагрузки, которые могут перенаправлять пользователей на вредоносные веб-сайты или приложения.
Чтобы продемонстрировать этот сценарий, замените файл AppDelegate.swift приведенным ниже кодом.
import UIKit
import WebKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, WKUIDelegate {
var window: UIWindow?
var webView: WKWebView!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize the window
window = UIWindow(frame: UIScreen.main.bounds)
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: window!.bounds, configuration: webConfiguration)
webView.uiDelegate = self
// Load the initial URL
let initialURL = URL(string: "https://8ksec.io")
let initialRequest = URLRequest(url: initialURL!)
webView.load(initialRequest)
// Set the web view as the root view controller's view
let viewController = UIViewController()
viewController.view = webView
window?.rootViewController = viewController
window?.makeKeyAndVisible()
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "dvia", url.host == "display" {
if let urlString = url.queryParameters?["message"]?.removingPercentEncoding {
let webViewController = UIViewController()
let webView = WKWebView(frame: webViewController.view.bounds)
// Create a dummy baseURL with a file path
let dummyBaseURL = URL(fileURLWithPath: NSTemporaryDirectory())
webView.loadHTMLString(urlString, baseURL: dummyBaseURL)
webViewController.view.addSubview(webView)
// Add a "Close" button to dismiss the web view
let closeButton = UIBarButtonItem(barButtonSystemItem: .close, target: self, action: #selector(closeWebView))
webViewController.navigationItem.rightBarButtonItem = closeButton
// Create a navigation controller to embed the web view controller
let navigationController = UINavigationController(rootViewController: webViewController)
// Present the navigation controller
self.window?.rootViewController?.present(navigationController, animated: true, completion: nil)
return true
}
}
return false
}
@objc func closeWebView() {
self.window?.rootViewController?.dismiss(animated: true, completion: nil)
}
}
extension URL {
var queryParameters: [String: String]? {
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else {
return nil
}
var parameters = [String: String]()
for item in queryItems {
parameters[item.name] = item.value
}
return parameters
}
}
В приведенном выше коде параметр сообщения извлекается из глубокой ссылки и присваивается переменной urlString. Однако код не выполняет никакой проверки или очистки этих входных данных. Следовательно, если злоумышленник создаст глубокую ссылку с параметром вредоносного сообщения, содержащим код HTML или JavaScript, он будет напрямую загружен и выполнен в веб-представлении.
Чтобы воспользоваться этой уязвимостью, злоумышленник может создать специально созданную полезную нагрузку HTML, содержащую гиперссылку, предназначенную для перенаправления пользователей на вредоносное веб-приложение, как показано ниже:
dvia://display?message=%3Ca%20href%3D%22http%3A%2F%2Fdamnvulnerableiosapp.com%2F%22%3Eopen%3C%2Fa%3E
Нажмите на ссылку выше.
Когда жертва нажимает на ссылку, открывается вредоносный URL.
Защита
Прежде чем загружать HTML-контент в веб-представление, важно подумать о кодировании или очистке выходных данных для параметра «сообщение». Этот шаг включает в себя фильтрацию или экранирование тегов HTML или специальных символов, которые могут потенциально выполнять вредоносный код.
Сценарий – 4: Атаки CSRF
CSRF или подделка межсайтовых запросов — это брешь в системе безопасности, которая возникает, когда вредоносный веб-сайт обманом заставляет браузер пользователя неосознанно отправлять несанкционированные запросы на другой веб-сайт, на котором пользователь аутентифицирован. Эта уязвимость не ограничивается только веб-приложениями; его также можно использовать с помощью глубоких ссылок в iOS или других платформах.
В iOS-приложениях CSRF-атаки часто происходят, когда действия выполняются через глубокие ссылки. Похожий случай можно найти в этом отчете о хакероне - https://hackerone.com/reports/805073, где злоумышленник смог манипулировать пользователями, чтобы они следовали за ними через CSRF, предоставив схему глубоких ссылок.
Финансовые приложения, которые включают в себя функцию прямых ссылок для повторных платежных транзакций, могут служить еще одной потенциальной мишенью для этой уязвимости. В этом сценарии злоумышленники используют функцию глубоких ссылок, предоставляя жертвам схемы глубоких ссылок, что позволяет им выполнять несанкционированные и произвольные транзакции.
Чтобы продемонстрировать этот сценарий, замените файл AppDelegate.swift приведенным ниже кодом.
import UIKit
import WebKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, WKUIDelegate {
var window: UIWindow?
var webView: WKWebView!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize the window
window = UIWindow(frame: UIScreen.main.bounds)
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: window!.bounds, configuration: webConfiguration)
webView.uiDelegate = self
// Load the initial URL
let initialURL = URL(string: "https://8ksec.io")
let initialRequest = URLRequest(url: initialURL!)
webView.load(initialRequest)
// Set the web view as the root view controller's view
let viewController = UIViewController()
viewController.view = webView
window?.rootViewController = viewController
window?.makeKeyAndVisible()
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "dvia", url.host == "payment" {
if let urlString = url.queryParameters?["user"]?.removingPercentEncoding {
let message = "Payment has been sent to \(urlString)"
let alertController = UIAlertController(title: "Payment", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
window?.rootViewController?.present(alertController, animated: true, completion: nil)
return true
}
}
return false
}
@objc func closeWebView() {
self.window?.rootViewController?.dismiss(animated: true, completion: nil)
}
}
extension URL {
var queryParameters: [String: String]? {
guard let components = URLComponents(url: self, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else {
return nil
}
var parameters = [String: String]()
for item in queryItems {
parameters[item.name] = item.value
}
return parameters
}
}
Приведенный выше код проверяет, является ли схема URL-адреса dvia и хостом является payment. Он принимает параметр для пользователя и инициирует платеж для этого пользователя. Злоумышленник может создать схемы deeplink, как показано ниже, при выполнении платеж будет выполнен для злоумышленника.
Предоставьте жертве приведенную выше схему deeplink.
Когда злоумышленник активирует схему, щелкнув по ней, произойдет выполнение, что приведет к завершению платежа.
Защита
Схемы Deeplink не должны реализовываться для выполнения конфиденциальных действий в приложении.
При необходимости важно проверить, были ли схемы deeplink активированы изнутри приложения или внешними компонентами.