
An embedded SDK is code you ship but did not write, running with your app's full permissions and signed with your identity. When an analytics, ads, or payments SDK quietly reads the clipboard, harvests the advertising ID, or ships data over weak TLS, the OS and your users cannot tell its behavior apart from yours. It is your breach and your privacy violation.
That is why an SDK deserves its own test, not just a line in the host-app report. This methodology narrows the lens to a single dependency: separating its behavior from the host, hooking its exact classes to watch what it touches, and intercepting its traffic to prove what leaves the device. The steps overlap a full app pentest but the attribution is the whole point.
It matters because the SDK runs in your process with your permissions, so its worst behavior is indistinguishable from yours to the OS and to your users. If your app has location access, the SDK has location access. If it makes network calls, they carry your app's identity and your TLS reputation.
The risks are concrete: silent collection of device IDs, contacts, and clipboard contents; exfiltration over weak or unpinned TLS; insecure on-device storage of what it gathers; extra attack surface through exported components or broad permissions the SDK requests; and supply-chain compromise where a trusted SDK ships malicious code in a routine update. These feed the OWASP Mobile Top 10 data and code-quality categories and map to MASVS-STORAGE, MASVS-CRYPTO, MASVS-NETWORK, and MASVS-PLATFORM.
Isolation is what separates SDK testing from a normal pentest: you must attribute every behavior to the SDK, not the host. Start by finding the SDK's namespace and the surface it adds to the manifest:
$ apktool d app.apk -o src/ && jadx -d out/ app.apk
$ grep -rl 'com.vendor.analytics' out/sources/ | head
out/sources/com/vendor/analytics/EventBuilder.java
out/sources/com/vendor/analytics/NetClient.java
out/sources/com/vendor/analytics/IdProvider.java
$ grep -nE 'uses-permission|exported="true"' src/AndroidManifest.xml
11: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <- added by SDK
38: <receiver android:name="com.vendor.analytics.CampaignReceiver" android:exported="true"/>Diffing the manifest with and without the SDK shows exactly which permissions and exported components it pulls in. Where you can, build a minimal harness app that imports only the SDK, so its traffic and storage are not buried under host-app noise. Map the SDK's declared endpoints from strings so you know what its traffic should look like before you intercept it.
Static analysis reads the SDK without running it, surfacing hardcoded secrets, weak crypto, and which sensitive sources it can touch. Run MobSF for a scored first pass, then read the SDK's decompiled classes directly:
$ grep -rniE 'getDeviceId|getImei|ClipboardManager|getLastKnownLocation|AdvertisingId' out/sources/com/vendor/
IdProvider.java:18: String id = tm.getDeviceId(); <- IMEI/device ID
IdProvider.java:24: ClipData c = clipboard.getPrimaryClip(); <- reads clipboard
$ grep -rniE 'api[_-]?key|secret|token' out/sources/com/vendor/
NetClient.java:12:
static final String VENDOR_KEY = "sk_live_4eC39HqLyjWDarjtT1zdp7dc"; <- hardcoded keyA clipboard read inside an analytics SDK is a privacy finding on its own. Note every sink that could send data off-device (device IDs, clipboard, contacts, location, installed-app enumeration) so you can confirm it during interception. On iOS, search for Keychain misuse and IDFA access. Static tells you what is possible; only runtime tells you what is real.
The defining move of SDK testing is hooking the SDK's own classes at runtime, so you see the real serialized payload instead of inferring it from decompiled code. objection gives quick wins, but a focused Frida script on the SDK's request builder is what proves exfiltration. Here is the attach and the hook landing:
$ frida -U -n com.target.app -l sdk_trace.js
____
/ _ | Frida 16.2.1 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Attaching...
[Pixel::com.target.app ]-> [+] Hooked com.vendor.analytics.EventBuilder.build()
[SDK payload] {"adid":"38400000-8cf0-11bd-b23e-10b96e40000d",
"lat":37.4219,"lng":-122.084,"clipboard":"acct: 4417-...",
"dest":"https://collect.vendor-3p.com/e"}That single payload shows the advertising ID, a precise location fix, and clipboard contents going to a third domain. The hook itself overrides EventBuilder.build(), logs the return, and passes it through untouched. Use Java.enumerateLoadedClasses() to confirm the SDK is loaded before you hook. This per-method runtime loop is exactly what agentic pentesting automates across many SDKs at once.
Intercept the SDK's traffic with Burp or mitmproxy and confirm three things: what it sends, whether it pins independently of the host, and whether it validates TLS at all. With your CA installed, exercise the SDK and read every request to its endpoints.
If the SDK's traffic appears in cleartext through your proxy, it does not pin (a finding when it carries sensitive data). If it blocks while the host's traffic flows, the SDK pins on its own networking stack and you need a Frida hook targeting that stack specifically, not the host's. When the SDK uses raw sockets or refuses the proxy, fall back to forced redirection from intercepting proxy-unaware app traffic. Record exactly which fields leave the device; that evidence drives both the security and the privacy findings, which often tie to data protection compliance.
On a recent assessment of a retail app, the host networking pinned correctly, so traffic interception came up empty and the report nearly closed there. The bundled ads SDK, though, had its own HTTP client that pinned separately and shipped the advertising ID plus a coarse location fix to a third domain the host code never referenced. Intercepting the host's traffic showed nothing; hooking the SDK's request builder directly, as in the payload above, exposed it in one run. The lesson is that an SDK is a black box only until you point Frida at its classes.
Two more blind spots cost teams findings. SDKs add exported components and broad permissions that widen attack surface without the host team noticing, and static tools tell you only what the SDK could touch, never what it actually exfiltrates. Confirm every suspected sink dynamically. The findings table below shows how a confirmed, attributed SDK report excerpt reads.
SDK remediation is part code fix, part governance. The code-level fixes mirror the host app: move any collected data into EncryptedSharedPreferences or the Keychain rather than plain storage, and never accept an SDK that bundles a live key in the binary. The harder, durable control is governance:
ACCESS_FINE_LOCATION but your app does not need it, remove it with a manifest merger override (tools:node="remove") so the SDK cannot use it.For the SDKs you keep, confirm their pinning is real and their traffic carries only what you authorized. Permission stripping and version pinning plus a re-test gate are the core supply-chain controls.