Skip to content

Instantly share code, notes, and snippets.

@jdkruzr
Created May 4, 2026 05:47
Show Gist options
  • Select an option

  • Save jdkruzr/fb4b452b8734f8b42ff0b04a03ce70e9 to your computer and use it in GitHub Desktop.

Select an option

Save jdkruzr/fb4b452b8734f8b42ff0b04a03ce70e9 to your computer and use it in GitHub Desktop.
Boox Security Analysis

Boox Palma 2 Pro - Privacy & Telemetry Analysis

Objective

Investigate claims that Onyx Boox devices "spy" on users by analyzing the actual code in Boox system applications. Determine what data is sent to external endpoints (particularly Chinese servers), whether it constitutes benign telemetry or something more concerning.

Device Under Analysis

  • Model: Palma 2 Pro (Palma2_Pro_C)
  • Firmware: 2025-12-27_14-24_4.1.1-rel_12272_6d0da782f
  • Android Version: 15
  • ADB Serial: bbb70bef
  • Analysis Date: 2026-03-27

Onyx Packages Installed

Package APK Path Size Priority
com.onyx (launcher) kcb-release.apk 110M HIGH - main system app
com.onyx.android.ksync ksync-release.apk 113M HIGH - cloud sync service
com.onyx.android.note knote2-release.apk 47M HIGH - notes app
com.onyx.android.onyxotaservice OnyxOtaService.apk 221K HIGH - OTA updates
com.onyx.aiassistant ai-assistant-release.apk 59M MEDIUM - AI features
com.onyx.appmarket app-market-release.apk 42M MEDIUM - app store
com.onyx.easytransfer EasyTransfer.apk 65M MEDIUM - data transfer
com.onyx.igetshop igetshop-release.apk 156M LOW - shopping
com.onyx.calculator (not pulled) - LOW
com.onyx.clock (not pulled) - LOW
com.onyx.dict (not pulled) - LOW
com.onyx.floatingbutton (not pulled) - LOW
com.onyx.gallery (not pulled) - LOW
com.onyx.kime (not pulled) - LOW
com.onyx.kreader (not pulled) - MEDIUM - e-reader
com.onyx.latinime (not pulled) - LOW - keyboard
com.onyx.mail (not pulled) - LOW
com.onyx.musicplayer (not pulled) - LOW
com.onyx.tscalibration (not pulled) - LOW
com.onyx.voicerecorder (not pulled) - LOW
com.onyx.android.production.test (not pulled) - LOW

Methodology

  1. Pull APKs from device via ADB
  2. Decompile with JADX (--deobf --show-bad-code flags)
  3. Search decompiled source for: network endpoints, data collection, telemetry classes, analytics SDKs, device fingerprinting, user data serialization
  4. Document each finding with: what data, where it goes, when it's triggered, how concerning

Findings

Legend

  • BENIGN - Standard telemetry, usage stats, crash reporting
  • NOTABLE - Collects more than expected but likely for legitimate purposes
  • CONCERNING - Collects sensitive data or sends to unexpected destinations
  • RED FLAG - Clearly problematic data collection or exfiltration

1. com.onyx.android.onyxotaservice (OTA Update Service)

Verdict: BENIGN

This is a straightforward Android A/B OTA update service. Key observations:

  • No network calls whatsoever. The service receives a local file path via intent (onyx.intent.action.OTA_START with path extra), decrypts the package with RSA (via native libota_jni.so), and applies it using Android's standard UpdateEngine.
  • The encrypted OTA package is decrypted to /data/local/assets/update.zip, then the payload is applied via UpdateEngine.applyPayload().
  • Safety checks: requires >3GB free space and >20% battery before proceeding.
  • After successful update, device reboots. Decrypted package is deleted after use.
  • RSA decryption happens in native code — the key is embedded in the .so, not visible in Java. This is standard practice for OTA integrity verification.
  • No telemetry, no phone-home, no analytics. This service is purely local.

