Skip to content
CyberXplore - Xplore the Unseen

La checklist per il pentest di app mobile: OWASP MASVS nella pratica

cyberxploreDi cyberxplore12 min di lettura

Una checklist sul campo per il penetration testing di app mobile basata su OWASP MASVS: analisi statica e dinamica, archiviazione insicura, crittografia debole e bypass del certificate pinning, da parte di tester che lo fanno di mestiere.

La checklist per il pentest di app mobile: OWASP MASVS nella pratica

Datemi un APK e cinque minuti e di solito vi restituirò qualcosa che gli sviluppatori non volevano finisse in produzione. Lo si scompatta, lo si passa in jadx, si fa grep sul codice sorgente decompilato cercando password, secret o api_key, e si guardano scorrere i risultati. Un token scritto nel codice qui. Un hostname di staging che risponde ancora là. Un TODO di uno sprint che nessuno ricorda di aver scritto.

È qui che inizia buona parte del penetration testing di app mobile e, più spesso di quanto dovrebbe, è anche da qui che arriva il primo vero risultato. Il client gira su hardware che non vi appartiene. Un attaccante può smontare il binario sul proprio banco di lavoro, ai propri ritmi, senza rate limiting e senza che nessuno lo osservi. Gli istinti del mondo web non sopravvivono all’impatto con questa realtà.

Ancoriamo ogni ingaggio all’OWASP Mobile Application Security Verification Standard, MASVS, e lo trasformiamo in una checklist che eseguiamo contro build reali di Android e iOS. Ecco come funziona davvero.

Punti chiave

  • Il penetration testing di app mobile abbina l’analisi statica del binario decompilato all’analisi dinamica di un’app in esecuzione e strumentata, perché il client è interamente nelle mani dell’attaccante.
  • OWASP MASVS raggruppa i controlli in archiviazione, crittografia, autenticazione, rete, interazione con la piattaforma, qualità del codice e resilienza; l’OWASP MASTG vi fornisce casi di test concreti per ciascuno.
  • I risultati seri che segnaliamo più spesso sono l’archiviazione locale dei dati insicura, la crittografia usata male e le falle di autorizzazione nel backend che emergono una volta sconfitto il certificate pinning.
  • Il certificate pinning rallenta un tester. Non rende sicura un’app. Se il server si fida del client, aggirare il pin non fa che rivelare i bug veri che stanno sotto.
  • MASVS definisce livelli di verifica (L1 di base, L2 difesa in profondità, R resilienza), quindi calibrate il test in base al rischio reale dell’app invece di testare tutto alla stessa profondità.

Che cos’è MASVS e perché basare su di esso un pentest mobile?

MASVS è la risposta di OWASP a una domanda semplice: che cosa dovrebbe fare davvero un’app mobile sicura? È la spina dorsale di qualsiasi ingaggio serio di penetration testing di app mobile. I requisiti sono suddivisi in gruppi di controlli – archiviazione (MASVS-STORAGE), crittografia (MASVS-CRYPTO), autenticazione e gestione delle sessioni (MASVS-AUTH), comunicazione di rete (MASVS-NETWORK), interazione con la piattaforma (MASVS-PLATFORM), qualità del codice (MASVS-CODE) e resilienza contro il reverse engineering (MASVS-RESILIENCE).

Il suo compagno, l’OWASP Mobile Application Security Testing Guide (MASTG), è il punto in cui lo standard dà il meglio di sé. MASVS dice che l’app “non dovrebbe archiviare dati sensibili non cifrati”. MASTG vi dice quali file estrarre, quali API perdono dati e come dimostrarlo. Usiamo MASVS come mappa di copertura affinché non venga saltato nulla, e MASTG come guida pratica per ogni controllo.

Vale la pena dirlo con chiarezza: una checklist è un pavimento, non un soffitto. Percorriamo le categorie MASVS per garantire la copertura, poi passiamo il resto dell’ingaggio a inseguire la logica specifica dell’app che nessuno standard potrebbe prevedere. I bug interessanti vivono quasi sempre nella logica di business e nel backend, non nel fatto che l’app spunti una casella generica.

