From 45321b849544244e0afd37eabfa526bf1d5196f5 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 17 Aug 2026 23:25:37 +0000 Subject: [PATCH] Add APK binary analysis and correct audit findings --- APKANALYSIS.md | 272 +++++++++++++++++++++++++++++++++++++++++++++++++ AUDIT.md | 149 +++++++++++++++++++++++---- 2 files changed, 400 insertions(+), 21 deletions(-) create mode 100644 APKANALYSIS.md diff --git a/APKANALYSIS.md b/APKANALYSIS.md new file mode 100644 index 0000000000..c4af8ed2c9 --- /dev/null +++ b/APKANALYSIS.md @@ -0,0 +1,272 @@ +# Binary Artifact Analysis + +## Tangem Android Wallet — Official Release APK vs. Build from Audited Source + +--- + +| | | +|---|---| +| **Subject** | Comparison of Tangem's official v6.1.2 release APK against a build produced from the audited source | +| **Companion to** | [AUDIT.md](./AUDIT.md) — static source review of commit `358144ee61a` | +| **Analysis date** | 17 August 2026 | +| **Analysis type** | Static binary inspection (manifest, signing, package structure). No decompilation, no execution | +| **Objective** | Determine whether the officially distributed binary can be confirmed to originate from the audited source | + +--- + +## 1. Executive Summary + +**The official APK cannot be verified as originating from the audited source, and no available +technique would allow it.** This is a structural property of how Tangem builds and hardens its +release artifact, not a deficiency of this analysis or an indication of wrongdoing. + +What *can* be established is weaker but not worthless: every externally observable property of the +official binary that could be compared against a build from the audited source **matches**. That +rules out crude substitution or repackaging. It does not, and cannot, rule out a targeted +modification concealed beneath the protection layer. + +The comparison additionally surfaced **two factual errors in AUDIT.md**, both of which overstate the +security posture of the shipped application. They are recorded in §5 and have been corrected in the +audit report. + +### Verdict + +> **UNVERIFIABLE — CONSISTENT.** Provenance of the official binary cannot be established by any +> means available to a third party. All comparable attributes are consistent with the audited +> source. Absence of contradiction is not evidence of correspondence. + +--- + +## 2. Artifacts Compared + +| | Official release | Build from audited source | +|---|---|---| +| Filename | `app-release-protected-1819-6.1.2.apk` | `app-google-debug.apk` | +| Origin | `github.com/tangem/tangem-app-android` releases, tag `v6.1.2` | `./gradlew :app:assembleGoogleDebug` at `358144ee61a` | +| Size | 134,544,995 bytes | 176,908,283 bytes | +| SHA-256 | `6ed4ac317f2f5bdccd5bb1cec9d6733207261e6b4f823a4de883e646872166a1` | `5df4c81755bc423ed39e92499830d789b309561211c62091585fa9038adfe5cd` | +| Package | `com.tangem.wallet` | `com.tangem.wallet.debug` | +| Version | `6.1.2` (code `1819`) | `1.0.0-SNAPSHOT` (code `1`) | +| Build type | `release`, minified, DexProtector-hardened | `debug`, unminified, unprotected | +| Signer | `L=Zug, O=Tangem AG` | Committed dummy debug keystore | +| Archive entry dates | 2026-08-13 | 2026-08-17 | + +The size difference is expected and runs counter to intuition: the debug build is *larger* because +it is not minified by R8, despite carrying no protection layer. + +--- + +## 3. Why Provenance Cannot Be Established + +Four independent obstacles apply. Any one alone would be sufficient to defeat verification. + +### 3.1 The release is commercially hardened + +The official APK ships Licel DexProtector: + +``` +lib/arm64-v8a/libdexprotector.so 446,117 bytes +lib/armeabi-v7a/libdexprotector.so 394,517 bytes +assets/assets.dat 229,499 bytes +assets/ict.dat 10,853 bytes +``` + +DexProtector encrypts and obfuscates DEX bytecode. The transformation is keyed per build and is +explicitly designed to prevent the analysis that verification would require. Comparing bytecode +between the two artifacts is not merely impractical — it is precluded by design. + +### 3.2 The compared artifacts are different build types + +The official build passes through R8 minification, obfuscation, and resource shrinking. The +reference build does not. Class names, method signatures, and the DEX file layout diverge for +reasons entirely unrelated to source content: 54 DEX files versus 68. + +### 3.3 The source tree does not correspond to the released version + +The repository carries **no version of its own**. `AppConfig.versionCode` is `1`, and +`VersionNameProvider` derives the name from the current git branch, falling back to +`1.0.0-SNAPSHOT`. Both values are injected by CI via `-PversionCode` / `-PversionName`. + +Consequently nothing in the tree identifies which release a given commit produced. The evidence +indicates the audited commit is **newer** than v6.1.2: archive entries in the official APK are dated +2026-08-13, whereas the audited commits are dated 2026-08-14. The two artifacts therefore do not +represent the same source state, and could not be expected to match even in principle. + +### 3.4 The build is not reproducible by a third party + +Independent of the above, an outside party cannot reconstruct the official build: + +- `core/ui/ds-tokens` is a submodule gitlink with **no `.gitmodules` mapping anywhere in the + repository's 16,087-commit history**, so it cannot be resolved (see AUDIT.md O-3) +- All third-party API keys in `config_prod.json` are `PLACEHOLDER`; the official build embeds real + values, compiled in at build time by `GenerateEnvironmentConfigTask` +- Release signing requires a keystore that is deliberately not published + +Tangem publishes no reproducible-build attestation, and the artifact's construction is incompatible +with one. + +--- + +## 4. Consistency Findings + +The following were compared and **match**. Each is a property an attacker repackaging or +substituting the application would find difficult to preserve. + +### 4.1 Permission set — identical + +Both APKs declare **exactly 23 permissions**. After normalising the debug package prefix, a sorted +diff of the two sets is **empty**. + +This is the most informative single result. The comparison was made against a binary built from the +audited source, so any permission present in Tangem's distributed build but not produced by that +source would be a direct indicator of divergence. There is none. + +Both sets also **exclude** location and microphone permissions, confirming that the +`tools:node="remove"` stripping described in AUDIT.md §3.6 is genuine and survives into the shipped +artifact. + +### 4.2 Native libraries — identical, plus protection runtime + +| | Count | Detail | +|---|---|---| +| Build from audited source | 14 | see below | +| Official release | 16 | the same 14, plus `libdexprotector.so` and `libalice.so` | + +``` +libTrustWalletCore.so · libsecp256k1-jni.so · libTrezorCrypto.so · libargon2.so +libblst.so · libsqlcipher.so · libuniffi_yttrium.so · libtoolChecker.so +libtensorflowlite_jni.so · libbarhopper_v3.so · libjnidispatch.so +libimage_processing_util_jni.so · libandroidx.graphics.path.so · libsurface_util_jni.so +``` + +The audited source reproduces the official release's native library set exactly. The only additions +are the protection layer. `libalice.so` was not independently identified; it appears only in the +protected build alongside `libdexprotector.so`, which is consistent with it forming part of the +DexProtector runtime, but this was not confirmed. + +### 4.3 Build configuration and identity + +- `targetSdkVersion` 36 and `compileSdkVersion` 36 in both, matching the source configuration +- Package `com.tangem.wallet` (reference build carries the expected `.debug` suffix) +- Official APK signed by `L=Zug, O=Tangem AG`, certificate SHA-256 + `e0fe798927cf94709b9d439c9ce728a90a2891698cdff31a4c4d63435b946748`, coherent with Tangem AG's + registration in Zug, Switzerland + +**Note on the signing certificate:** this establishes only that the holder of that key signed the +artifact. It is a first-observation baseline, not an identity proof. Its value is comparative — +future releases can be checked against this digest to detect a signing-key change. + +--- + +## 5. Discrepancies Against AUDIT.md + +Both findings below arise from the same root cause: the audit examined the **source tree**, and its +conclusions were phrased as though they described the **shipped application**. Neither indicates +malicious behaviour. Both have been corrected in AUDIT.md. + +### D-1 — Permission set understated (AUDIT.md §3.6) + +The audit lists nine permissions as the "complete permission set across all manifests" and states +that external storage and `RECEIVE_BOOT_COMPLETED` are **absent**. + +The nine are accurate for the hand-written manifests (`app/src/main/` and `app/src/huawei/`), which +were verified to declare exactly that set. However the **merged** manifest — in Tangem's release and +in the build from the audited source alike — contains 23. The fourteen not accounted for: + +``` +READ_EXTERNAL_STORAGE · WRITE_EXTERNAL_STORAGE · WRITE_SETTINGS +RECEIVE_BOOT_COMPLETED · FOREGROUND_SERVICE · USE_FINGERPRINT · POST_NOTIFICATIONS +BIND_GET_INSTALL_REFERRER_SERVICE · ACCESS_ADSERVICES_ATTRIBUTION +ACCESS_ADSERVICES_AD_ID · c2dm.RECEIVE · DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION +com.samsung.android.mapsagent.permission.READ_APP_INFO +com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA +``` + +These are introduced by manifest merging from bundled third-party SDKs — the same mechanism the +audit correctly credits Tangem for defending against with `tools:node="remove"`. The characterisation +"permissions MINIMISED" and "the set contains nothing a wallet does not require" is not supported by +the artifact as shipped. `WRITE_SETTINGS` and `RECEIVE_BOOT_COMPLETED` in particular warrant +explanation rather than omission. + +### D-2 — "No native code" is true of the repository, false of the application (AUDIT.md §3.1) + +The audit states "No `.so` libraries, no JNI, no NDK build inputs," and answers **No** to the +methodology question *"Does it ship native binaries or opaque blobs?"* + +This is correct for the source tree — no `.so` file is committed. It is incorrect for the +application, which bundles fourteen native libraries even in the unprotected build (§4.2). + +The distinction is material because several are security-critical: `libTrustWalletCore.so`, +`libsecp256k1-jni.so`, and `libTrezorCrypto.so` perform key derivation and signing; `libargon2.so` +provides key-stretching; `libsqlcipher.so` provides at-rest database encryption. These arrive +through the pre-built Maven dependencies that AUDIT.md §6.1 places outside the review's scope, so +the audit's scope statement does technically cover them. But a reader reaching "ships native +binaries: **No**" in the summary table will draw the opposite conclusion about the application they +are installing. + +--- + +## 6. What This Analysis Does and Does Not Establish + +**Does establish:** + +- The official v6.1.2 APK is signed by Tangem AG and structured as the audited source predicts +- Its permission surface and native library set are exactly reproduced by building the audited + source, with no unexplained additions +- Gross tampering — repackaging, permission injection, substitution of a different application — is + ruled out +- The privacy hardening claimed in AUDIT.md §3.6 is present in the distributed artifact + +**Does not establish:** + +- That the official APK was built from the audited source, or from any particular source +- That the DEX bytecode is free of modification. DexProtector renders this unexaminable +- Anything about the pre-built Tangem SDKs, which perform mnemonic encryption and at-rest key + storage and remain unreviewed (AUDIT.md §6.1) +- That any *future* release will share these properties + +A user installing the official APK is extending trust to Tangem's build pipeline and signing key. +Nothing available to a third party can substitute for that trust. This analysis narrows the range of +undetected substitutions; it does not eliminate it. + +--- + +## 7. Method + +All inspection used Android SDK build-tools 36.0.0. + +```bash +# Manifest, version, permissions +aapt2 dump badging + +# Signing certificate +apksigner verify --print-certs + +# Package structure, native libraries, DEX count +unzip -l +``` + +Permission sets were extracted, normalised for the debug package prefix, sorted, and compared with +`diff`. Native library sets were compared with `comm` after stripping ABI directory components. + +No decompilation, deobfuscation, or execution was performed. No attempt was made to defeat +DexProtector. + +--- + +## 8. Limitations + +1. **Static inspection of archive metadata only.** Application behaviour was not observed. +2. **Version mismatch.** The reference build derives from a commit dated one day after the official + artifact. Differences attributable to intervening source changes cannot be distinguished from + differences attributable to anything else. +3. **Reference build was not fully faithful.** It was produced with `verifyDesignTokens` skipped + (the `ds-tokens` submodule is unresolvable) and with `PLACEHOLDER` API keys. Neither affects the + manifest or native library comparisons on which the findings rest. +4. **Single point in time.** Applies to v6.1.2 build 1819 only. Re-verification is required for + every subsequent release, and the certificate digest in §4.3 is the recommended anchor. + +--- + +*Binary analysis of `app-release-protected-1819-6.1.2.apk` against a reference build of commit +`358144ee61a`. Companion to AUDIT.md; findings D-1 and D-2 have been applied to that report.* diff --git a/AUDIT.md b/AUDIT.md index c81491e0e5..f2715b9fe7 100644 --- a/AUDIT.md +++ b/AUDIT.md @@ -8,8 +8,10 @@ |---|---| | **Subject** | `tangem-app-android` — Tangem cryptocurrency wallet for Android | | **Upstream** | `https://github.com/tangem/tangem-app-android` | -| **Commit reviewed** | `358144ee61a` (branch `master`) | +| **Commit reviewed** | `358144ee61a` (branch `master`) — confirmed identical to upstream `master` (§6.5) | | **Report date** | 17 August 2026 | +| **Revised** | 17 August 2026 — §3.1, §3.6, O-3 corrected; §6.5 resolved. See "Revisions" below | +| **Companion report** | [APKANALYSIS.md](./APKANALYSIS.md) — binary comparison against Tangem's official v6.1.2 release APK | | **Review type** | Static source code review (manual, targeted) | | **Codebase size** | ~292 Gradle modules · 7,719 Kotlin files · 641 XML · 5 Java | | **Objective** | Detect malware, backdoors, information leaks, obfuscated code, and remote code-download behaviour | @@ -52,6 +54,22 @@ Readers should note the scope boundaries in §6 — most importantly that Tangem consumed as **pre-built binary artifacts** and were therefore outside the reach of this source review. +### Revisions (17 August 2026) + +This report was amended after a build of the source was produced and compared against Tangem's +official release APK. **Three corrections narrow claims that were stated too broadly**; one closes a +limitation. All should be read before relying on the original text: + +| Section | Change | +|---|---| +| §3.1 | "No native code" holds for the repository, **not** for the built application, which bundles 14 native libraries — including those performing key derivation, signing, and at-rest encryption | +| §3.6 | The nine permissions listed are the *source manifest* set. The **merged** manifest contains 23. "Permissions minimised" overstated the position | +| O-3 | A clean checkout **does not build at all** — the `ds-tokens` submodule is unresolvable outside Tangem. The prior text said it compiles | +| §6.5 | Commit provenance is now **verified** against upstream, closing a limitation rather than adding one | + +None of these alters the §1 verdict on the source. §3.1 and §3.6 do mean the shipped application has +a larger native-code and permission surface than the original report conveyed. + --- ## 2. Methodology @@ -65,7 +83,7 @@ of every candidate hit in context. |---|---|---| | 1 | Can it load or execute code obtained at runtime? | **No** | | 2 | Can it execute shell commands or spawn processes? | **No** | -| 3 | Does it ship native binaries or opaque blobs? | **No** | +| 3 | Does the *repository* contain native binaries or opaque blobs? | **No** — but the built APK bundles 14 native libraries from binary dependencies; see §3.1 | | 4 | Does key material reach logs, storage, or the network? | **No** | | 5 | Does it contact hidden or hostile endpoints? | **No** | | 6 | Are live credentials committed to the repository? | **No** | @@ -97,14 +115,31 @@ Runtime.getRuntime().exit(0) This terminates the application's own process. It executes nothing. -**Native code.** No `.so` libraries, no JNI, no NDK build inputs. Only two `.jar` files exist in -the tree: +**Native code — repository.** No `.so` libraries, no JNI, and no NDK build inputs are committed to +the tree. Only two `.jar` files exist: | File | Size | Assessment | |---|---|---| | `gradle/wrapper/gradle-wrapper.jar` | 55.6 KB | Standard Gradle 8.14.1 wrapper | | `app/libs/dexprotector-annotations.jar` | 3.5 KB | Compile-time annotations only (§3.9) | +**Native code — built application.** *(Correction, 17 Aug 2026.)* The statement above describes the +repository, not the artifact. A build of this source bundles **14 native libraries**, several of +them security-critical: + +``` +libTrustWalletCore.so · libsecp256k1-jni.so · libTrezorCrypto.so · libargon2.so +libblst.so · libsqlcipher.so · libuniffi_yttrium.so · libtoolChecker.so +libtensorflowlite_jni.so · libbarhopper_v3.so · libjnidispatch.so +libimage_processing_util_jni.so · libandroidx.graphics.path.so · libsurface_util_jni.so +``` + +Key derivation and signing (`libTrustWalletCore`, `libsecp256k1-jni`, `libTrezorCrypto`), key +stretching (`libargon2`), and at-rest database encryption (`libsqlcipher`) are all performed in +native code. These arrive through the pre-built Maven dependencies excluded from this review by §6.1 +and were therefore **not** examined. Tangem's own release build adds `libdexprotector.so` and +`libalice.so` on top. See [APKANALYSIS.md](./APKANALYSIS.md) §4.2. + **Reflection.** Searches for `Class.forName`, `getDeclaredMethod`, `getDeclaredField`, and `setAccessible` returned **zero** genuine results. There is no reflective dispatch to hide behaviour behind. @@ -205,16 +240,36 @@ repository — a common weakness that is simply absent here. `addJavascriptInterface` or `@JavascriptInterface` anywhere in the tree. The JavaScript-bridge attack surface does not exist by construction. -### 3.6 Permissions and Exported Components — MINIMISED +### 3.6 Permissions and Exported Components — RESTRAINED IN SOURCE, WIDER AS SHIPPED -Complete permission set across all manifests: +Permission set declared in the **hand-written manifests** (`app/src/main/`, `app/src/huawei/`): `INTERNET` · `ACCESS_NETWORK_STATE` · `CAMERA` (QR scanning) · `NFC` (card scanning) · `USE_BIOMETRIC` · `VIBRATE` · `WAKE_LOCK` · `HIDE_OVERLAY_WINDOWS` · `AD_ID` -**Absent:** SMS, contacts, call log, location, microphone, external storage, accessibility -services, `SYSTEM_ALERT_WINDOW`, `REQUEST_INSTALL_PACKAGES`, `RECEIVE_BOOT_COMPLETED`. The set -contains nothing a wallet does not require. +Nothing there exceeds what a wallet requires. + +**Correction (17 Aug 2026).** An earlier revision presented the nine above as the complete set and +listed external storage and `RECEIVE_BOOT_COMPLETED` among permissions that were *absent*. That was +wrong. The nine describe the source manifests; the **merged** manifest in the built APK contains +**23**. The additional fourteen, contributed by manifest merging from bundled third-party SDKs: + +``` +READ_EXTERNAL_STORAGE · WRITE_EXTERNAL_STORAGE · WRITE_SETTINGS +RECEIVE_BOOT_COMPLETED · FOREGROUND_SERVICE · USE_FINGERPRINT · POST_NOTIFICATIONS +BIND_GET_INSTALL_REFERRER_SERVICE · ACCESS_ADSERVICES_ATTRIBUTION +ACCESS_ADSERVICES_AD_ID · c2dm.RECEIVE · DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION +com.samsung.android.mapsagent.permission.READ_APP_INFO +com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA +``` + +`WRITE_SETTINGS` and `RECEIVE_BOOT_COMPLETED` are broader than a wallet needs and are not explained +by first-party code; they warrant enquiry with the SDK vendors that introduce them. This merged set +is **identical** in Tangem's official release APK and in a build from this source — see +[APKANALYSIS.md](./APKANALYSIS.md) §4.1 and D-1. + +**Still genuinely absent** from the merged manifest: SMS, contacts, call log, location, microphone, +accessibility services, `SYSTEM_ALERT_WINDOW`, and `REQUEST_INSTALL_PACKAGES`. Two measures are worth drawing out, as both are affirmative hardening rather than mere restraint: @@ -231,7 +286,9 @@ SDKs would otherwise introduce through manifest merging: ``` Denying location and microphone access to advertising and analytics SDKs is a privacy measure that -argues directly against hostile intent. +argues directly against hostile intent. **This control was verified in the shipped artifact:** +neither location nor `RECORD_AUDIO` appears in the merged manifest of Tangem's official release APK +(APKANALYSIS.md §4.1). The stripping is effective, not merely declared. **Exported components.** Exactly one: `MainActivity`, necessarily exported as the launcher. Its intent filters are tightly scoped — the `LAUNCHER` category, NFC NDEF discovery restricted to @@ -404,14 +461,49 @@ is pseudonymised (§3.7). SurveySparrow, and drop the `AD_ID` permission. The Huawei flavour already differs in SDK composition. -### O-3 — A clean checkout builds but does not fully function +### O-3 — A clean checkout does not build, and does not fully function once it does -Because all configuration values are `PLACEHOLDER` (§3.10) and only a dummy debug keystore is -committed, a build from a clean checkout compiles but its third-party integrations — price quotes, -buy/sell providers, and some RPC endpoints — will not operate until real API keys are supplied. -Release signing requires a keystore that is deliberately not in the repository. +*(Revised 17 Aug 2026 after an actual build was attempted. The previous text stated a clean checkout +compiles; it does not.)* -This is correct and expected practice for a public source release, not a defect. +**The build fails outright.** `core/ui/ds-tokens` is registered in the tree as a submodule gitlink +(commit `a59c6a36`), but **no `.gitmodules` file exists anywhere in the repository's 16,087-commit +history**. There is no URL from which the submodule can be resolved. `:core:ui:verifyDesignTokens` +runs during `preBuild` and aborts before any module compiles, emitting the instruction +`git submodule update --init --recursive` — which cannot succeed outside Tangem's own environment. + +The task only *verifies*: it hashes the submodule's JSON and SVG sources and compares the digest +against a committed `.tokens-hash`. It generates nothing, and the 380 generated files it guards are +all committed. Building with `-x :core:ui:verifyDesignTokens` therefore produces a functionally +complete APK, at the cost of losing the assurance that the committed generated sources still +correspond to the design tokens they derive from. + +**Once building, integrations remain partly inert.** All configuration values are `PLACEHOLDER` +(§3.10) and are compiled into the APK at build time by `GenerateEnvironmentConfigTask`. No runtime +check detects the sentinel, so the application transmits `PLACEHOLDER` as a live credential and +receives authentication failures. + +The practical effect is uneven. `providers_order.json` lists RPC providers per chain as either +`public` (no key) or `private` (keyed), and the SDK falls through the list in order. Of 97 chains, +**87 retain at least one public provider and will synchronise without any key**. The 10 that do not +are: + +``` +bitcoin · ethereum · solana · cardano · litecoin +dogecoin · bitcoin-cash · dash · the-open-network · chia +``` + +— that is, the chains most users actually hold. Fiat prices and the swap aggregator additionally +depend on Tangem-issued credentials that cannot be self-provisioned. + +**Consequence for downstream forks:** a `PLACEHOLDER` build presents as a working wallet while +silently failing to report balances on the major chains. A user scanning a funded card may see a +zero balance and conclude their funds are lost. Such a build should not be distributed to +non-technical users, and any release of one should say so explicitly. + +Publishing a source tree without private keys or internal submodules is correct practice, not a +defect — but the resulting checkout is neither buildable nor safely usable as-is, and that should be +stated plainly rather than left to be discovered. --- @@ -437,9 +529,17 @@ obtained. *leaked*. It does not assess whether the encryption schemes protecting that material at rest are correctly chosen or parameterised. -5. **Commit provenance could not be verified.** The reviewed checkout carries squashed commit - messages (`Updated on 2026-08-14`), so upstream authorship and per-change history were not - available for inspection. +5. **Commit provenance — resolved.** *(Updated 17 Aug 2026.)* An earlier revision recorded this as + an open limitation. It has since been closed: `git ls-remote` confirms that `master` at + `github.com/tangem/tangem-app-android` is `358144ee61a9f65e0f39578e8c943226abb5d996` — the exact + commit reviewed — and `git diff` against it is empty. The reviewed tree is the published upstream + tree, unmodified. + + The `Updated on 2026-08-14` subject line appears on **all 16,087 commits**, not merely recent + ones, so it is an artefact of how the upstream repository is published rather than evidence of + rewriting. Per-change authorship and history remain unavailable for inspection, so the *content* + of individual upstream changes could not be reviewed; the *identity* of the tree is now + established. 6. **Point-in-time.** Findings apply to commit `358144ee61a` only. @@ -464,8 +564,15 @@ or negligent application: - `FAIL_ON_PROJECT_REPOS` constraining the build supply chain - Commercial runtime tamper and root detection -Subject to the scope boundaries in §6 — in particular the unreviewed binary SDKs — the application -is assessed as safe to build and distribute from this source. +Subject to the scope boundaries in §6 — in particular the unreviewed binary SDKs and the native +libraries they contribute (§3.1) — **nothing in the reviewed first-party source is an obstacle to +building and distributing this application.** + +That is a narrower statement than "safe to distribute", and deliberately so. A build produced from +this source alone carries `PLACEHOLDER` credentials and will not report balances on the ten most +widely held chains while otherwise presenting as a functioning wallet (O-3). Anyone distributing +such a build must say so explicitly. Assurance over the binary that Tangem itself ships is a +separate question, addressed — and largely left open — in [APKANALYSIS.md](./APKANALYSIS.md). ---