Files analyzed:

  • OnyxOtaService.java - Service lifecycle, intent handling
  • UpdateManager.java - Update engine interaction, progress tracking
  • Util.java - Battery/space checks
  • PackageFiles.java - ZIP metadata parsing
  • RsaUtil.java - Native RSA decryption bridge
  • NotificationUtils.java - Foreground service notification (not analyzed, standard)

2. com.onyx (Main Launcher / KCB) - Server Infrastructure

Verdict: NOTABLE

The launcher contains the entire Onyx SDK including network infrastructure. The server routing architecture is region-aware with distinct Chinese and international clusters.

2a. Server Cluster Architecture (ClusterHost.java, ClusterInfo.java, Constant.java)

The device routes traffic to different server clusters based on region selection:

Region Main Host Data Host Log Host WebSocket
China https://send2boox.com https://data.boox.com https://log.boox.com wss://cb.send2boox.com/neocloud
USA https://push.boox.com https://en-data.boox.com https://en-lon.boox.com wss://cb.boox.com/neocloud
Europe https://eur.boox.com https://en-data.boox.com (same as data) wss://eurcb.boox.com/neocloud
Vietnam (uses US hosts) (uses US hosts) (uses US hosts) (uses US hosts)
Test https://dev.send2boox.com (same) (same) wss://cb.send2boox.com/neocloud

Key observation: When configured for a non-Chinese cluster, the device should route all traffic to the corresponding international endpoints. The question is whether any code paths bypass this and still hit Chinese servers.

Additional hardcoded endpoints found:

  • Index servers (CN): https://index1-5.send2boox.com
  • Index servers (Intl): https://index1-5.boox.com
  • Captive portal checks (CN): http://ntp.send2boox.com/generate_204, also Huawei and Xiaomi
  • Captive portal checks (Intl): Google clients + http://en-ntp.boox.com/generate_204
  • Hardcoded test IP: http://119.23.143.188/ (Alibaba Cloud - likely dev infrastructure)
  • Hardcoded internal IPs: 192.168.x.x (development/testing, not reachable externally)

Notable: The captive portal detection code (CheckCaptivePortalRequest.java) uses Chinese connectivity check URLs (Huawei HiCloud, Xiaomi) for CN cluster devices and Google URLs for international ones. This is actually smart engineering — Google's connectivity check URLs are blocked in China.

2b. IMEI Upload (UploadImeiAction.java)

Verdict: NOTABLE

The device uploads IMEI numbers, MAC address, and CPU serial to Onyx servers. This is triggered by a needToUploadImei flag in DeviceConfig. Key details:

  • Data sent: MAC address, CPU serial number, IMEI slot 1, IMEI slot 2
  • Destination: The active cluster's API endpoint (respects region selection)
  • When: Once per device, gated by a persistent flag (key_upload_imei)
  • Guard: Only runs when DeviceConfig.needToUploadImei is true AND hasn't been uploaded before (stored in MMKV)
  • API endpoint: DeviceService.uploadImei() with a hardcoded UUID token

This is device registration/activation data. It's the kind of thing a manufacturer collects to track device populations, warranty, and anti-theft. The fact that it only runs once and is gated behind a config flag is reassuring. However, IMEI is sensitive PII in many jurisdictions (it uniquely identifies a cellular modem worldwide).

2c. Hardware-Based Login (LoginByHardwareInfoRequest.java)

Verdict: NOTABLE

The device can auto-authenticate to Onyx cloud using hardware identifiers:

  • Method: Takes the MAC address, appends two hardcoded UUID salts, MD5-hashes each to create a username/password pair: MD5(mac + salt1) / MD5(mac + salt2)
  • Purpose: Creates an anonymous device account for cloud services without requiring user registration
  • Token management: Standard Bearer token auth, stored locally, refreshed on expiry

This is a common pattern for IoT/device cloud services. It means the device has a persistent cloud identity even without a user account. Not nefarious, but worth knowing — your device is "phoning home" with an identity derived from your MAC address.

2d. Reading Statistics (OnyxStatistics.java, PushStatisticsRequest.java, OnyxStatisticsService.java)