Come si testa un’app mobile? Statico più dinamico

Ogni lavoro sono due passaggi sullo stesso bersaglio: l’app a riposo e l’app mentre gira. Saltatene uno e vi perdete metà del quadro.

Analisi statica: leggere il binario

Su Android decompiliamo per prima cosa. apktool vi restituisce il manifest e le risorse; jadx riporta il DEX a Java leggibile. Su iOS lavorate con un IPA decifrato, i class dump e l’Info.plist. Lo scopo del passaggio statico è capire l’app prima di eseguirla e cogliere le cose che nel traffico non compaiono mai.

Una mossa di apertura tipica su Android:

apktool d target.apk -o target_src
jadx -d target_out target.apk

# hunt for obvious secrets and dangerous config
grep -rniE "api[_-]?key|secret|password|token|BEGIN RSA" target_out/
grep -rn "usesCleartextTraffic" target_src/AndroidManifest.xml

Poi leggiamo l’AndroidManifest in cerca di componenti esportati: activity, service, broadcast receiver e content provider marcati con android:exported="true" senza alcuna protezione tramite permessi. Un’activity esportata che riceve un intent e carica una URL in una WebView è un percorso classico verso il task hijacking o l’injection in WebView. Su iOS la caccia equivalente riguarda gli schemi URL personalizzati e gli Universal Links dichiarati nel plist, perché anche quelli sono punti d’ingresso raggiungibili da un attaccante.

Anche la configurazione di rete conta qui. usesCleartextTraffic="true", o un network_security_config.xml permissivo che si fida delle CA aggiunte dall’utente, vi dice che il traffico in chiaro o l’intercettazione sono sul tavolo prima ancora di aprire un proxy.

Analisi dinamica: eseguirla e osservare

L’analisi dinamica richiede un dispositivo Android con root o un iPhone con jailbreak, oppure i loro equivalenti in emulatore. La nostra strumentazione di riferimento è Frida con Objection sopra. Frida aggancia i metodi a runtime, estrae gli argomenti e riscrive i valori di ritorno. Objection ci regala vittorie rapide – elencare le voci del keychain, estrarre le SharedPreferences, disattivare i controlli di pin più comuni – senza scrivere a mano un hook per ognuno.

Facciamo passare tutto il traffico attraverso Burp Suite. Nel momento in cui l’app parla con il suo backend, il lavoro specifico del mobile per lo più finisce e comincia il testing di API classico: controlli di autorizzazione, IDOR sugli identificatori di oggetto, mass assignment, il replay delle richieste di un altro utente. Ottenere una vista pulita di quel traffico è la priorità numero uno, ed è esattamente per questo che il certificate pinning conta così tanto nel flusso di lavoro.

Quali sono i risultati più comuni in un pentest di app mobile?

La stessa manciata di problemi si ripresenta da un ingaggio all’altro. Si mappano in modo pulito sulle categorie MASVS, il che è un buon indizio che lo standard è stato costruito su dolore reale e non sulla teoria.

Archiviazione dei dati insicura (MASVS-STORAGE)

Questo è il risultato che segnaliamo più spesso. Le app mettono in cache molto più di quanto gli sviluppatori immaginino. Su Android estraiamo la sandbox e scorriamo gli XML delle SharedPreferences, i database SQLite e i file nella directory dei dati interna:

adb shell run-as com.example.app ls -la /data/data/com.example.app/
adb shell run-as com.example.app cat shared_prefs/*.xml

Token di sessione. Credenziali complete. Dati personali (PII). A volte dati di pagamento, in chiaro dentro le SharedPreferences o in una tabella SQLite non cifrata. Su iOS la stessa classe di bug compare in NSUserDefaults, nei file plist, negli store Core Data e nelle voci del Keychain salvate con una classe di accessibilità debole come kSecAttrAccessibleAlways. Tutto ciò che è leggibile su un dispositivo perso o infettato da malware è un’esposizione reale, e corrisponde a CWE-312, archiviazione in chiaro di informazioni sensibili.

Crittografia debole o usata male (MASVS-CRYPTO)

La categoria crittografia raramente riguarda matematica rotta. Riguarda l’uso scorretto. Chiavi scritte nel codice, prese direttamente dal sorgente decompilato. La modalità ECB, dove blocchi di testo in chiaro ripetuti lasciano trapelare la struttura nel cifrato – quella scelta di algoritmo rotto è CWE-327. IV statici o nulli. “Cifratura” fatta in casa che si rivela essere Base64 con qualche passaggio in più, e Base64 è codifica, non protezione.

Frida è perfetto per confermarlo dal vivo. Agganciate la configurazione del cipher e stampate la chiave e l’IV mentre l’app gira:

Java.perform(function () {
  var Cipher = Java.use("javax.crypto.Cipher");
  Cipher.init.overload("int", "java.security.Key").implementation = function (mode, key) {
    console.log("[cipher] alg=" + this.getAlgorithm() +
                " key=" + Java.use("android.util.Base64").encodeToString(key.getEncoded(), 0));
    return this.init(mode, key);
  };
});

Quando la chiave che “protegge” i vostri dati viene stampata sulla console all’avvio dell’app, la discussione sulla robustezza teorica è chiusa.

Falle di autorizzazione e di sessione nel backend (MASVS-AUTH)

Una volta che il traffico è visibile, è il server a reggere la fiducia, ed è lì che si nascondono i bug ad alta gravità. Token che non scadono mai. Identificatori di sessione prevedibili. Decisioni di autorizzazione prese lato client anziché lato server. Se l’app nasconde un pulsante da amministratore ma l’API risponde tranquillamente alla chiamata da amministratore da un account normale, quello è un critico, e nessun hardening del client lo risolve.

Come si aggira il certificate pinning?

Il pinning si aggira agganciando il codice che esegue il controllo del pin e forzandolo a passare – di solito con Frida o Objection – così che la vostra CA di proxy torni a essere considerata attendibile. Objection offre un comando in una riga:

objection -g com.example.app explore
# then, in the Objection prompt:
android sslpinning disable

Per le app con un’implementazione di pinning personalizzata o controlli in codice nativo, il bypass generico fallisce e si passa a uno script Frida mirato che aggancia lo specifico TrustManager, il CertificatePinner di OkHttp o il percorso nativo SSL_CTX_set_custom_verify. Su iOS di solito agganciate TrustKit o la logica di valutazione della fiducia propria dell’app attorno a SecTrustEvaluate.

Ecco la parte di opinione. Il pinning è un dosso, non un controllo. Alza il costo per un attaccante occasionale e fa guadagnare tempo contro il tooling automatizzato, il che è davvero utile e vale la pena implementarlo. Ma se sconfiggere il pin rivela un’API con l’autorizzazione rotta, il pinning era solo cosmetico. Testiamo ogni app come se il pinning fosse già sconfitto, perché un attaccante motivato con il binario e un dispositivo con root lo sconfiggerà. MASVS colloca il pinning sotto la resilienza esattamente per questo motivo: è difesa in profondità, non un sostituto di un backend che applica le proprie regole.

Come si risolvono questi problemi?

Soprattutto rispettando la piattaforma. Usate l’archiviazione sicura fornita dal sistema operativo invece di costruirne una vostra: Android Keystore ed EncryptedSharedPreferences tramite Jetpack Security, e il Keychain di iOS con una classe di accessibilità sensata come kSecAttrAccessibleWhenUnlockedThisDeviceOnly. Non parcheggiate mai segreti a lunga vita nelle SharedPreferences o in NSUserDefaults.

Per la crittografia, rivolgetevi a librerie di alto livello collaudate anziché a chiamate di cipher grezze. Tink di Google è un buon valore predefinito perché rende la scelta sicura quella facile. Non spedite chiavi dentro l’app; derivatele o fornitele a runtime e tenete le vere decisioni di fiducia sul server. Trattate il client come non attendibile, da un capo all’altro – ogni controllo di autorizzazione e di validazione che conta deve essere applicato lato server, perché il client mobile può essere manomesso e lo sarà. Aggiungete pinning e anti-tamper come strati aggiuntivi una volta che le fondamenta sono a posto, non prima.

Come aiuta CyberXplore

Il nostro servizio di penetration testing di applicazioni mobile esegue contro i vostri build di Android e iOS l’intera metodologia allineata a MASVS descritta qui: analisi statica del binario decompilato, analisi dinamica su dispositivi strumentati, bypass del pinning e uno sguardo severo alle API di backend su cui l’app si appoggia. Ricevete un report che ordina i risultati per impatto reale sul business, con passi di riproduzione che uno sviluppatore può seguire e un retest una volta applicate le correzioni, così che la correzione sia verificata e non solo dichiarata. State preparando una revisione per l’app store, un questionario di sicurezza di un cliente o un audit di conformità? Allineiamo l’ingaggio al giusto livello di verifica MASVS. Richiedete un preventivo e parlateci della vostra app; ne definiremo il perimetro con onestà.

FAQ

Quanto dura un penetration test di un’app mobile?

Un’app mirata su una singola piattaforma di solito richiede una o due settimane di test, a seconda del numero di funzionalità, delle dimensioni della superficie di API e del fatto che sia Android sia iOS rientrino nel perimetro. Le app con una logica di backend pesante richiedono più tempo, perché la maggior parte dei risultati seri vive nell’autorizzazione lato server, ed è lì che se ne vanno le ore una volta che il traffico è visibile.

Serve il codice sorgente per testare un’app mobile?

No. Lavoriamo benissimo in modalità black-box con il solo APK o IPA compilato, dato che la decompilazione fa comunque parte del lavoro. Detto questo, un test gray-box in cui condividete il sorgente e account di test trova di più e lo trova più in fretta, perché dedichiamo le ore di test a bug reali invece che al reverse engineering. Consigliamo il gray-box per il miglior rapporto qualità-prezzo.

Qual è la differenza tra MASVS e MASTG?

MASVS è lo standard: definisce i requisiti di sicurezza che un’app mobile dovrebbe soddisfare, raggruppati in categorie e livelli di verifica. MASTG è la guida ai test: fornisce ai tester tecniche concrete, l’uso degli strumenti e casi di test per verificare ogni requisito. In pratica usiamo MASVS come checklist di copertura e MASTG come manuale di procedura.

Il certificate pinning rende sicura la mia app?

No. Il pinning è un controllo di resilienza che rallenta l’intercettazione e gli attacchi automatizzati, il che vale la pena avere, ma un tester determinato con un dispositivo con root lo aggirerà. Non fa nulla contro l’archiviazione locale insicura, la crittografia debole o l’autorizzazione di backend rotta. Consideratelo uno strato sopra un’app che è già sicura senza di esso.

Ogni quanto dovremmo fare il pentest di un’app mobile?

Almeno una volta all’anno, e dopo ogni cambiamento significativo come un nuovo flusso di autenticazione, una funzionalità di pagamento o un’integrazione di backend importante. Le app mobile escono in fretta, e ogni release può reintrodurre vecchi problemi o aggiungere nuova superficie di attacco, perciò un test puntuale vi dice soltanto qualcosa sul build che avete testato. Molti team abbinano un test completo annuale a retest più leggeri sulle release importanti.

Lavora con CyberXplore

Penetration Testing di Applicazioni Web

Vedi questo rischio nei tuoi sistemi? I nostri tester senior trovano e dimostrano esattamente questi problemi e ti danno un percorso chiaro per risolverli.

Articoli correlati

Trasforma questi approfondimenti in un progetto

Ottieni un penetration test guidato da esperti senior e su misura per il tuo stack - risultati concreti, non una checklist.

  • Retest gratuito di ogni correzione
  • Scope e preventivo in 24 ore
  • Solo tester senior
  • ISO 27001
  • ISO 9001
  • OSCP
  • CRTP
  • CREST
Richiedi un preventivo