Забезпечення відповідності мобільного додатку вимогам PCI DSS (платіжні дані)
PCI DSS v4.0—стандарт Ради по стандартам безпеки платіжних карт, обов'язковий для будь-якого ПЗ, яке передає, обробляє або зберігає дані володільців карт. Для мобільних додатків критичні розділ 6 (Secure Development) та розділ 4 (Encryption in Transit). Без відповідності крупний еквайєр просто не видасть можливість прямого еквайрингу—прийдеться працювати лише через iframe-рішення.
Що конкретно порушують більшість додатків
Хранення PAN в логах. Розробник додає Log.d("Payment", "Card: $cardNumber") для дебагу. Потрапляє в logcat, який читається будь-яким іншим додатком на незахищеному Android-пристрої. PCI DSS вимога 3.3: PAN не повинен відображатися в логах у незашифрованому вигляді.
Скриншоти екрана введення карти. Android за замовчуванням дозволяє робити скриншоти будь-якого Activity. На екрані введення реквізитів—критична уразливість:
// Повинно бути на будь-якому екрані з карточними даними
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
На iOS аналогічно—потрібно перекривати UI при переході в background:
func applicationWillResignActive(_ application: UIApplication) {
// Додати overlay поверх sensitive-контенту
coverSensitiveContent()
}
Відсутність Certificate Pinning. Трафік до платіжного сервера перехоплюється Charles Proxy або mitmproxy без будь-яких перешкод. PCI DSS 6.5.4 вимагає захисту від атак типу man-in-the-middle.
// iOS: URLSession з кастомним делегатом для certificate pinning
class PinnedURLSessionDelegate: NSObject, URLSessionDelegate {
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
) {
guard
let serverTrust = challenge.protectionSpace.serverTrust,
let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0)
else {
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
let pinnedHash = "sha256/AbCdEfGhIjKlMnOpQrStUvWxYz123456789="
let serverHash = certificateHash(certificate)
if serverHash == pinnedHash {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
}
Root/Jailbreak Detection. PCI DSS 6.4.3 рекомендує (але не обов'язує) обнаруживати скомпрометовані пристрої. На практиці крупні еквайєри вимагають це через SDK. Використовують комбінацію: перевірка наявності /bin/bash, Cydia, su-команди, несумісність підпису процесу.
Tokenization замість зберігання PAN
Головний принцип PCI DSS для мобільних додатків—не зберігати PAN вообще. Додаток працює з токеном, який видає платіжний провайдер. Stripe називає це PaymentMethod, CloudPayments—Token, YooKassa—payment_method_id.
// Stripe: ніколи не бачимо PAN у коді
import StripePaymentSheet
var configuration = PaymentSheet.Configuration()
configuration.merchantDisplayName = "YourShop"
PaymentSheet.FlowController.create(
paymentIntentClientSecret: clientSecret,
configuration: configuration
) { [weak self] result in
switch result {
case .success(let flowController):
self?.paymentSheetFlowController = flowController
case .failure(let error):
// обробляємо
}
}
Карточні дані йдуть прямо в Stripe SDK → Stripe токенізує → додаток отримує paymentMethodId. PAN ніколи не торкається вашого сервера—це зменшує scope PCI DSS з SAQ D до SAQ A.
Audit Trail та логування
PCI DSS вимога 10: логувати доступ до cardholder data environment. Для мобільного додатку це означає:
- Логувати кожен успішний/невдалий платіж з timestamp, userId, замаскованим PAN (перші 6 + останні 4 цифри), статусом
- Логи зберігати не менше 12 місяців, з яких 3—немедленно доступні
- Захистити логи від модифікації (append-only storage)
Маскування PAN у логах:
fun maskPan(pan: String): String {
return pan.take(6) + "*".repeat(pan.length - 10) + pan.takeLast(4)
}
// "4111111111111111" → "411111******1111"
Процес оцінки та роботи
Повноцінна PCI DSS оцінка для мобільного додатку включає кілька етапів.
Scoping—визначаємо, чи торкається мобільний додаток cardholder data environment безпосередньо або через провайдера (Stripe, CloudPayments). Якщо через провайдера—scope значно менший.
Gap-аналіз—перевіряємо 12 вимог стандарту застосовно до коду, інфраструктури, процесів. Типові знахідки: plaintext logs, відсутність certificate pinning, missing FLAG_SECURE, недостатнє шифрування local storage.
Remediation—виправлення знайдених уразливостей: внедрення certificate pinning, переведення зберігання на Keychain/Keystore, налаштування obfuscation, додавання root detection.
Penetration Testing—PCI DSS 11.3 вимагає pen-тест мінімум раз на рік та після значимих змін. Для мобільних додатків: статичний аналіз (MobSF, Checkmarx), динамічний з прокси, тестування binary reversing.
ASV Scanning—якщо додаток взаємодіє з сервером безпосередньо, вимагається квартальне сканування через Approved Scanning Vendor.
Ориентири по терміні
Gap-аналіз та звіт—3–5 днів. Remediation—залежить від кількості та складності знахідок, зазвичай 1–3 тижні. Підготовка до QSA-аудиту—додатково.
Вартість розраховується індивідуально після аналізу вимог та поточного стану кодової бази.