Verdict: NOTABLE

This is the most comprehensive telemetry system in the launcher. It tracks detailed reading behavior and syncs it to Onyx cloud.

Events tracked (BaseStatisticsModel types):

Type ID Event Data Collected
0 Document opened file path, title, name, authors, MD5 hash, doc ID
1 Page changed last page, current page, time spent on page
2 Annotation (add/update/delete) original text, user note, chapter, position
3 Dictionary lookup looked-up word
4 Text selected selected text content
5 Document closed chapter, current page, reading progress %, time spent
6 Document finished comment, score/rating, path, title, authors
7 Battery status battery level, status
8 Form field selected field name, field content
9 Document ID migration old doc ID, file path

Each event also includes: device MAC address, document MD5, session ID, timestamp, account ID (if logged in), and action type (add/update/delete).

Sync behavior:

  • Batches events (sends when buffer hits 5 events or on activity pause/resume)
  • Only syncs over WiFi (NetworkUtil.isWiFiConnected())
  • Requires user to be logged in (isLoggedIn())
  • Respects OnyxSystemConfig.isAutoSyncReaderStatistics() setting
  • Respects cluster-level statistics enable flag
  • Destination: cluster-appropriate API endpoint (e.g., en-data.boox.com/api/1/statistics/)

Analysis: This is standard e-reader usage analytics, similar to what Kindle, Kobo, and other e-readers collect. The data is reading-focused (what you read, for how long, what you annotate). It does NOT collect:

  • Screen contents or screenshots
  • Browsing history outside the reader
  • App usage data
  • Location data
  • Contact lists, messages, or other personal data
  • Keystroke data

The text selected and dictionary lookup events do send the actual text content, which could be sensitive depending on context. But this appears to be for syncing highlights/annotations to the cloud, not for surveillance.

Important safeguard: The checkPushable() method requires WiFi connection, user login, cluster enablement, AND the auto-sync setting to all be true before sending. Users who don't log into an Onyx account won't have statistics synced.

2e. Log Collection / Feedback (OnyxLogService.java, LogCollection.java)

Verdict: BENIGN

The log reporting system (OnyxLogService) is a user-initiated feedback/bug-report mechanism, NOT automatic telemetry:

  • reportLogCollection - POSTs a LogCollection containing:
    • User-provided name, email, description
    • ComplainInfo (reason code, reason text, prompt, content) - user's bug report
    • Firmware info (model, build, fingerprint)
    • ServerInfo (which cluster)
    • Optional zip file attachment (likely device logs)
  • getEncryptionKey - fetches an encryption key (presumably to encrypt the log upload)

This is a standard "Send Feedback" feature. The user explicitly triggers it and provides their own description. The firmware info is necessary context for diagnosing bugs.


2f. Cloud Index Service (CloudIndexServiceRequest.java, FirmwareOTAActivity.java)

Verdict: NOTABLE

