Tencent/Shadow
零反射全动态Android插件框架
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 7w ago
- ✓11 active contributors
- ✓BSD-3-Clause licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Single-maintainer risk — top contributor 83% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/tencent/shadow)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/tencent/shadow on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: Tencent/Shadow
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/Tencent/Shadow shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 7w ago
- 11 active contributors
- BSD-3-Clause licensed
- CI configured
- Tests present
- ⚠ Single-maintainer risk — top contributor 83% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live Tencent/Shadow
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/Tencent/Shadow.
What it runs against: a local clone of Tencent/Shadow — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in Tencent/Shadow | Confirms the artifact applies here, not a fork |
| 2 | License is still BSD-3-Clause | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 76 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Tencent/Shadow. If you don't
# have one yet, run these first:
#
# git clone https://github.com/Tencent/Shadow.git
# cd Shadow
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of Tencent/Shadow and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Tencent/Shadow(\\.git)?\\b" \\
&& ok "origin remote is Tencent/Shadow" \\
|| miss "origin remote is not Tencent/Shadow (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(BSD-3-Clause)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"BSD-3-Clause\"" package.json 2>/dev/null) \\
&& ok "license is BSD-3-Clause" \\
|| miss "license drift — was BSD-3-Clause at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/HostApplication.java" \\
&& ok "projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/HostApplication.java" \\
|| miss "missing critical file: projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/HostApplication.java"
test -f "projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/PluginHelper.java" \\
&& ok "projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/PluginHelper.java" \\
|| miss "missing critical file: projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/PluginHelper.java"
test -f "projects/sample/dynamic-apk/sample-hello-api-holder/src/main/java/com/tencent/shadow/sample/apk/hello/DynamicHello.java" \\
&& ok "projects/sample/dynamic-apk/sample-hello-api-holder/src/main/java/com/tencent/shadow/sample/apk/hello/DynamicHello.java" \\
|| miss "missing critical file: projects/sample/dynamic-apk/sample-hello-api-holder/src/main/java/com/tencent/shadow/sample/apk/hello/DynamicHello.java"
test -f "projects/sample/dynamic-apk/sample-hello-apk/src/main/java/com/tencent/shadow/dynamic/impl/HelloFactoryImpl.java" \\
&& ok "projects/sample/dynamic-apk/sample-hello-apk/src/main/java/com/tencent/shadow/dynamic/impl/HelloFactoryImpl.java" \\
|| miss "missing critical file: projects/sample/dynamic-apk/sample-hello-apk/src/main/java/com/tencent/shadow/dynamic/impl/HelloFactoryImpl.java"
test -f "buildScripts/gradle/versions.properties" \\
&& ok "buildScripts/gradle/versions.properties" \\
|| miss "missing critical file: buildScripts/gradle/versions.properties"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 76 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~46d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/Tencent/Shadow"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Shadow is Tencent's zero-reflection, fully dynamic Android plugin framework that allows APKs to be loaded and executed as plugins without any bytecode manipulation or hidden API calls. It enables plugins to reuse existing standalone app source code and supports all four Android components, Fragments, DataBinding, cross-process Services, custom Themes, and multi-APK loading within a single host app—all while keeping host app footprint at just 15KB and ~160 methods. Monorepo: projects/sdk/ contains the plugin framework core (core.loader, core.transform in Kotlin; ShadowActivity, component proxies), projects/test/ has unit and integration tests with AGP version matrices, projects/sample/ has runnable sample apps (sample-app as standalone, sample-host as plugin host, sample-hello-api* as plugin feature modules). Build orchestration via buildScripts/gradle/{common.gradle, maven.gradle} with custom aar-to-jar-plugin for APK handling.
👥Who it's for
Android developers at companies deploying feature modules and business plugins at scale (Tencent validated with 'billion-level users'). Specifically: host app developers integrating dynamic features, plugin developers writing feature APKs that need component support, and framework engineers maintaining plugin ecosystems without reflection-based magic.
🌱Maturity & risk
Production-ready. Tencent's internal framework validated at billion-user scale. Repository shows well-organized structure (monorepo under projects/{sdk,test,sample}), comprehensive CI workflows (.github/workflows/check-build-test.yml, AGP compatibility testing), and detailed README with deployment guidance. Active maintenance with modern tooling (Android Studio Arctic Fox 2020.3.1+, Kotlin for core.loader and core.transform).
Low risk for established teams; moderate risk for smaller orgs. Code is large (1.18M Java, 460K Kotlin) with complex dynamics (classloader manipulation, bytecode transformation). Dependencies are well-managed via buildScripts/gradle/versions.properties. Main risk: fully dynamic plugin framework means bugs in host or plugin loading can crash entire app—requires careful testing. Documentation on '原理与设计说明文档' (design docs) is still listed as future work, so architectural deep-dives are limited.
Active areas of work
Active development with CI/CD workflows (check-build-test.yml triggers on push). GitHub Actions include pre-build and post-build steps (.github/actions/). Ongoing work on AGP (Android Gradle Plugin) compatibility across JDK 11 and JDK 17. Feature backlog in README: design documentation, multi-plugin demos, automated test expansion, and download manager implementation with plugin update capabilities.
🚀Get running
git clone https://github.com/Tencent/Shadow.git
cd Shadow
# Open in Android Studio (Arctic Fox 2020.3.1 or newer)
# or build via Gradle wrapper:
./gradlew build
# To run sample:
./gradlew :projects:sample:sample-host:installDebug
Daily commands:
# From repo root:
./gradlew build # Full build with tests
./gradlew :projects:sample:sample-host:assembleDebug # Build host APK
./gradlew :projects:sample:dynamic-apk:sample-hello-api:assembleDebug # Build plugin APK
# Or open in Android Studio and run sample-host or sample-app module directly
🗺️Map of the codebase
projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/HostApplication.java— Host application entry point that initializes the Shadow plugin framework and manages plugin lifecycle for the entire systemprojects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/PluginHelper.java— Core helper class that manages plugin loading, initialization, and communication between host and plugin processesprojects/sample/dynamic-apk/sample-hello-api-holder/src/main/java/com/tencent/shadow/sample/apk/hello/DynamicHello.java— Defines the dynamic interface contract that plugins must implement, serving as the bridge between host and plugin codeprojects/sample/dynamic-apk/sample-hello-apk/src/main/java/com/tencent/shadow/dynamic/impl/HelloFactoryImpl.java— Plugin-side factory implementation that instantiates plugin components without reflection, demonstrating Shadow's zero-reflection approachbuildScripts/gradle/versions.properties— Centralized dependency version management used across all subprojects and build scriptsbuild.gradle— Root build configuration that loads versions and manages buildscript dependencies for the entire multi-module project
🛠️How to make changes
Add a New Plugin Component (Activity, Service, etc.)
- Create the API interface in sample-hello-api module (
projects/sample/dynamic-apk/sample-hello-api/src/main/java/com/tencent/shadow/sample/api/hello/) - Implement the component in sample-hello-apk plugin module following the factory pattern without reflection (
projects/sample/dynamic-apk/sample-hello-apk/src/main/java/com/tencent/shadow/dynamic/impl/) - Register the factory in HelloFactoryImpl to enable host instantiation (
projects/sample/dynamic-apk/sample-hello-apk/src/main/java/com/tencent/shadow/dynamic/impl/HelloFactoryImpl.java) - Add the component to the whitelist if it accesses host APIs (
projects/sample/dynamic-apk/sample-hello-apk/src/main/java/com/tencent/shadow/dynamic/impl/WhiteList.java) - Declare in plugin manifest and host manifest with plugin-aware configuration (
projects/sample/dynamic-apk/sample-hello-apk/src/main/AndroidManifest.xml)
Enable Plugin Loading in Host Application
- Initialize Shadow framework in HostApplication with minimal overhead (
projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/HostApplication.java) - Configure plugin manager and update strategy in PluginHelper (
projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/PluginHelper.java) - Set up plugin API holder in FixedPathPmUpdater for runtime plugin availability (
projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/api/FixedPathPmUpdater.java) - Trigger plugin loading from UI activity (
projects/sample/dynamic-apk/sample-hello-host/src/main/java/com/tencent/shadow/sample/host/MainActivity.java)
Update Dependency Versions
- Edit the centralized versions properties file (
buildScripts/gradle/versions.properties) - Reference the version variable in subproject build.gradle files using ext.variableName (
projects/sample/dynamic-apk/sample-hello-api/build.gradle) - Rebuild and verify all modules sync correctly (
build.gradle)
🔧Why these technologies
- Kotlin for core.loader and core.transform — Concise syntax and null-safety reduce boilerplate and errors in complex plugin transformation logic
- Multi-module Gradle project — Enforces clear separation between API contracts, host, and plugin implementations; enables reuse of plugin source code for standalone APK
- Factory Pattern (no reflection) — Enables deterministic, type-safe plugin component instantiation without relying on reflection, ensuring compatibility with Google's non-public SDK restrictions
- Inter-process Communication (IPC) for Services — Allows plugins to expose services in separate processes, enabling isolation and better resource management
⚖️Trade-offs already made
-
All framework code is dynamically part of the plugin, not statically linked in host
- Why: Allows plugins to evolve independently of host APK versions, preventing version skew issues
- Consequence: Plugin APK size increases slightly, but host remains minimal; requires robust plugin versioning strategy
-
Zero-reflection API instantiation with explicit factory implementations
- Why: Eliminates hidden API usage that violates Android SDK restrictions and improves debuggability
- Consequence: Requires explicit factory code in each plugin; cannot auto-discover implementations via annotations or classpath scanning
-
Support for reusing standalone APK source code as-is
- Why: Reduces maintenance burden—developers can test plugins as normal apps before deployment
- Consequence: Must coordinate dual build targets and ensure manifest compatibility across standalone and plugin deployments
-
Minimal host footprint (~15KB, 160 method count)
- Why: Reduces host APK size impact and keeps host simple, critical for adoption
- Consequence: Heavy lifting deferred to plugin framework code loaded at runtime; requires careful separation of concerns
🚫Non-goals (don't propose these)
- Does not handle authentication or permission delegation between host and plugins (relies on whitelist)
- Not designed for real-time hot-swapping of running plugin code (plugins must be loaded and unloaded as complete units)
- Does not provide cross-plugin communication framework (each plugin is isolated from others)
- Not intended for obfuscation or anti-tampering of plugin
🪤Traps & gotchas
Tencent Maven mirror default: Build defaults to https://mirrors.tencent.com/nexus/repository/maven-public/ (faster in China); set DISABLE_TENCENT_MAVEN_MIRROR=true env var to fall back to Google/Maven Central if mirrors are unavailable. Buildscript duplication: buildscript blocks cannot import from other Gradle files per comments in build.gradle—must sync buildscript across multiple files when updating dependencies. AGP version matrix: Tests run against multiple AGP versions (see projects/test/gradle-plugin-agp-compat-test/); ensure local Android Studio AGP matches if tests mysteriously fail. ShadowActivity method coverage: Not all Activity methods are proxied—missing methods must be explicitly added; check test failures for 'Method Not Found' errors as your cue. Dynamic classloading gotcha: Plugin APKs are loaded into custom ClassLoaders, not app ClassLoader—this breaks some reflection-based libraries; Tencent's zero-reflection design avoids this but third-party dependencies may fail (undocumented trade-off).
🏗️Architecture
💡Concepts to learn
- ClassLoader hierarchy and plugin isolation — Shadow uses custom ClassLoaders to load plugin APKs into separate namespace without polluting host ClassLoader—understanding parent delegation and class resolution order is critical to diagnosing plugin-host conflicts
- Activity proxy pattern (ShadowActivity) — Host app doesn't directly instantiate plugin Activities; instead proxies route through ShadowActivity which delegates to plugin's real Activity—this is how Shadow avoids bytecode hacks
- Zero-reflection plugin instantiation — Shadow's core innovation: plugin classes are instantiated via standard constructor or factory methods, never via reflection API—this ensures forward compatibility as Android restricts hidden APIs
- Bytecode transformation (via core.transform) — Plugin APKs are modified at build time (not runtime) to inject compatibility code—understanding what transforms are applied prevents surprises when plugins behave differently than standalone APKs
- APK-to-JAR conversion (aar-to-jar-plugin) — Shadow's custom Gradle plugin extracts and restructures plugin APK resources for dynamic loading—critical to understand when build output layout doesn't match expected plugin structure
- Dynamic service binding across process boundaries — Shadow supports cross-process Service communication from host to plugin—requires understanding AIDL and Binder protocol, which Shadow abstracts but still requires careful IPC design
- Gradle plugin version matrix testing (AGP compatibility) — Shadow's test suite validates against multiple Android Gradle Plugin versions to ensure plugins work across different host build environments—understanding why this matters prevents version conflicts in production
🔗Related repos
DroidPlugin/DroidPlugin— Earlier Android plugin framework using reflection; comparison point showing why Shadow's zero-reflection approach is safer and more maintainablealibaba/atlas— Alibaba's plugin framework focusing on components; similar problem domain but different architecture—useful for evaluating trade-offs in dynamic loading strategiesgoogle/dynamicfeatures-ondemand— Google's on-demand dynamic feature delivery via Play Core Library; official alternative if you're distributing via Google Play (Shadow is broader, supports any host)Tencent/VasDolly— Tencent's companion tool for APK channel packaging and signing—commonly paired with Shadow for plugin distribution and versioningairbnb/epoxy— Not directly related but used in similar monorepo structures for modular feature development; demonstrates Android composition patterns Shadow enables
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for core plugin loading mechanism in projects/sample/dynamic-apk
The sample projects (sample-hello-api, sample-hello-api-holder, sample-hello-apk) demonstrate the plugin architecture but lack visible unit test coverage. Given that Shadow is a production framework used by billions, adding unit tests for the HelloFactory, IHelloWorld interface loading, and HelloImplLoader would validate the core dynamic loading mechanism and serve as regression tests for the framework.
- [ ] Create tests/unit/java/com/tencent/shadow/sample/apk/hello/ directory structure
- [ ] Add HelloImplLoaderTest.java to verify plugin class loading without reflection
- [ ] Add HelloFactoryTest.java to test interface instantiation and dynamic binding
- [ ] Verify tests pass in .github/workflows/check-build-test.yml
- [ ] Document test setup in projects/sample/README.md
Create GitHub Actions workflow to validate Gradle version compatibility across Android API levels
The README mentions the project is adapted for 'Android Studio Arctic Fox | 2020.3.1' and that 'lower versions may fail due to Gradle version being too high', but there's no automated CI validation. Add a workflow that tests building against multiple Gradle versions and AGP versions to prevent regressions and clarify compatibility matrix.
- [ ] Create .github/workflows/gradle-compatibility-matrix.yml
- [ ] Matrix test: gradle_version=[7.x, 8.x], agp_version=[4.2.x, 7.x, 8.x]
- [ ] Reuse .github/actions/pre-build and .github/actions/post-build
- [ ] Document minimum version requirements in CONTRIBUTING.md with test results
- [ ] Add badge to README.md linking to compatibility matrix results
Add integration tests validating the 15KB host footprint and 160 method count claims
Shadow's key differentiator is its minimal host footprint (15KB, ~160 methods), but this isn't validated in CI. Create a build artifact analyzer that measures and asserts these metrics for the core loader components, ensuring future changes don't bloat the host.
- [ ] Create buildScripts/gradle/artifact-metrics.gradle to measure APK/AAR sizes and method counts
- [ ] Add task to analyze core.loader and core.transform compiled sizes
- [ ] Integrate into .github/workflows/check-build-test.yml to fail if footprint exceeds thresholds
- [ ] Document metrics baseline in projects/sample/README.md
- [ ] Create buildScripts/gradle/method-count-validator.gradle using 'method-count-transformer' or similar tool
🌿Good first issues
- Add missing Activity lifecycle methods to
ShadowActivity.javabased on Android 12+ API additions (e.g.,onPictureInPictureModeChanged)—grep test failures for 'Method Not Found', implement as simple delegation to proxy. - Expand automated test coverage for Fragment XML inflation in plugins (
projects/test/lacks Fragment layout inflation tests mentioned in README supported features)—create test case underprojects/test/mirroring sample-hello-api pattern. - Document the plugin API holder pattern used in
sample-hello-api*modules with a step-by-step guide inprojects/sample/README.md—currently only inferred from source; add code comments and CONTRIBUTING.md examples.
⭐Top contributors
Click to expand
Top contributors
- @shifujun — 83 commits
- @yanglw — 5 commits
- @AntonioShare — 3 commits
- @aprz512 — 2 commits
- @4327b9fb — 1 commits
📝Recent commits
Click to expand
Recent commits
4e9f70a— fix(core.loader): 修复容器authority和插件authority相同时返回错误 Uri 的问题 (yanglw)aff2f05— feat(core.runtime): 支持Content Provider多authority功能 (yanglw)adafe8e— feat(core.runtime): 支持Content Provider设置multiprocess="true" (yanglw)45bb5d0— fix(core.gradle-plugin): 修复在 Windows 平台连续 gradle clean 打包失败的问题 (yanglw)05c213b— feat(core.gradle-plugin): 支持AGP 8后开启shrinkResources (yanglw)474e6bf— ci: 主动安装Android SDK 33 (shifujun)f9dc394— fix(core.gradle-plugin): 兼容AGP 8.9.0 (4327b9fb)09e7e0a— build: 修复IDE无法直接Run项目的问题 (shifujun)04094e0— fix: sample-host更新manager.apk时需要先设置可写入 (shifujun)d577c95— fix(sample): 大于API 33,广播插件case,运行崩溃 (AntonioShare)
🔒Security observations
The Shadow Android plugin framework codebase shows a moderate security posture with several concerns primarily around dependency management, dynamic code loading, and plugin validation. The framework's architecture inherently involves dynamic loading and plugin execution, which introduces inherent security risks that must be mitigated through strict validation, whitelisting, and artifact verification. Key issues include unvalidated repository configurations, lack of version pinning for critical dependencies, and potential insecure deserialization in the plugin loading mechanism. The codebase would benefit from implementing dependency scanning in CI/CD, strict plugin validation policies, and comprehensive security documentation for plugin developers.
- High · Unvalidated Maven Repository Configuration —
build.gradle (buildscript repositories section). The build.gradle file uses a Tencent mirror repository (https://mirrors.tencent.com/nexus/repository/maven-public/) that can be disabled via an environment variable. If the mirror is unavailable or compromised, dependencies may be pulled from fallback repositories without proper verification. Additionally, there's no checksum validation for downloaded artifacts. Fix: Implement artifact checksum verification, use repository authentication, pin specific dependency versions, and consider using a private artifact repository with security scanning enabled. - High · Dynamic Dependency Loading Without Version Pinning —
build.gradle (classpath dependencies). The build.gradle uses dynamic version properties loaded from versions.properties file without clear version pinning for critical classpath dependencies like 'com.android.tools.build:gradle' and 'com.tencent.shadow.coding' plugins. This creates a supply chain risk where updated plugins could introduce malicious code. Fix: Pin all dependency versions to specific releases, implement dependency lock files (gradle.lockfile), and audit all transitive dependencies using 'gradle dependencies' command. - Medium · Potential Insecure Deserialization in Plugin Framework —
projects/sample/dynamic-apk/ (plugin loading mechanism). The Shadow plugin framework is described as supporting dynamic APK loading and full dynamic implementation. Dynamic loading and deserialization of plugin code without strict validation could allow arbitrary code execution if plugin sources are compromised. Fix: Implement strict whitelist validation for plugin classes, use signed/verified plugin packages, implement runtime permission checking, and audit the HelloFactoryImpl and plugin loading mechanisms for unsafe deserialization. - Medium · WhiteList Implementation May Be Incomplete —
projects/sample/dynamic-apk/sample-hello-apk/src/main/java/com/tencent/shadow/dynamic/impl/WhiteList.java. A WhiteList.java file exists in the plugin sample, but without reviewing its implementation, there's a risk that the whitelist mechanism is incomplete or bypassable, potentially allowing plugins to access restricted host classes or APIs. Fix: Review and audit the whitelist implementation for completeness, ensure it covers all sensitive APIs, implement logging for whitelist violations, and consider using a declarative security policy file. - Medium · Gradle Wrapper JAR File in Repository —
gradle/wrapper/gradle-wrapper.jar and gradle/wrapper/gradle-wrapper.properties. The gradle-wrapper.jar is committed to the repository. While gradle-wrapper is generally necessary, the JAR file should be verified to ensure it hasn't been tampered with. The wrapper.properties should validate the checksum. Fix: Verify the gradle-wrapper.jar integrity, ensure gradle-wrapper.properties contains the distributionSha256Sum for validation, and consider implementing automated checks to prevent tampered wrapper updates. - Low · Missing Security Headers in Build Configuration —
projects/sample/ (build.gradle files). The build configuration lacks explicit security settings such as minSdkVersion security constraints, ProGuard/R8 obfuscation verification, and network security configuration details. Fix: Explicitly set minimum SDK version appropriately, enable ProGuard/R8 obfuscation in release builds, implement network security configuration (network-security-config.xml), and add integrity checking. - Low · No Dependency Security Scanning Visible —
.github/workflows/ (CI/CD configuration). No evidence of dependency vulnerability scanning tools (like OWASP Dependency-Check, Snyk) in the build pipeline or CI/CD configuration. Fix: Integrate OWASP Dependency-Check or similar tools into GitHub Actions workflows, scan for known vulnerabilities in classpath dependencies, and fail builds on critical vulnerabilities.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.