During OTA firmware checks, the device contacts a hardcoded Chinese IP address (http://119.23.143.188/api/) regardless of which server cluster the user selected. This is the "Cloud Index Service" — a bootstrap endpoint that tells the device where its actual server is.

  • Data sent: MAC address, installation ID
  • Data received: Server configuration (which cluster to use)
  • Protocol: HTTP (unencrypted!)
  • Always hits this IP: Yes, even for US/EU users

This is likely the source of the "my Boox hits Chinese servers" reports. It's a server discovery/bootstrap mechanism, not data exfiltration. But it does mean:

  1. Every firmware check phones home to a Chinese IP
  2. The request is unencrypted (HTTP, not HTTPS)
  3. It sends your MAC address to that IP

2g. Reading Statistics: Chinese Cluster ONLY

Verdict: SIGNIFICANT FINDING (positive)

A critical discovery in ClusterManager.java line 123-125:

public static boolean isEnabledStatisticsCluster(ClusterInfo clusterInfo) {
    return clusterInfo.isChineseCluster();
}

Reading statistics are ONLY synced to the cloud for Chinese cluster users. The PushStatisticsRequest.checkPushable() method requires isEnabledStatisticsCluster() to return true, which only happens for the Chinese cluster. If you're on the US or EU server, all that reading telemetry (document opens, page changes, annotations, etc.) stays on-device and is never transmitted.

This is a major finding in favor of the "benign telemetry" hypothesis. Chinese users get reading analytics synced (presumably for the reading statistics feature in the Boox app). International users do not.


3. com.onyx.android.ksync (Cloud Sync Service)

Verdict: NOTABLE

The ksync app is the main cloud synchronization service. It handles syncing notes, reader data, calendar events, and messages between the device and Boox cloud.

3a. Alibaba Cloud OSS Storage (OssConfigInfo.java)

File uploads (notes, logs, AI data) go to Alibaba Cloud Object Storage:

Cluster OSS Endpoint Buckets
China oss-cn-shenzhen.aliyuncs.com onyx-note, onyx-log-collection, onyx-cloud, onyx-ai
US oss-us-west-1.aliyuncs.com onyx-note-us, onyx-log-collection-us, onyx-cloud-us, onyx-ai-us
Test oss-cn-shenzhen.aliyuncs.com onyx-cloud-test (always Chinese, even for US config)

Key point: US cluster data goes to Alibaba Cloud's US-West-1 region (Oregon). The data is stored on Alibaba Cloud infrastructure but in a US data center. Chinese cluster data stays in Shenzhen. The test bucket always goes to China, but test mode wouldn't be active on consumer devices.

All OSS connections use HTTPS.

3b. CouchDB/Couchbase Sync Protocol

The primary sync mechanism uses CouchDB replication over WebSocket:

  • China: wss://cb.send2boox.com/neocloud
  • US: wss://cb.boox.com/neocloud
  • EU: wss://eurcb.boox.com/neocloud

Sync data types:

  • Note documents and annotations (NoteDocDataReplicator)
  • Group collaboration data (GroupDocDataReplicator)
  • Reader/eBook metadata (ReaderDocDataReplicator)
  • Calendar events (CalendarReplicatorManager)

All sync connections use WSS (WebSocket Secure = encrypted).

3c. Device Fingerprinting (DeviceUtils.java)

The SDK collects several hardware identifiers:

Identifier Method Purpose
deviceUniqueId CPU ID (hex encoded), falls back to MAC address Primary device identity
deviceMAC WiFi MAC address Network identification
deviceSerial Android ID hashed to UUID, falls back to IMEI hashed Persistent device ID
cpuId CPU serial from /proc/cpuinfo Hardware fingerprint

The getDeviceSerial() method has a notable detail: it checks for Android ID 9774d56d682e549c (a known buggy value on some devices) and falls back to IMEI in that case. Otherwise it uses Android ID, which is scoped per-app on modern Android.

3d. Speech/AI Services

The ksync app integrates multiple Chinese AI services for speech recognition:

  • Alibaba Cloud (Aliyun) - Speech recognition
  • Baidu - Speech recognition
  • Volcengine (ByteDance) - Speech recognition
  • QWen (Alibaba LLM) - Document analysis (uploads files to cloud)

These are user-initiated features (speech-to-text, AI assistant). Audio data and documents are sent to these services when the user explicitly uses these features. They are not background data collection.

3e. Feedback/Log Upload Flow

When users submit feedback:

  1. Fetch encryption key from cloud (GetLogEncryptionKeyRequest)
  2. Compress device logs into zip
  3. Encrypt and upload zip to Alibaba OSS (onyx-log-collection bucket)
  4. Submit feedback metadata via CouchDB sync

This is explicitly user-initiated (you tap "Send Feedback"). The logs contain system diagnostic information for bug reports.


4. com.onyx.android.note (Notes App)

Verdict: BENIGN to NOTABLE

The notes app primarily relies on the same SDK infrastructure as the launcher.

4a. Note Sync

Notes sync via the same CouchDB replication protocol as ksync:

  • Note content (text, drawings, shapes) syncs to the user's selected cluster
  • Uses WSS (encrypted WebSocket)
  • Each note includes NoteDeviceInfo metadata (device info embedded in note)

4b. Third-Party Cloud Storage Integrations

The notes app supports exporting/syncing to many third-party services:

  • Chinese: Youdao Note, Baidu Cloud, Aliyun Drive, NutStore (Jianguoyun)
  • International: OneDrive, Dropbox, Notion, Readwise, Zotero, OneNote
  • Generic: WebDAV

These are opt-in integrations that the user explicitly configures. They follow standard OAuth flows.

4c. AI/OCR Features

  • Baidu OCR and Volcengine OCR for text recognition
  • AI assistant for document analysis (uploads to Aliyun AI)
  • These are user-initiated features, not background collection

4d. Notable Absence of Third-Party Analytics

Neither the ksync nor note app contains any commercial analytics SDKs. No Firebase Analytics, no Umeng, no Mixpanel, no AppsFlyer. The only analytics are Onyx's own reading statistics system (which, as noted, only syncs for Chinese cluster users).


Key Findings Summary

What the device DOES send:

  1. Device registration (once): IMEI, MAC, CPU serial → Onyx servers (respects cluster)
  2. Cloud index bootstrap: MAC + installation ID → hardcoded Chinese IP 119.23.143.188 (HTTP, unencrypted) during firmware checks
  3. Reading statistics: Detailed reading behavior → Onyx cloud, but ONLY for Chinese cluster users. US/EU users' reading stats stay local.
  4. Note sync: Note content → selected cluster's CouchDB (WSS encrypted)
  5. AI features (user-initiated): Documents/audio → Alibaba/Baidu/ByteDance AI services
  6. Feedback (user-initiated): Device logs + user description → Onyx cloud
  7. Captive portal checks: Hits region-appropriate connectivity check URLs

What the device does NOT send:

  • Screen contents or screenshots
  • Browsing history
  • App usage data (outside reading)
  • Location data
  • Contacts, SMS, call logs
  • Keystroke data
  • Microphone data (except when user explicitly uses speech features)
  • Camera data

5. com.onyx.aiassistant (AI Assistant)

Verdict: NOTABLE

The AI assistant is a cloud-dependent feature that sends user content to Onyx's AI backend for processing.

5a. Data Sent to AI Services

When using the AI assistant, the following data is transmitted:

  • Full conversation history (all user messages + AI responses) sent with every request
  • Document content when using document analysis features (PDF, EPUB, etc. up to 50MB)
  • Custom prompts and user input text
  • Reading context (document metadata, file path, MD5 hash)

5b. Device Identity in Every Request (DeviceUniqueIdHeaderInterceptor.java)

A notable finding: the AI assistant adds a deviceUniqueId HTTP header to every single API request via an OkHttp interceptor. This means every AI conversation is tied to a persistent device identity, even without a user account.

5c. Usage Quota Reporting (ReportUsageCountHelper.java)

The app reports feature usage counts to Onyx servers:

  • Endpoint: userPowers/updateUseinfo (POST)
  • Data: auth token, device model, permission tag, usage count
  • This is for enforcing free-tier usage limits on AI features

5d. Assessment

This is standard cloud AI assistant behavior. ChatGPT, Google Gemini, and every other cloud AI service works the same way — your conversation goes to servers for processing. The key points:

  • User-initiated only (you have to actively use the AI features)
  • No background data collection
  • No microphone/camera access detected in code
  • Usage counting is for quota enforcement, not surveillance

6. com.onyx.appmarket (App Market)

Verdict: BENIGN

The app market is straightforward with minimal tracking.

6a. App Browsing Data

When browsing/searching apps, the following is sent:

  • Device MAC address, device model, language
  • Search keywords, category filters, pagination
  • Hardcoded API token: onyx-app-token: 648220d9-7b90-43fd-bc2d-d217e00da1a7

6b. Download Counting

Each app download triggers a touchDownloadCount request sending the package name and device model. This is standard app store behavior for popularity tracking.

6c. No Third-Party Analytics

No Firebase, Umeng, Mixpanel, or any other commercial analytics SDK detected. Local EventBus events track UI state (clicks, downloads, installs) but these are not transmitted to servers.


7. com.onyx.easytransfer (EasyTransfer)

Verdict: BENIGN

EasyTransfer is primarily a local peer-to-peer file transfer tool.

7a. Transfer Mechanism

  • Uses TCP sockets on ports 8085 (file transfer) and 8086 (screen casting)
  • Operates over local WiFi — devices connect directly
  • Custom binary protocol using ktor/netty framework
  • File transfers do NOT phone home to Onyx servers

7b. WeChat Integration (Optional)

If the user opts into WeChat-based transfer, device registration occurs:

  • Sent to WeChat API (api.weixin.qq.com): MAC address, serial number, CPU model, device unique ID
  • WeChat AppID: wxdef46042a22e2e89
  • This is only triggered if the user explicitly uses the WeChat transfer feature

7c. Cleartext Traffic

The app allows cleartext HTTP traffic (for local WiFi transfers). This is expected for a local transfer tool but means transfers on shared WiFi could theoretically be sniffed.


8. com.onyx.igetshop (iGet Shop / DeDao)

Verdict: CONCERNING — but it's a third-party app, not Onyx code

This is the outlier in the entire analysis. igetshop is NOT an Onyx-developed app — it's a repackaged DeDao (得到) e-book/content platform by Luojilab, a major Chinese content company.

8a. Extensive Third-Party Analytics

Unlike every other Onyx app, this one is loaded with tracking:

  • AutoPointer (Luojilab's custom analytics): Sends click events, view events, user interactions to logs.luojilab.com
  • Tencent Bugly: Crash reporting with native crash + ANR tracking
  • UTDID2 (Alibaba): Cross-app device tracking identifier
  • Alibaba AMSDevReporter: SDK usage reporting
  • iFlytek SDK: Speech/AI services
  • Rong Cloud: Messaging infrastructure

8b. Behavioral Data Collected

The AutoPointer analytics system sends to logs.luojilab.com/logsSdk.do:

  • Event name, network type, user ID, session ID
  • Screen resolution, device MAC, timestamps
  • Click tracking (CTR events)
  • Content browsing behavior

8c. Aggressive Permissions

This app declares far more permissions than any other Onyx app:

  • ACCESS_FINE_LOCATION — GPS location
  • READ_PHONE_STATE — IMEI/phone number
  • CHANGE_WIFI_STATE — WiFi modification
  • SYSTEM_ALERT_WINDOW — Overlay windows
  • MANAGE_EXTERNAL_STORAGE — Full filesystem access
  • DUMP — System dump access
  • Cleartext traffic enabled

8d. Architecture

Hybrid app: native e-book reader + WebView-based shopping marketplace. Content loads from igetget.com and h5.sao.cn. Shopping and articles are web-based; book reading uses native Onyx SDK rendering.

8e. Important Context

This is a third-party content platform bundled by Onyx, similar to how Samsung bundles Facebook or carriers bundle bloatware. The tracking in this app is by Luojilab/DeDao, not by Onyx. It's the only app in the entire analysis with commercial analytics SDKs, location permissions, or aggressive data collection.

If you're concerned about privacy, this is the one app worth disabling or restricting via Android's app permissions.


9. com.onyx.kime (Keyboard / IME)

Verdict: BENIGN — Clean keyboard, no keystroke exfiltration

This was the most privacy-critical app to analyze — a keyboard that leaks keystrokes would be a dealbreaker. The findings are reassuring:

  • Engine: Built on Rime IME (open-source input method framework, v1.7.3). All keystroke processing happens locally.
  • ZERO keystroke transmission. No POST/PUT requests in the entire Kime codebase. Text is committed locally via InputConnection.commitText().
  • One network call total: GET api/1/keyboard — downloads dictionary metadata (names, versions, URLs, MD5 checksums) over WiFi only. No user data sent.
  • User dictionary is local only. No cloud sync of typed words or prediction data.
  • Clipboard monitoring exists but is purely local (for paste functionality).
  • No analytics SDKs. No Firebase, Crashlytics, or any telemetry.
  • No device fingerprinting in the keyboard code itself.
  • Speech-to-text is delegated to the Onyx SDK (which may use Baidu/Alibaba), but this is an optional feature the user explicitly activates.

Supported input methods: Pinyin, Cangjie, Wubi, Shuangpin, Bopomofo, Japanese, Korean, English, handwriting recognition.


10. com.onyx.kreader (E-Reader)

Verdict: NOTABLE

The dedicated e-reader app uses the same OnyxStatistics infrastructure as the launcher but adds some unique features:

10a. Library Tree Sync (PushLibraryTreeAction)

The reader can sync your entire book library structure to the cloud — not just reading stats, but metadata about which books you have and how they're organized. This is for cross-device library sync.

10b. Enhanced Reading Statistics

Same types as the launcher (document open/close, page changes, annotations, dictionary lookups, time spent), but note that these stats are still gated by isEnabledStatisticsCluster() — meaning they only sync for Chinese cluster users.

10c. Document Fingerprinting

Three-level identification for books:

  • MD5 hash of file content
  • Persistent docId (survives file renames)
  • File path with case-insensitive matching

This allows Onyx to track the same document across renames and devices. Standard for cross-device sync features, but worth noting.

10d. DRM Detection

ZhiShuDRMDetector identifies DRM-protected books (Chinese e-book platform). JD.com novel integration with encrypted PIN handling. No active license phone-home detected in decompiled code.

10e. No Additional Third-Party SDKs

No analytics beyond the standard Onyx SDK. Same clean profile as the other first-party apps.


11. com.onyx.mail (KMail)

Verdict: BENIGN — Standard email client, no Onyx proxying

KMail is a straightforward email client built on JavaMail (com.sun.mail):

  • Direct IMAP/POP3/SMTP connections to user's mail server. Email is NOT proxied through Onyx servers.
  • Email content never touches Onyx cloud for standard send/receive operations.
  • Only 2 Onyx-specific endpoints found:
    1. certificates/findByName?name=aliyunMail — fetches AES-encrypted credentials for the "memo-to-email" feature (send notes as email)
    2. users/send/mail — sends memos/notes as email attachments through Onyx cloud (only for the memo feature, not regular email)
  • Calendar sync uses direct Google Calendar API and Exchange Web Services.
  • No address book sync to Onyx cloud.
  • No analytics or telemetry detected.

Third-Party Dependencies (Note App as Example)

The note app bundles the following third-party libraries, representative of the Onyx SDK dependency tree:

Library Purpose Privacy Relevance
Alibaba FastJSON2 JSON serialization None (local processing)
Alibaba OSS SDK Cloud object storage File uploads to Alibaba Cloud
Dropbox SDK Dropbox integration User-initiated cloud sync
Evernote SDK Evernote export User-initiated
MyScript iink Handwriting recognition Local processing (on-device)
Tencent MMKV Key-value storage Local storage only
Tencent WeChat SDK WeChat sharing/login Sends device info to Tencent when used
Sardine (WebDAV) WebDAV client User-configured cloud sync
Microsoft Live SDK OneDrive/OneNote User-initiated cloud sync
OkHttp3 / Retrofit2 HTTP client Network transport layer
DBFlow (Raizlabs) SQLite ORM Local database
Glide (Bumptech) Image loading Local caching
xCrash Native crash capture Local crash logs
SmartRefreshLayout Pull-to-refresh UI None (UI only)
AndroidSVG (Caverock) SVG rendering None (local rendering)
OneGravity RTEditor Rich text editing None (local editing)
liulishuo FileDownloader File download manager Network downloads
asha libresample2 Audio resampling Local audio processing

Notable: No commercial analytics SDKs (Firebase, Umeng, Mixpanel, etc.) in the dependency tree. The Tencent dependency is MMKV (local storage) and WeChat SDK (social sharing), not analytics.


The "Chinese server" question:

For US/EU cluster users, the main data flows go to international endpoints (push.boox.com, en-data.boox.com, cb.boox.com). However, there are at least two cases where Chinese servers are contacted regardless:

  1. Cloud index service (119.23.143.188) during OTA checks — sends MAC address
  2. OSS test bucket (always oss-cn-shenzhen.aliyuncs.com) — but only active in test mode

The cloud index service is the most likely explanation for why users observe Chinese endpoint access. It's a server discovery mechanism, not data exfiltration, but it is an unnecessary leak of device identity to a Chinese IP over unencrypted HTTP.

Overall Assessment

The evidence strongly supports the benign telemetry hypothesis for Onyx's own apps. This is a Chinese company that:

  • Built region-aware infrastructure to route international users through non-Chinese servers
  • Disabled reading analytics sync entirely for non-Chinese users
  • Uses standard e-reader telemetry patterns comparable to Kindle/Kobo
  • Does NOT embed commercial analytics SDKs in their own apps
  • Does NOT collect sensitive personal data (contacts, location, etc.) in their own apps
  • Has a legitimate (if sloppy) bootstrap mechanism that hits a Chinese IP

The one exception is the bundled igetshop (DeDao) app, which is a third-party content platform with extensive commercial analytics, location permissions, and behavioral tracking. This is NOT Onyx's code — it's Luojilab's — but Onyx chose to bundle it.

Valid Criticisms

  1. Cloud index server (119.23.143.188): Unencrypted HTTP to a Chinese IP, leaking MAC addresses. Should be HTTPS and region-aware.
  2. IMEI upload: One-time device registration sends IMEI, MAC, CPU serial. Standard for manufacturers but IMEI is sensitive PII.
  3. Bundled third-party app (igetshop/DeDao): Aggressive tracking, location permissions, multiple analytics SDKs. Onyx should either not bundle this or clearly disclose it.
  4. AI assistant device tracking: Persistent device ID in every API request header.
  5. Some legacy HTTP endpoints: Several constants reference http:// rather than https:// for data.boox.com endpoints. Modern code appears to use HTTPS via ClusterHost, but legacy constants remain.

What Would Be Needed for a Stronger "Clean Bill of Health"

  • Move cloud index service to HTTPS with region-appropriate endpoints
  • Remove or make the igetshop app opt-in rather than pre-installed
  • Audit and remove legacy HTTP constants
  • Document the IMEI upload in privacy policy with clear opt-out
  • Add transparency about what the AI assistant device ID header is used for

Apps Analyzed

App Files Verdict Key Finding
com.onyx (launcher) 30,005 NOTABLE Region-aware infra, reading stats CN-only, index server leaks MAC
com.onyx.android.onyxotaservice 58 BENIGN Zero network calls, purely local
com.onyx.android.ksync 27,955 NOTABLE CouchDB sync, Alibaba OSS storage, speech AI services
com.onyx.android.note 27,838 BENIGN-NOTABLE Standard note sync, no extra tracking beyond SDK
com.onyx.aiassistant 17,053 NOTABLE Device ID header on all requests, usage quota reporting
com.onyx.appmarket 16,453 BENIGN Minimal tracking, download counting only
com.onyx.easytransfer 13,008 BENIGN P2P local transfer, optional WeChat integration
com.onyx.igetshop 7,311 CONCERNING Third-party (DeDao/Luojilab), heavy analytics, location perms
com.onyx.kime (keyboard) 16,493 BENIGN No keystroke exfiltration, Rime engine, 1 network call total
com.onyx.kreader (e-reader) 50,236 NOTABLE Library tree sync, reading stats (CN-only), DRM detection
com.onyx.mail (KMail) 19,918 BENIGN Direct IMAP/POP3/SMTP, no Onyx proxy, no analytics

Total Java files analyzed: ~226,328 across 11 APKs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment