@wazir-dev/cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +111 -0
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/assets/composition-engine.mmd +34 -0
- package/assets/demo-script.sh +17 -0
- package/assets/logo-dark.svg +14 -0
- package/assets/logo.svg +14 -0
- package/assets/pipeline.mmd +39 -0
- package/assets/record-demo.sh +51 -0
- package/docs/README.md +51 -0
- package/docs/adapters/context-mode.md +60 -0
- package/docs/concepts/architecture.md +87 -0
- package/docs/concepts/artifact-model.md +60 -0
- package/docs/concepts/composition-engine.md +36 -0
- package/docs/concepts/indexing-and-recall.md +160 -0
- package/docs/concepts/observability.md +41 -0
- package/docs/concepts/roles-and-workflows.md +59 -0
- package/docs/concepts/terminology-policy.md +27 -0
- package/docs/getting-started/01-installation.md +78 -0
- package/docs/getting-started/02-first-run.md +102 -0
- package/docs/getting-started/03-adding-to-project.md +15 -0
- package/docs/getting-started/04-host-setup.md +15 -0
- package/docs/guides/ci-integration.md +15 -0
- package/docs/guides/creating-skills.md +15 -0
- package/docs/guides/expertise-module-authoring.md +15 -0
- package/docs/guides/hook-development.md +15 -0
- package/docs/guides/memory-and-learnings.md +34 -0
- package/docs/guides/multi-host-export.md +15 -0
- package/docs/guides/troubleshooting.md +101 -0
- package/docs/guides/writing-custom-roles.md +15 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
- package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
- package/docs/readmes/INDEX.md +99 -0
- package/docs/readmes/features/expertise/README.md +171 -0
- package/docs/readmes/features/exports/README.md +222 -0
- package/docs/readmes/features/hooks/README.md +103 -0
- package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
- package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
- package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
- package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
- package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
- package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
- package/docs/readmes/features/hooks/session-start.md +119 -0
- package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
- package/docs/readmes/features/roles/README.md +157 -0
- package/docs/readmes/features/roles/clarifier.md +152 -0
- package/docs/readmes/features/roles/content-author.md +190 -0
- package/docs/readmes/features/roles/designer.md +193 -0
- package/docs/readmes/features/roles/executor.md +184 -0
- package/docs/readmes/features/roles/learner.md +210 -0
- package/docs/readmes/features/roles/planner.md +182 -0
- package/docs/readmes/features/roles/researcher.md +164 -0
- package/docs/readmes/features/roles/reviewer.md +184 -0
- package/docs/readmes/features/roles/specifier.md +162 -0
- package/docs/readmes/features/roles/verifier.md +215 -0
- package/docs/readmes/features/schemas/README.md +178 -0
- package/docs/readmes/features/skills/README.md +63 -0
- package/docs/readmes/features/skills/brainstorming.md +96 -0
- package/docs/readmes/features/skills/debugging.md +148 -0
- package/docs/readmes/features/skills/design.md +120 -0
- package/docs/readmes/features/skills/prepare-next.md +109 -0
- package/docs/readmes/features/skills/run-audit.md +159 -0
- package/docs/readmes/features/skills/scan-project.md +109 -0
- package/docs/readmes/features/skills/self-audit.md +176 -0
- package/docs/readmes/features/skills/tdd.md +137 -0
- package/docs/readmes/features/skills/using-skills.md +92 -0
- package/docs/readmes/features/skills/verification.md +120 -0
- package/docs/readmes/features/skills/writing-plans.md +104 -0
- package/docs/readmes/features/tooling/README.md +320 -0
- package/docs/readmes/features/workflows/README.md +186 -0
- package/docs/readmes/features/workflows/author.md +181 -0
- package/docs/readmes/features/workflows/clarify.md +154 -0
- package/docs/readmes/features/workflows/design-review.md +171 -0
- package/docs/readmes/features/workflows/design.md +169 -0
- package/docs/readmes/features/workflows/discover.md +162 -0
- package/docs/readmes/features/workflows/execute.md +173 -0
- package/docs/readmes/features/workflows/learn.md +167 -0
- package/docs/readmes/features/workflows/plan-review.md +165 -0
- package/docs/readmes/features/workflows/plan.md +170 -0
- package/docs/readmes/features/workflows/prepare-next.md +167 -0
- package/docs/readmes/features/workflows/review.md +169 -0
- package/docs/readmes/features/workflows/run-audit.md +191 -0
- package/docs/readmes/features/workflows/spec-challenge.md +159 -0
- package/docs/readmes/features/workflows/specify.md +160 -0
- package/docs/readmes/features/workflows/verify.md +177 -0
- package/docs/readmes/packages/README.md +50 -0
- package/docs/readmes/packages/ajv.md +117 -0
- package/docs/readmes/packages/context-mode.md +118 -0
- package/docs/readmes/packages/gray-matter.md +116 -0
- package/docs/readmes/packages/node-test.md +137 -0
- package/docs/readmes/packages/yaml.md +112 -0
- package/docs/reference/configuration-reference.md +159 -0
- package/docs/reference/expertise-index.md +52 -0
- package/docs/reference/git-flow.md +43 -0
- package/docs/reference/hooks.md +87 -0
- package/docs/reference/host-exports.md +50 -0
- package/docs/reference/launch-checklist.md +172 -0
- package/docs/reference/marketplace-listings.md +76 -0
- package/docs/reference/release-process.md +34 -0
- package/docs/reference/roles-reference.md +77 -0
- package/docs/reference/skills.md +33 -0
- package/docs/reference/templates.md +29 -0
- package/docs/reference/tooling-cli.md +94 -0
- package/docs/truth-claims.yaml +222 -0
- package/expertise/PROGRESS.md +63 -0
- package/expertise/README.md +18 -0
- package/expertise/antipatterns/PROGRESS.md +56 -0
- package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
- package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
- package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
- package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
- package/expertise/antipatterns/backend/index.md +24 -0
- package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
- package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
- package/expertise/antipatterns/code/async-antipatterns.md +622 -0
- package/expertise/antipatterns/code/code-smells.md +1186 -0
- package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
- package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
- package/expertise/antipatterns/code/index.md +27 -0
- package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
- package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
- package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
- package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
- package/expertise/antipatterns/design/dark-patterns.md +1121 -0
- package/expertise/antipatterns/design/index.md +22 -0
- package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
- package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
- package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
- package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
- package/expertise/antipatterns/frontend/index.md +23 -0
- package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
- package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
- package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
- package/expertise/antipatterns/index.md +31 -0
- package/expertise/antipatterns/performance/index.md +20 -0
- package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
- package/expertise/antipatterns/performance/premature-optimization.md +623 -0
- package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
- package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
- package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
- package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
- package/expertise/antipatterns/process/index.md +23 -0
- package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
- package/expertise/antipatterns/security/index.md +20 -0
- package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
- package/expertise/antipatterns/security/security-theater.md +843 -0
- package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
- package/expertise/architecture/PROGRESS.md +70 -0
- package/expertise/architecture/data/caching-architecture.md +671 -0
- package/expertise/architecture/data/data-consistency.md +574 -0
- package/expertise/architecture/data/data-modeling.md +536 -0
- package/expertise/architecture/data/event-streams-and-queues.md +634 -0
- package/expertise/architecture/data/index.md +25 -0
- package/expertise/architecture/data/search-architecture.md +663 -0
- package/expertise/architecture/data/sql-vs-nosql.md +708 -0
- package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
- package/expertise/architecture/decisions/build-vs-buy.md +616 -0
- package/expertise/architecture/decisions/index.md +23 -0
- package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
- package/expertise/architecture/decisions/technology-selection.md +616 -0
- package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
- package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
- package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
- package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
- package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
- package/expertise/architecture/distributed/index.md +25 -0
- package/expertise/architecture/distributed/saga-pattern.md +797 -0
- package/expertise/architecture/foundations/architectural-thinking.md +460 -0
- package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
- package/expertise/architecture/foundations/design-principles-solid.md +649 -0
- package/expertise/architecture/foundations/domain-driven-design.md +719 -0
- package/expertise/architecture/foundations/index.md +25 -0
- package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
- package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
- package/expertise/architecture/index.md +34 -0
- package/expertise/architecture/integration/api-design-graphql.md +638 -0
- package/expertise/architecture/integration/api-design-grpc.md +804 -0
- package/expertise/architecture/integration/api-design-rest.md +892 -0
- package/expertise/architecture/integration/index.md +25 -0
- package/expertise/architecture/integration/third-party-integration.md +795 -0
- package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
- package/expertise/architecture/integration/websockets-realtime.md +791 -0
- package/expertise/architecture/mobile-architecture/index.md +22 -0
- package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
- package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
- package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
- package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
- package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
- package/expertise/architecture/patterns/event-driven.md +797 -0
- package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
- package/expertise/architecture/patterns/index.md +27 -0
- package/expertise/architecture/patterns/layered-architecture.md +736 -0
- package/expertise/architecture/patterns/microservices.md +753 -0
- package/expertise/architecture/patterns/modular-monolith.md +692 -0
- package/expertise/architecture/patterns/monolith.md +626 -0
- package/expertise/architecture/patterns/plugin-architecture.md +735 -0
- package/expertise/architecture/patterns/serverless.md +780 -0
- package/expertise/architecture/scaling/database-scaling.md +615 -0
- package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
- package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
- package/expertise/architecture/scaling/index.md +24 -0
- package/expertise/architecture/scaling/multi-tenancy.md +800 -0
- package/expertise/architecture/scaling/stateless-design.md +787 -0
- package/expertise/backend/embedded-firmware.md +625 -0
- package/expertise/backend/go.md +853 -0
- package/expertise/backend/index.md +24 -0
- package/expertise/backend/java-spring.md +448 -0
- package/expertise/backend/node-typescript.md +625 -0
- package/expertise/backend/python-fastapi.md +724 -0
- package/expertise/backend/rust.md +458 -0
- package/expertise/backend/solidity.md +711 -0
- package/expertise/composition-map.yaml +443 -0
- package/expertise/content/foundations/content-modeling.md +395 -0
- package/expertise/content/foundations/editorial-standards.md +449 -0
- package/expertise/content/foundations/index.md +24 -0
- package/expertise/content/foundations/microcopy.md +455 -0
- package/expertise/content/foundations/terminology-governance.md +509 -0
- package/expertise/content/index.md +34 -0
- package/expertise/content/patterns/accessibility-copy.md +518 -0
- package/expertise/content/patterns/index.md +24 -0
- package/expertise/content/patterns/notification-content.md +433 -0
- package/expertise/content/patterns/sample-content.md +486 -0
- package/expertise/content/patterns/state-copy.md +439 -0
- package/expertise/design/PROGRESS.md +58 -0
- package/expertise/design/disciplines/dark-mode-theming.md +577 -0
- package/expertise/design/disciplines/design-systems.md +595 -0
- package/expertise/design/disciplines/index.md +25 -0
- package/expertise/design/disciplines/information-architecture.md +800 -0
- package/expertise/design/disciplines/interaction-design.md +788 -0
- package/expertise/design/disciplines/responsive-design.md +552 -0
- package/expertise/design/disciplines/usability-testing.md +516 -0
- package/expertise/design/disciplines/user-research.md +792 -0
- package/expertise/design/foundations/accessibility-design.md +796 -0
- package/expertise/design/foundations/color-theory.md +797 -0
- package/expertise/design/foundations/iconography.md +795 -0
- package/expertise/design/foundations/index.md +26 -0
- package/expertise/design/foundations/motion-and-animation.md +653 -0
- package/expertise/design/foundations/rtl-design.md +585 -0
- package/expertise/design/foundations/spacing-and-layout.md +607 -0
- package/expertise/design/foundations/typography.md +800 -0
- package/expertise/design/foundations/visual-hierarchy.md +761 -0
- package/expertise/design/index.md +32 -0
- package/expertise/design/patterns/authentication-flows.md +474 -0
- package/expertise/design/patterns/content-consumption.md +789 -0
- package/expertise/design/patterns/data-display.md +618 -0
- package/expertise/design/patterns/e-commerce.md +1494 -0
- package/expertise/design/patterns/feedback-and-states.md +642 -0
- package/expertise/design/patterns/forms-and-input.md +819 -0
- package/expertise/design/patterns/gamification.md +801 -0
- package/expertise/design/patterns/index.md +31 -0
- package/expertise/design/patterns/microinteractions.md +449 -0
- package/expertise/design/patterns/navigation.md +800 -0
- package/expertise/design/patterns/notifications.md +705 -0
- package/expertise/design/patterns/onboarding.md +700 -0
- package/expertise/design/patterns/search-and-filter.md +601 -0
- package/expertise/design/patterns/settings-and-preferences.md +768 -0
- package/expertise/design/patterns/social-and-community.md +748 -0
- package/expertise/design/platforms/desktop-native.md +612 -0
- package/expertise/design/platforms/index.md +25 -0
- package/expertise/design/platforms/mobile-android.md +825 -0
- package/expertise/design/platforms/mobile-cross-platform.md +983 -0
- package/expertise/design/platforms/mobile-ios.md +699 -0
- package/expertise/design/platforms/tablet.md +794 -0
- package/expertise/design/platforms/web-dashboard.md +790 -0
- package/expertise/design/platforms/web-responsive.md +550 -0
- package/expertise/design/psychology/behavioral-nudges.md +449 -0
- package/expertise/design/psychology/cognitive-load.md +1191 -0
- package/expertise/design/psychology/error-psychology.md +778 -0
- package/expertise/design/psychology/index.md +22 -0
- package/expertise/design/psychology/persuasive-design.md +736 -0
- package/expertise/design/psychology/user-mental-models.md +623 -0
- package/expertise/design/tooling/open-pencil.md +266 -0
- package/expertise/frontend/angular.md +1073 -0
- package/expertise/frontend/desktop-electron.md +546 -0
- package/expertise/frontend/flutter.md +782 -0
- package/expertise/frontend/index.md +27 -0
- package/expertise/frontend/native-android.md +409 -0
- package/expertise/frontend/native-ios.md +490 -0
- package/expertise/frontend/react-native.md +1160 -0
- package/expertise/frontend/react.md +808 -0
- package/expertise/frontend/vue.md +1089 -0
- package/expertise/humanize/domain-rules-code.md +79 -0
- package/expertise/humanize/domain-rules-content.md +67 -0
- package/expertise/humanize/domain-rules-technical-docs.md +56 -0
- package/expertise/humanize/index.md +35 -0
- package/expertise/humanize/self-audit-checklist.md +87 -0
- package/expertise/humanize/sentence-patterns.md +218 -0
- package/expertise/humanize/vocabulary-blacklist.md +105 -0
- package/expertise/i18n/PROGRESS.md +65 -0
- package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
- package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
- package/expertise/i18n/advanced/complex-scripts.md +30 -0
- package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
- package/expertise/i18n/advanced/testing-i18n.md +28 -0
- package/expertise/i18n/content/content-adaptation.md +23 -0
- package/expertise/i18n/content/locale-specific-formatting.md +23 -0
- package/expertise/i18n/content/machine-translation-integration.md +28 -0
- package/expertise/i18n/content/translation-management.md +29 -0
- package/expertise/i18n/foundations/date-time-calendars.md +67 -0
- package/expertise/i18n/foundations/i18n-architecture.md +272 -0
- package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
- package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
- package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
- package/expertise/i18n/foundations/string-externalization.md +236 -0
- package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
- package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
- package/expertise/i18n/index.md +38 -0
- package/expertise/i18n/platform/backend-i18n.md +31 -0
- package/expertise/i18n/platform/flutter-i18n.md +148 -0
- package/expertise/i18n/platform/native-android-i18n.md +36 -0
- package/expertise/i18n/platform/native-ios-i18n.md +36 -0
- package/expertise/i18n/platform/react-i18n.md +103 -0
- package/expertise/i18n/platform/web-css-i18n.md +81 -0
- package/expertise/i18n/rtl/arabic-specific.md +175 -0
- package/expertise/i18n/rtl/hebrew-specific.md +149 -0
- package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
- package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
- package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
- package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
- package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
- package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
- package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
- package/expertise/i18n/rtl/rtl-typography.md +160 -0
- package/expertise/index.md +113 -0
- package/expertise/index.yaml +216 -0
- package/expertise/infrastructure/cloud-aws.md +597 -0
- package/expertise/infrastructure/cloud-gcp.md +599 -0
- package/expertise/infrastructure/cybersecurity.md +816 -0
- package/expertise/infrastructure/database-mongodb.md +447 -0
- package/expertise/infrastructure/database-postgres.md +400 -0
- package/expertise/infrastructure/devops-cicd.md +787 -0
- package/expertise/infrastructure/index.md +27 -0
- package/expertise/performance/PROGRESS.md +50 -0
- package/expertise/performance/backend/api-latency.md +1204 -0
- package/expertise/performance/backend/background-jobs.md +506 -0
- package/expertise/performance/backend/connection-pooling.md +1209 -0
- package/expertise/performance/backend/database-query-optimization.md +515 -0
- package/expertise/performance/backend/index.md +23 -0
- package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
- package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
- package/expertise/performance/foundations/caching-strategies.md +489 -0
- package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
- package/expertise/performance/foundations/index.md +24 -0
- package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
- package/expertise/performance/foundations/memory-management.md +964 -0
- package/expertise/performance/foundations/performance-budgets.md +1314 -0
- package/expertise/performance/index.md +31 -0
- package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
- package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
- package/expertise/performance/infrastructure/index.md +22 -0
- package/expertise/performance/infrastructure/load-balancing.md +1081 -0
- package/expertise/performance/infrastructure/observability.md +1079 -0
- package/expertise/performance/mobile/index.md +23 -0
- package/expertise/performance/mobile/mobile-animations.md +544 -0
- package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
- package/expertise/performance/mobile/mobile-network.md +452 -0
- package/expertise/performance/mobile/mobile-rendering.md +599 -0
- package/expertise/performance/mobile/mobile-startup-time.md +505 -0
- package/expertise/performance/platform-specific/flutter-performance.md +647 -0
- package/expertise/performance/platform-specific/index.md +22 -0
- package/expertise/performance/platform-specific/node-performance.md +1307 -0
- package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
- package/expertise/performance/platform-specific/react-performance.md +1403 -0
- package/expertise/performance/web/bundle-optimization.md +1239 -0
- package/expertise/performance/web/image-and-media.md +636 -0
- package/expertise/performance/web/index.md +24 -0
- package/expertise/performance/web/network-optimization.md +1133 -0
- package/expertise/performance/web/rendering-performance.md +1098 -0
- package/expertise/performance/web/ssr-and-hydration.md +918 -0
- package/expertise/performance/web/web-vitals.md +1374 -0
- package/expertise/quality/accessibility.md +985 -0
- package/expertise/quality/evidence-based-verification.md +499 -0
- package/expertise/quality/index.md +24 -0
- package/expertise/quality/ml-model-audit.md +614 -0
- package/expertise/quality/performance.md +600 -0
- package/expertise/quality/testing-api.md +891 -0
- package/expertise/quality/testing-mobile.md +496 -0
- package/expertise/quality/testing-web.md +849 -0
- package/expertise/security/PROGRESS.md +54 -0
- package/expertise/security/agentic-identity.md +540 -0
- package/expertise/security/compliance-frameworks.md +601 -0
- package/expertise/security/data/data-encryption.md +364 -0
- package/expertise/security/data/data-privacy-gdpr.md +692 -0
- package/expertise/security/data/database-security.md +1171 -0
- package/expertise/security/data/index.md +22 -0
- package/expertise/security/data/pii-handling.md +531 -0
- package/expertise/security/foundations/authentication.md +1041 -0
- package/expertise/security/foundations/authorization.md +603 -0
- package/expertise/security/foundations/cryptography.md +1001 -0
- package/expertise/security/foundations/index.md +25 -0
- package/expertise/security/foundations/owasp-top-10.md +1354 -0
- package/expertise/security/foundations/secrets-management.md +1217 -0
- package/expertise/security/foundations/secure-sdlc.md +700 -0
- package/expertise/security/foundations/supply-chain-security.md +698 -0
- package/expertise/security/index.md +31 -0
- package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
- package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
- package/expertise/security/infrastructure/container-security.md +721 -0
- package/expertise/security/infrastructure/incident-response.md +1295 -0
- package/expertise/security/infrastructure/index.md +24 -0
- package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
- package/expertise/security/infrastructure/network-security.md +1337 -0
- package/expertise/security/mobile/index.md +23 -0
- package/expertise/security/mobile/mobile-android-security.md +1218 -0
- package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
- package/expertise/security/mobile/mobile-data-storage.md +1265 -0
- package/expertise/security/mobile/mobile-ios-security.md +1401 -0
- package/expertise/security/mobile/mobile-network-security.md +1520 -0
- package/expertise/security/smart-contract-security.md +594 -0
- package/expertise/security/testing/index.md +22 -0
- package/expertise/security/testing/penetration-testing.md +1258 -0
- package/expertise/security/testing/security-code-review.md +1765 -0
- package/expertise/security/testing/threat-modeling.md +1074 -0
- package/expertise/security/testing/vulnerability-scanning.md +1062 -0
- package/expertise/security/web/api-security.md +586 -0
- package/expertise/security/web/cors-and-headers.md +433 -0
- package/expertise/security/web/csrf.md +562 -0
- package/expertise/security/web/file-upload.md +1477 -0
- package/expertise/security/web/index.md +25 -0
- package/expertise/security/web/injection.md +1375 -0
- package/expertise/security/web/session-management.md +1101 -0
- package/expertise/security/web/xss.md +1158 -0
- package/exports/README.md +17 -0
- package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
- package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
- package/exports/hosts/claude/.claude/agents/designer.md +55 -0
- package/exports/hosts/claude/.claude/agents/executor.md +55 -0
- package/exports/hosts/claude/.claude/agents/learner.md +51 -0
- package/exports/hosts/claude/.claude/agents/planner.md +53 -0
- package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
- package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
- package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
- package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
- package/exports/hosts/claude/.claude/commands/author.md +42 -0
- package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
- package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
- package/exports/hosts/claude/.claude/commands/design.md +44 -0
- package/exports/hosts/claude/.claude/commands/discover.md +37 -0
- package/exports/hosts/claude/.claude/commands/execute.md +48 -0
- package/exports/hosts/claude/.claude/commands/learn.md +38 -0
- package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
- package/exports/hosts/claude/.claude/commands/plan.md +39 -0
- package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
- package/exports/hosts/claude/.claude/commands/review.md +40 -0
- package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
- package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
- package/exports/hosts/claude/.claude/commands/specify.md +38 -0
- package/exports/hosts/claude/.claude/commands/verify.md +37 -0
- package/exports/hosts/claude/.claude/settings.json +34 -0
- package/exports/hosts/claude/CLAUDE.md +19 -0
- package/exports/hosts/claude/export.manifest.json +38 -0
- package/exports/hosts/claude/host-package.json +67 -0
- package/exports/hosts/codex/AGENTS.md +19 -0
- package/exports/hosts/codex/export.manifest.json +38 -0
- package/exports/hosts/codex/host-package.json +41 -0
- package/exports/hosts/cursor/.cursor/hooks.json +16 -0
- package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
- package/exports/hosts/cursor/export.manifest.json +38 -0
- package/exports/hosts/cursor/host-package.json +42 -0
- package/exports/hosts/gemini/GEMINI.md +19 -0
- package/exports/hosts/gemini/export.manifest.json +38 -0
- package/exports/hosts/gemini/host-package.json +41 -0
- package/hooks/README.md +18 -0
- package/hooks/definitions/loop_cap_guard.yaml +21 -0
- package/hooks/definitions/post_tool_capture.yaml +24 -0
- package/hooks/definitions/pre_compact_summary.yaml +19 -0
- package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
- package/hooks/definitions/protected_path_write_guard.yaml +19 -0
- package/hooks/definitions/session_start.yaml +19 -0
- package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
- package/hooks/loop-cap-guard +17 -0
- package/hooks/post-tool-lint +36 -0
- package/hooks/protected-path-write-guard +17 -0
- package/hooks/session-start +41 -0
- package/llms-full.txt +2355 -0
- package/llms.txt +43 -0
- package/package.json +79 -0
- package/roles/README.md +20 -0
- package/roles/clarifier.md +42 -0
- package/roles/content-author.md +63 -0
- package/roles/designer.md +55 -0
- package/roles/executor.md +55 -0
- package/roles/learner.md +51 -0
- package/roles/planner.md +53 -0
- package/roles/researcher.md +43 -0
- package/roles/reviewer.md +54 -0
- package/roles/specifier.md +47 -0
- package/roles/verifier.md +71 -0
- package/schemas/README.md +24 -0
- package/schemas/accepted-learning.schema.json +20 -0
- package/schemas/author-artifact.schema.json +156 -0
- package/schemas/clarification.schema.json +19 -0
- package/schemas/design-artifact.schema.json +80 -0
- package/schemas/docs-claim.schema.json +18 -0
- package/schemas/export-manifest.schema.json +20 -0
- package/schemas/hook.schema.json +67 -0
- package/schemas/host-export-package.schema.json +18 -0
- package/schemas/implementation-plan.schema.json +19 -0
- package/schemas/proposed-learning.schema.json +19 -0
- package/schemas/research.schema.json +18 -0
- package/schemas/review.schema.json +29 -0
- package/schemas/run-manifest.schema.json +18 -0
- package/schemas/spec-challenge.schema.json +18 -0
- package/schemas/spec.schema.json +20 -0
- package/schemas/usage.schema.json +102 -0
- package/schemas/verification-proof.schema.json +29 -0
- package/schemas/wazir-manifest.schema.json +173 -0
- package/skills/README.md +40 -0
- package/skills/brainstorming/SKILL.md +77 -0
- package/skills/debugging/SKILL.md +50 -0
- package/skills/design/SKILL.md +61 -0
- package/skills/dispatching-parallel-agents/SKILL.md +128 -0
- package/skills/executing-plans/SKILL.md +70 -0
- package/skills/finishing-a-development-branch/SKILL.md +169 -0
- package/skills/humanize/SKILL.md +123 -0
- package/skills/init-pipeline/SKILL.md +124 -0
- package/skills/prepare-next/SKILL.md +20 -0
- package/skills/receiving-code-review/SKILL.md +123 -0
- package/skills/requesting-code-review/SKILL.md +105 -0
- package/skills/requesting-code-review/code-reviewer.md +108 -0
- package/skills/run-audit/SKILL.md +197 -0
- package/skills/scan-project/SKILL.md +41 -0
- package/skills/self-audit/SKILL.md +153 -0
- package/skills/subagent-driven-development/SKILL.md +154 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/skills/subagent-driven-development/implementer-prompt.md +102 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/tdd/SKILL.md +23 -0
- package/skills/using-git-worktrees/SKILL.md +163 -0
- package/skills/using-skills/SKILL.md +95 -0
- package/skills/verification/SKILL.md +22 -0
- package/skills/wazir/SKILL.md +463 -0
- package/skills/writing-plans/SKILL.md +30 -0
- package/skills/writing-skills/SKILL.md +157 -0
- package/skills/writing-skills/anthropic-best-practices.md +122 -0
- package/skills/writing-skills/persuasion-principles.md +50 -0
- package/templates/README.md +20 -0
- package/templates/artifacts/README.md +10 -0
- package/templates/artifacts/accepted-learning.md +19 -0
- package/templates/artifacts/accepted-learning.template.json +12 -0
- package/templates/artifacts/author.md +74 -0
- package/templates/artifacts/author.template.json +19 -0
- package/templates/artifacts/clarification.md +21 -0
- package/templates/artifacts/clarification.template.json +12 -0
- package/templates/artifacts/execute-notes.md +19 -0
- package/templates/artifacts/implementation-plan.md +21 -0
- package/templates/artifacts/implementation-plan.template.json +11 -0
- package/templates/artifacts/learning-proposal.md +19 -0
- package/templates/artifacts/next-run-handoff.md +21 -0
- package/templates/artifacts/plan-review.md +19 -0
- package/templates/artifacts/proposed-learning.template.json +12 -0
- package/templates/artifacts/research.md +21 -0
- package/templates/artifacts/research.template.json +12 -0
- package/templates/artifacts/review-findings.md +19 -0
- package/templates/artifacts/review.template.json +11 -0
- package/templates/artifacts/run-manifest.template.json +8 -0
- package/templates/artifacts/spec-challenge.md +19 -0
- package/templates/artifacts/spec-challenge.template.json +11 -0
- package/templates/artifacts/spec.md +21 -0
- package/templates/artifacts/spec.template.json +12 -0
- package/templates/artifacts/verification-proof.md +19 -0
- package/templates/artifacts/verification-proof.template.json +11 -0
- package/templates/examples/accepted-learning.example.json +14 -0
- package/templates/examples/author.example.json +152 -0
- package/templates/examples/clarification.example.json +15 -0
- package/templates/examples/docs-claim.example.json +8 -0
- package/templates/examples/export-manifest.example.json +7 -0
- package/templates/examples/host-export-package.example.json +11 -0
- package/templates/examples/implementation-plan.example.json +17 -0
- package/templates/examples/proposed-learning.example.json +13 -0
- package/templates/examples/research.example.json +15 -0
- package/templates/examples/research.example.md +6 -0
- package/templates/examples/review.example.json +17 -0
- package/templates/examples/run-manifest.example.json +9 -0
- package/templates/examples/spec-challenge.example.json +14 -0
- package/templates/examples/spec.example.json +21 -0
- package/templates/examples/verification-proof.example.json +21 -0
- package/templates/examples/wazir-manifest.example.yaml +65 -0
- package/templates/task-definition-schema.md +99 -0
- package/tooling/README.md +20 -0
- package/tooling/src/adapters/context-mode.js +50 -0
- package/tooling/src/capture/command.js +376 -0
- package/tooling/src/capture/store.js +99 -0
- package/tooling/src/capture/usage.js +270 -0
- package/tooling/src/checks/branches.js +50 -0
- package/tooling/src/checks/brand-truth.js +110 -0
- package/tooling/src/checks/changelog.js +231 -0
- package/tooling/src/checks/command-registry.js +36 -0
- package/tooling/src/checks/commits.js +102 -0
- package/tooling/src/checks/docs-drift.js +103 -0
- package/tooling/src/checks/docs-truth.js +201 -0
- package/tooling/src/checks/runtime-surface.js +156 -0
- package/tooling/src/cli.js +116 -0
- package/tooling/src/command-options.js +56 -0
- package/tooling/src/commands/validate.js +320 -0
- package/tooling/src/doctor/command.js +91 -0
- package/tooling/src/export/command.js +77 -0
- package/tooling/src/export/compiler.js +498 -0
- package/tooling/src/guards/loop-cap-guard.js +52 -0
- package/tooling/src/guards/protected-path-write-guard.js +67 -0
- package/tooling/src/index/command.js +152 -0
- package/tooling/src/index/storage.js +1061 -0
- package/tooling/src/index/summarizers.js +261 -0
- package/tooling/src/loaders.js +18 -0
- package/tooling/src/project-root.js +22 -0
- package/tooling/src/recall/command.js +225 -0
- package/tooling/src/schema-validator.js +30 -0
- package/tooling/src/state-root.js +40 -0
- package/tooling/src/status/command.js +71 -0
- package/wazir.manifest.yaml +135 -0
- package/workflows/README.md +19 -0
- package/workflows/author.md +42 -0
- package/workflows/clarify.md +38 -0
- package/workflows/design-review.md +46 -0
- package/workflows/design.md +44 -0
- package/workflows/discover.md +37 -0
- package/workflows/execute.md +48 -0
- package/workflows/learn.md +38 -0
- package/workflows/plan-review.md +42 -0
- package/workflows/plan.md +39 -0
- package/workflows/prepare-next.md +37 -0
- package/workflows/review.md +40 -0
- package/workflows/run-audit.md +41 -0
- package/workflows/spec-challenge.md +41 -0
- package/workflows/specify.md +38 -0
- package/workflows/verify.md +37 -0
|
@@ -0,0 +1,1229 @@
|
|
|
1
|
+
# Mobile Binary Protection
|
|
2
|
+
|
|
3
|
+
> Expertise module for AI agents protecting mobile app binaries from reverse engineering,
|
|
4
|
+
> tampering, and runtime exploitation. Covers Android and iOS platforms, cross-platform
|
|
5
|
+
> frameworks, and defense-in-depth strategies aligned with OWASP MASVS-RESILIENCE.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Threat Landscape
|
|
10
|
+
|
|
11
|
+
### 1.1 The Attack Surface
|
|
12
|
+
|
|
13
|
+
Mobile binaries ship to devices the attacker fully controls. Unlike server-side code,
|
|
14
|
+
every instruction, string literal, and resource is available for offline analysis with
|
|
15
|
+
unlimited time. The attack surface includes:
|
|
16
|
+
|
|
17
|
+
- **Static analysis** -- Decompiling APK (apktool, jadx, JADX-GUI) or IPA (Hopper,
|
|
18
|
+
class-dump, otool) to read source-equivalent code.
|
|
19
|
+
- **Dynamic analysis** -- Attaching debuggers (lldb, gdb, IDA Pro) or instrumentation
|
|
20
|
+
frameworks (Frida, Xposed, Cydia Substrate) at runtime.
|
|
21
|
+
- **Repackaging** -- Decompiling, modifying, re-signing, and redistributing tampered
|
|
22
|
+
binaries through unofficial channels.
|
|
23
|
+
- **Hooking** -- Intercepting function calls at runtime to alter behavior, bypass
|
|
24
|
+
security checks, or steal credentials (Frida, Xposed Framework, Substrate).
|
|
25
|
+
- **Credential extraction** -- Harvesting API keys, tokens, certificates, and secrets
|
|
26
|
+
embedded in the binary or its resources.
|
|
27
|
+
- **Piracy and cloning** -- Removing license checks, DRM, or in-app purchase
|
|
28
|
+
verification to distribute free copies.
|
|
29
|
+
|
|
30
|
+
### 1.2 Real-World Incidents
|
|
31
|
+
|
|
32
|
+
**GoldFactory Campaign (2024):** Targeted Southeast Asian users with modified banking
|
|
33
|
+
apps. Attackers decompiled legitimate banking applications, embedded trojans and
|
|
34
|
+
backdoors, and redistributed poisoned versions through phishing campaigns and counterfeit
|
|
35
|
+
Play Store websites. Over 11,000 infections were confirmed.
|
|
36
|
+
Source: Promon App Threat Report 2024.
|
|
37
|
+
|
|
38
|
+
**Snowblind Banking Trojan (2024):** Discovered in Southeast Asia, Snowblind exploited
|
|
39
|
+
the Linux kernel's seccomp (secure computing) feature to hook into an app's
|
|
40
|
+
anti-repackaging checks and redirect them away from tampered code. This allowed attackers
|
|
41
|
+
to repackage banking apps while neutralizing existing integrity verification.
|
|
42
|
+
Source: Promon mobile malware report 2025.
|
|
43
|
+
|
|
44
|
+
**FjordPhantom (2024):** Used virtualization to install a repackaged banking app
|
|
45
|
+
alongside the legitimate version on the same device. A virtualized layer between them
|
|
46
|
+
redirected anti-tampering checks so neither app detected the other, enabling credential
|
|
47
|
+
theft and transaction manipulation.
|
|
48
|
+
Source: Promon mobile malware report 2025.
|
|
49
|
+
|
|
50
|
+
**NGate NFC Relay Attack (Nov 2023 -- Mar 2024):** Targeted customers of three major
|
|
51
|
+
Czech banks. Attackers distributed phishing SMS messages linking to fake banking apps
|
|
52
|
+
that contained the open-source NFCGate tool. The malicious app relayed NFC payment card
|
|
53
|
+
data from victims' Android devices to attacker-controlled devices, enabling contactless
|
|
54
|
+
payment fraud.
|
|
55
|
+
Source: The Hacker News, August 2024.
|
|
56
|
+
|
|
57
|
+
**Chameleon Android Banking Trojan (2024):** New campaigns identified by ThreatFabric
|
|
58
|
+
targeted Canadian hospitality workers using a disguised CRM app. The trojan harvested
|
|
59
|
+
banking credentials through overlay attacks after bypassing Android 13 restricted
|
|
60
|
+
settings.
|
|
61
|
+
Source: ThreatFabric research, July 2024.
|
|
62
|
+
|
|
63
|
+
**Frida Hooking Detection Gap:** Promon's 2024 report tested 144 popular Android apps
|
|
64
|
+
and found that only 3 (roughly 2%) responded appropriately to Frida's presence. The
|
|
65
|
+
remaining 98% of top-tier apps had zero detection of unmodified Frida instrumentation.
|
|
66
|
+
Source: Promon App Threat Report 2024.
|
|
67
|
+
|
|
68
|
+
### 1.3 Attacker Toolchain
|
|
69
|
+
|
|
70
|
+
| Tool | Platform | Purpose |
|
|
71
|
+
|------|----------|---------|
|
|
72
|
+
| apktool | Android | APK decompilation/recompilation |
|
|
73
|
+
| jadx / JADX-GUI | Android | DEX to Java decompilation |
|
|
74
|
+
| Frida | Both | Dynamic instrumentation and hooking |
|
|
75
|
+
| Xposed Framework | Android | Runtime method hooking |
|
|
76
|
+
| Cydia Substrate | iOS | Runtime method swizzling |
|
|
77
|
+
| Hopper Disassembler | iOS | ARM binary disassembly |
|
|
78
|
+
| class-dump | iOS | ObjC class/method extraction |
|
|
79
|
+
| IDA Pro | Both | Professional disassembly/debugging |
|
|
80
|
+
| Ghidra | Both | NSA open-source reverse engineering |
|
|
81
|
+
| objection | Both | Frida-powered runtime exploration |
|
|
82
|
+
| MobSF | Both | Automated static/dynamic analysis |
|
|
83
|
+
| Liberty Lite / FlyJB | iOS | Jailbreak detection bypass |
|
|
84
|
+
| Magisk Hide / Zygisk | Android | Root detection bypass |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 2. Core Security Principles
|
|
89
|
+
|
|
90
|
+
### 2.1 Defense in Depth
|
|
91
|
+
|
|
92
|
+
No single protection mechanism survives a determined attacker. Effective binary
|
|
93
|
+
protection layers multiple independent defenses:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
Layer 1: Code Obfuscation -- Raises static analysis cost
|
|
97
|
+
Layer 2: String/Resource Encryption -- Hides secrets from strings output
|
|
98
|
+
Layer 3: Integrity Verification -- Detects binary modification
|
|
99
|
+
Layer 4: Anti-Debug / Anti-Hook -- Blocks dynamic analysis
|
|
100
|
+
Layer 5: Environment Checks -- Detects root/jailbreak/emulator
|
|
101
|
+
Layer 6: Server-Side Validation -- Never trust client-only checks
|
|
102
|
+
Layer 7: RASP -- Runtime behavioral monitoring
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Each layer increases the attacker's required skill level, time investment, and tooling
|
|
106
|
+
cost. The goal is not perfect protection (impossible on client devices) but raising the
|
|
107
|
+
cost of attack above the value of the target.
|
|
108
|
+
|
|
109
|
+
### 2.2 Code Signing and Binary Integrity
|
|
110
|
+
|
|
111
|
+
**iOS:** Apple enforces mandatory code signing. Every binary must be signed with a valid
|
|
112
|
+
Apple Developer certificate. The system verifies the signature at install time and
|
|
113
|
+
periodically at runtime. Modifying any signed binary invalidates the signature.
|
|
114
|
+
|
|
115
|
+
**Android:** APK Signature Scheme v2/v3/v4 covers the entire APK file. Google Play App
|
|
116
|
+
Signing manages keys server-side. Signature verification occurs at install time but NOT
|
|
117
|
+
at runtime by default -- apps must implement their own runtime signature checks.
|
|
118
|
+
|
|
119
|
+
### 2.3 The Client Trust Problem
|
|
120
|
+
|
|
121
|
+
All client-side protections share a fundamental limitation: they run on a device the
|
|
122
|
+
attacker controls. Therefore:
|
|
123
|
+
|
|
124
|
+
- Never rely solely on client-side checks for security-critical decisions.
|
|
125
|
+
- Always validate critical operations server-side.
|
|
126
|
+
- Treat client-side protections as cost-raisers, not guarantees.
|
|
127
|
+
- Use attestation APIs (Play Integrity, App Attest) to shift trust anchors to the
|
|
128
|
+
platform vendor.
|
|
129
|
+
|
|
130
|
+
### 2.4 Anti-Tampering Philosophy
|
|
131
|
+
|
|
132
|
+
Effective anti-tampering follows three principles:
|
|
133
|
+
|
|
134
|
+
1. **Detect** -- Identify that tampering, hooking, or analysis is occurring.
|
|
135
|
+
2. **React** -- Respond appropriately (crash, degrade, report, wipe sensitive data).
|
|
136
|
+
3. **Scatter** -- Distribute detection checks throughout the codebase so removing one
|
|
137
|
+
check does not disable all protection.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 3. Implementation Patterns
|
|
142
|
+
|
|
143
|
+
### 3.1 iOS Protection Techniques
|
|
144
|
+
|
|
145
|
+
#### Code Signing and Entitlements
|
|
146
|
+
|
|
147
|
+
iOS code signing is enforced by the kernel. Key implementation points:
|
|
148
|
+
|
|
149
|
+
- Use **Hardened Runtime** with only necessary entitlements.
|
|
150
|
+
- Enable **App Attest** (DeviceCheck framework) to cryptographically prove binary
|
|
151
|
+
integrity to your server.
|
|
152
|
+
- Strip **debug symbols** from release builds (STRIP_INSTALLED_PRODUCT = YES).
|
|
153
|
+
- Disable **Bitcode** submission if not needed (deprecated as of Xcode 14).
|
|
154
|
+
|
|
155
|
+
#### Anti-Debug Protection
|
|
156
|
+
|
|
157
|
+
```swift
|
|
158
|
+
// Deny debugger attachment via ptrace
|
|
159
|
+
import Foundation
|
|
160
|
+
|
|
161
|
+
func denyDebugger() {
|
|
162
|
+
let PT_DENY_ATTACH: CInt = 31
|
|
163
|
+
let handle = dlopen("/usr/lib/libc.dylib", RTLD_NOW)
|
|
164
|
+
typealias PtraceType = @convention(c) (CInt, pid_t, CInt, CInt) -> CInt
|
|
165
|
+
let ptracePtr = dlsym(handle, "ptrace")
|
|
166
|
+
let ptrace = unsafeBitCast(ptracePtr, to: PtraceType.self)
|
|
167
|
+
let _ = ptrace(PT_DENY_ATTACH, 0, 0, 0)
|
|
168
|
+
dlclose(handle)
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Jailbreak Detection (Swift)
|
|
173
|
+
|
|
174
|
+
```swift
|
|
175
|
+
import Foundation
|
|
176
|
+
import UIKit
|
|
177
|
+
|
|
178
|
+
struct JailbreakDetector {
|
|
179
|
+
|
|
180
|
+
static func isJailbroken() -> Bool {
|
|
181
|
+
return checkSuspiciousFiles()
|
|
182
|
+
|| checkSuspiciousURLSchemes()
|
|
183
|
+
|| checkWriteAccess()
|
|
184
|
+
|| checkFork()
|
|
185
|
+
|| checkDylibs()
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Check for known jailbreak artifacts
|
|
189
|
+
private static func checkSuspiciousFiles() -> Bool {
|
|
190
|
+
let paths = [
|
|
191
|
+
"/Applications/Cydia.app",
|
|
192
|
+
"/Library/MobileSubstrate/MobileSubstrate.dylib",
|
|
193
|
+
"/bin/bash",
|
|
194
|
+
"/usr/sbin/sshd",
|
|
195
|
+
"/etc/apt",
|
|
196
|
+
"/usr/bin/ssh",
|
|
197
|
+
"/private/var/lib/apt/",
|
|
198
|
+
"/private/var/lib/cydia",
|
|
199
|
+
"/private/var/stash",
|
|
200
|
+
"/usr/libexec/sftp-server",
|
|
201
|
+
"/var/cache/apt",
|
|
202
|
+
"/var/lib/cydia",
|
|
203
|
+
"/usr/sbin/frida-server",
|
|
204
|
+
"/usr/bin/cycript",
|
|
205
|
+
"/usr/local/bin/cycript",
|
|
206
|
+
"/usr/lib/libcycript.dylib"
|
|
207
|
+
]
|
|
208
|
+
return paths.contains { FileManager.default.fileExists(atPath: $0) }
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Check if Cydia URL scheme is registered
|
|
212
|
+
private static func checkSuspiciousURLSchemes() -> Bool {
|
|
213
|
+
let schemes = ["cydia://", "sileo://", "zbra://", "undecimus://"]
|
|
214
|
+
return schemes.contains { scheme in
|
|
215
|
+
guard let url = URL(string: scheme) else { return false }
|
|
216
|
+
return UIApplication.shared.canOpenURL(url)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Attempt to write outside the sandbox
|
|
221
|
+
private static func checkWriteAccess() -> Bool {
|
|
222
|
+
let testPath = "/private/jailbreak_test_\(UUID().uuidString)"
|
|
223
|
+
do {
|
|
224
|
+
try "test".write(toFile: testPath, atomically: true, encoding: .utf8)
|
|
225
|
+
try FileManager.default.removeItem(atPath: testPath)
|
|
226
|
+
return true // Write succeeded = jailbroken
|
|
227
|
+
} catch {
|
|
228
|
+
return false
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Sandbox denies fork() on non-jailbroken devices
|
|
233
|
+
private static func checkFork() -> Bool {
|
|
234
|
+
let pid = fork()
|
|
235
|
+
if pid >= 0 {
|
|
236
|
+
if pid > 0 { kill(pid, SIGTERM) }
|
|
237
|
+
return true
|
|
238
|
+
}
|
|
239
|
+
return false
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Check for suspicious loaded dylibs (Frida, Substrate, etc.)
|
|
243
|
+
private static func checkDylibs() -> Bool {
|
|
244
|
+
let suspiciousLibs = [
|
|
245
|
+
"FridaGadget", "frida-agent", "libcycript",
|
|
246
|
+
"MobileSubstrate", "SubstrateLoader",
|
|
247
|
+
"SSLKillSwitch", "SSLKillSwitch2"
|
|
248
|
+
]
|
|
249
|
+
let count = _dyld_image_count()
|
|
250
|
+
for i in 0..<count {
|
|
251
|
+
guard let name = _dyld_get_image_name(i) else { continue }
|
|
252
|
+
let imageName = String(cString: name)
|
|
253
|
+
if suspiciousLibs.contains(where: { imageName.contains($0) }) {
|
|
254
|
+
return true
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return false
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### App Attest Integration
|
|
263
|
+
|
|
264
|
+
```swift
|
|
265
|
+
import DeviceCheck
|
|
266
|
+
|
|
267
|
+
func attestKey(challenge: Data) async throws -> Data {
|
|
268
|
+
let service = DCAppAttestService.shared
|
|
269
|
+
guard service.isSupported else {
|
|
270
|
+
throw AttestError.notSupported
|
|
271
|
+
}
|
|
272
|
+
let keyId = try await service.generateKey()
|
|
273
|
+
let attestation = try await service.attestKey(keyId, clientDataHash: challenge)
|
|
274
|
+
// Send attestation + keyId to your server for verification
|
|
275
|
+
return attestation
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### 3.2 Android Protection Techniques
|
|
280
|
+
|
|
281
|
+
#### ProGuard/R8 Configuration
|
|
282
|
+
|
|
283
|
+
R8 is the default code shrinker and obfuscator since Android Gradle Plugin 3.4.
|
|
284
|
+
ProGuard is deprecated. Key configuration:
|
|
285
|
+
|
|
286
|
+
```groovy
|
|
287
|
+
// build.gradle.kts (app module)
|
|
288
|
+
android {
|
|
289
|
+
buildTypes {
|
|
290
|
+
release {
|
|
291
|
+
isMinifyEnabled = true
|
|
292
|
+
isShrinkResources = true
|
|
293
|
+
proguardFiles(
|
|
294
|
+
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
295
|
+
"proguard-rules.pro"
|
|
296
|
+
)
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Critical ProGuard/R8 Rules:**
|
|
303
|
+
|
|
304
|
+
```proguard
|
|
305
|
+
# proguard-rules.pro
|
|
306
|
+
|
|
307
|
+
# Move all obfuscated classes into a single flat package
|
|
308
|
+
-repackageclasses
|
|
309
|
+
|
|
310
|
+
# Keep data models used with Gson/Moshi/Retrofit
|
|
311
|
+
-keep class com.example.app.data.model.** { *; }
|
|
312
|
+
|
|
313
|
+
# Keep Retrofit interfaces
|
|
314
|
+
-keep,allowobfuscation interface com.example.app.api.** { *; }
|
|
315
|
+
|
|
316
|
+
# Remove logging in release
|
|
317
|
+
-assumenosideeffects class android.util.Log {
|
|
318
|
+
public static int v(...);
|
|
319
|
+
public static int d(...);
|
|
320
|
+
public static int i(...);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
# Never use these in release builds:
|
|
324
|
+
# -dontoptimize (disables all R8 optimizations)
|
|
325
|
+
# -dontobfuscate (disables renaming entirely)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Important:** Starting with Android Gradle Plugin 9.0, the legacy `proguard-android.txt`
|
|
329
|
+
is no longer supported. Always use `proguard-android-optimize.txt`.
|
|
330
|
+
|
|
331
|
+
#### Root Detection (Kotlin)
|
|
332
|
+
|
|
333
|
+
```kotlin
|
|
334
|
+
object RootDetector {
|
|
335
|
+
|
|
336
|
+
fun isRooted(): Boolean {
|
|
337
|
+
return checkBuildTags()
|
|
338
|
+
|| checkSuBinary()
|
|
339
|
+
|| checkRootApps()
|
|
340
|
+
|| checkDangerousProps()
|
|
341
|
+
|| checkRWSystem()
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Test-keys in build tags indicate non-release firmware
|
|
345
|
+
private fun checkBuildTags(): Boolean {
|
|
346
|
+
return android.os.Build.TAGS?.contains("test-keys") == true
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Check for su binary in common locations
|
|
350
|
+
private fun checkSuBinary(): Boolean {
|
|
351
|
+
val paths = arrayOf(
|
|
352
|
+
"/system/bin/su", "/system/xbin/su",
|
|
353
|
+
"/sbin/su", "/data/local/xbin/su",
|
|
354
|
+
"/data/local/bin/su", "/system/sd/xbin/su",
|
|
355
|
+
"/system/bin/failsafe/su", "/data/local/su",
|
|
356
|
+
"/su/bin/su", "/system/app/Superuser.apk",
|
|
357
|
+
"/system/app/SuperSU.apk",
|
|
358
|
+
"/data/adb/modules" // Magisk modules directory
|
|
359
|
+
)
|
|
360
|
+
return paths.any { java.io.File(it).exists() }
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Check for known root management apps
|
|
364
|
+
private fun checkRootApps(): Boolean {
|
|
365
|
+
val packages = arrayOf(
|
|
366
|
+
"com.topjohnwu.magisk", // Magisk Manager
|
|
367
|
+
"eu.chainfire.supersu", // SuperSU
|
|
368
|
+
"com.koushikdutta.superuser", // Superuser
|
|
369
|
+
"com.thirdparty.superuser",
|
|
370
|
+
"com.noshufou.android.su",
|
|
371
|
+
"com.yellowes.su",
|
|
372
|
+
"com.kingroot.kinguser",
|
|
373
|
+
"com.kingo.root"
|
|
374
|
+
)
|
|
375
|
+
val pm = Runtime.getRuntime()
|
|
376
|
+
return packages.any { pkg ->
|
|
377
|
+
try {
|
|
378
|
+
pm.exec(arrayOf("pm", "list", "packages", pkg))
|
|
379
|
+
.inputStream.bufferedReader().readLine() != null
|
|
380
|
+
} catch (e: Exception) { false }
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Check dangerous system properties
|
|
385
|
+
private fun checkDangerousProps(): Boolean {
|
|
386
|
+
return try {
|
|
387
|
+
val process = Runtime.getRuntime()
|
|
388
|
+
.exec(arrayOf("getprop", "ro.debuggable"))
|
|
389
|
+
val value = process.inputStream.bufferedReader().readLine()
|
|
390
|
+
value?.trim() == "1"
|
|
391
|
+
} catch (e: Exception) { false }
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Check if /system is mounted read-write
|
|
395
|
+
private fun checkRWSystem(): Boolean {
|
|
396
|
+
return try {
|
|
397
|
+
val mounts = java.io.File("/proc/mounts").readText()
|
|
398
|
+
mounts.lines().any { line ->
|
|
399
|
+
line.contains("/system") && line.contains("rw,")
|
|
400
|
+
}
|
|
401
|
+
} catch (e: Exception) { false }
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
#### Play Integrity API
|
|
407
|
+
|
|
408
|
+
Google's Play Integrity API (replacement for SafetyNet, fully transitioned May 2025)
|
|
409
|
+
provides device and app integrity attestation:
|
|
410
|
+
|
|
411
|
+
```kotlin
|
|
412
|
+
import com.google.android.play.core.integrity.IntegrityManagerFactory
|
|
413
|
+
import com.google.android.play.core.integrity.IntegrityTokenRequest
|
|
414
|
+
|
|
415
|
+
suspend fun requestIntegrityToken(nonce: String): String {
|
|
416
|
+
val integrityManager = IntegrityManagerFactory.create(applicationContext)
|
|
417
|
+
val request = IntegrityTokenRequest.builder()
|
|
418
|
+
.setNonce(nonce) // Server-generated, one-time use
|
|
419
|
+
.setCloudProjectNumber(PROJECT_NUMBER)
|
|
420
|
+
.build()
|
|
421
|
+
val response = integrityManager.requestIntegrityToken(request).await()
|
|
422
|
+
return response.token() // Send to YOUR server for verification
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Server-side: Decode and verify the token. Key verdicts:
|
|
426
|
+
// - MEETS_DEVICE_INTEGRITY: Genuine Android device
|
|
427
|
+
// - MEETS_BASIC_INTEGRITY: May be rooted but passes basic checks
|
|
428
|
+
// - MEETS_STRONG_INTEGRITY: Hardware-backed, recent security patch
|
|
429
|
+
// - App licensing verdict: Installed from Play Store
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Key change (May 2025):** Hardware-backed security signals are now required for
|
|
433
|
+
MEETS_STRONG_INTEGRITY. Devices running Android 13+ must have a security update from
|
|
434
|
+
the last 12 months to receive this verdict.
|
|
435
|
+
|
|
436
|
+
#### Emulator Detection
|
|
437
|
+
|
|
438
|
+
```kotlin
|
|
439
|
+
object EmulatorDetector {
|
|
440
|
+
fun isEmulator(): Boolean {
|
|
441
|
+
return (Build.FINGERPRINT.startsWith("generic")
|
|
442
|
+
|| Build.FINGERPRINT.startsWith("unknown")
|
|
443
|
+
|| Build.MODEL.contains("google_sdk")
|
|
444
|
+
|| Build.MODEL.contains("Emulator")
|
|
445
|
+
|| Build.MODEL.contains("Android SDK built for x86")
|
|
446
|
+
|| Build.MANUFACTURER.contains("Genymotion")
|
|
447
|
+
|| Build.BRAND.startsWith("generic")
|
|
448
|
+
&& Build.DEVICE.startsWith("generic")
|
|
449
|
+
|| "google_sdk" == Build.PRODUCT
|
|
450
|
+
|| Build.HARDWARE.contains("goldfish")
|
|
451
|
+
|| Build.HARDWARE.contains("ranchu"))
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
#### Debugger Detection (Android)
|
|
457
|
+
|
|
458
|
+
```kotlin
|
|
459
|
+
object DebugDetector {
|
|
460
|
+
fun isDebugged(): Boolean {
|
|
461
|
+
return android.os.Debug.isDebuggerConnected()
|
|
462
|
+
|| android.os.Debug.waitingForDebugger()
|
|
463
|
+
|| isTracerPidSet()
|
|
464
|
+
|| isDebuggableBuild()
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// /proc/self/status TracerPid != 0 means a debugger is attached
|
|
468
|
+
private fun isTracerPidSet(): Boolean {
|
|
469
|
+
return try {
|
|
470
|
+
val status = java.io.File("/proc/self/status").readText()
|
|
471
|
+
val tracerLine = status.lines()
|
|
472
|
+
.find { it.startsWith("TracerPid:") }
|
|
473
|
+
val pid = tracerLine?.split(":")?.get(1)?.trim()?.toIntOrNull() ?: 0
|
|
474
|
+
pid != 0
|
|
475
|
+
} catch (e: Exception) { false }
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
private fun isDebuggableBuild(): Boolean {
|
|
479
|
+
return (applicationContext.applicationInfo.flags
|
|
480
|
+
and android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE) != 0
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
#### Frida Detection (Android)
|
|
486
|
+
|
|
487
|
+
```kotlin
|
|
488
|
+
object FridaDetector {
|
|
489
|
+
|
|
490
|
+
fun isFridaPresent(): Boolean {
|
|
491
|
+
return checkFridaPort()
|
|
492
|
+
|| checkFridaProcesses()
|
|
493
|
+
|| checkFridaLibraries()
|
|
494
|
+
|| checkFridaNamedPipes()
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// Frida default port is 27042
|
|
498
|
+
private fun checkFridaPort(): Boolean {
|
|
499
|
+
return try {
|
|
500
|
+
val socket = java.net.Socket()
|
|
501
|
+
socket.connect(java.net.InetSocketAddress("127.0.0.1", 27042), 100)
|
|
502
|
+
socket.close()
|
|
503
|
+
true
|
|
504
|
+
} catch (e: Exception) { false }
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Check /proc for frida-server process
|
|
508
|
+
private fun checkFridaProcesses(): Boolean {
|
|
509
|
+
return try {
|
|
510
|
+
val process = Runtime.getRuntime().exec(arrayOf("ps", "-A"))
|
|
511
|
+
val output = process.inputStream.bufferedReader().readText()
|
|
512
|
+
output.contains("frida") || output.contains("gum-js-loop")
|
|
513
|
+
} catch (e: Exception) { false }
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Check loaded libraries for Frida artifacts
|
|
517
|
+
private fun checkFridaLibraries(): Boolean {
|
|
518
|
+
return try {
|
|
519
|
+
val maps = java.io.File("/proc/self/maps").readText()
|
|
520
|
+
maps.contains("frida") || maps.contains("gadget")
|
|
521
|
+
} catch (e: Exception) { false }
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Frida uses named pipes like linjector
|
|
525
|
+
private fun checkFridaNamedPipes(): Boolean {
|
|
526
|
+
val pipeDir = java.io.File("/proc/self/fd")
|
|
527
|
+
return pipeDir.listFiles()?.any { fd ->
|
|
528
|
+
try {
|
|
529
|
+
val link = java.nio.file.Files.readSymbolicLink(fd.toPath())
|
|
530
|
+
link.toString().contains("linjector")
|
|
531
|
+
} catch (e: Exception) { false }
|
|
532
|
+
} ?: false
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### 3.3 Native Code for Sensitive Logic (NDK)
|
|
538
|
+
|
|
539
|
+
Move critical security checks to native C/C++ code compiled with the NDK. Native code
|
|
540
|
+
is harder to decompile than Java/Kotlin bytecode:
|
|
541
|
+
|
|
542
|
+
```c
|
|
543
|
+
// native-lib.c
|
|
544
|
+
#include <jni.h>
|
|
545
|
+
#include <string.h>
|
|
546
|
+
#include <sys/ptrace.h>
|
|
547
|
+
#include <unistd.h>
|
|
548
|
+
|
|
549
|
+
// Anti-debug: call ptrace on self to prevent debugger attachment
|
|
550
|
+
JNIEXPORT jboolean JNICALL
|
|
551
|
+
Java_com_example_app_Security_isDebuggerAttached(JNIEnv *env, jobject obj) {
|
|
552
|
+
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
|
|
553
|
+
return JNI_TRUE; // Already being traced
|
|
554
|
+
}
|
|
555
|
+
return JNI_FALSE;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Verify APK signature at native level
|
|
559
|
+
JNIEXPORT jboolean JNICALL
|
|
560
|
+
Java_com_example_app_Security_verifySignature(
|
|
561
|
+
JNIEnv *env, jobject obj, jbyteArray signature) {
|
|
562
|
+
|
|
563
|
+
// Expected SHA-256 of release signing certificate
|
|
564
|
+
const unsigned char expected[] = {
|
|
565
|
+
0xAB, 0xCD, 0xEF, /* ... your cert hash ... */
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
jbyte *sig = (*env)->GetByteArrayElements(env, signature, NULL);
|
|
569
|
+
jsize len = (*env)->GetArrayLength(env, signature);
|
|
570
|
+
|
|
571
|
+
jboolean valid = (len == sizeof(expected)
|
|
572
|
+
&& memcmp(sig, expected, len) == 0) ? JNI_TRUE : JNI_FALSE;
|
|
573
|
+
|
|
574
|
+
(*env)->ReleaseByteArrayElements(env, signature, sig, 0);
|
|
575
|
+
return valid;
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## 4. Vulnerability Catalog
|
|
582
|
+
|
|
583
|
+
### VULN-01: Hardcoded Secrets in Binary
|
|
584
|
+
|
|
585
|
+
**Risk:** Critical. API keys, tokens, and credentials compiled into the binary are
|
|
586
|
+
trivially extractable with `strings`, jadx, or Hopper.
|
|
587
|
+
|
|
588
|
+
```java
|
|
589
|
+
// VULNERABLE: Secret visible in decompiled code
|
|
590
|
+
public class ApiClient {
|
|
591
|
+
private static final String API_KEY = "sk-live-a1b2c3d4e5f6";
|
|
592
|
+
private static final String DB_PASSWORD = "SuperSecret123!";
|
|
593
|
+
}
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
```kotlin
|
|
597
|
+
// SECURE: Fetch secrets from server after authentication
|
|
598
|
+
class ApiClient(private val tokenProvider: TokenProvider) {
|
|
599
|
+
suspend fun getApiKey(): String {
|
|
600
|
+
return tokenProvider.fetchSecureToken(scope = "api-access")
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### VULN-02: No Code Obfuscation
|
|
606
|
+
|
|
607
|
+
**Risk:** High. Unobfuscated Java/Kotlin code decompiles to near-original source,
|
|
608
|
+
exposing business logic, algorithms, and security mechanisms.
|
|
609
|
+
|
|
610
|
+
```groovy
|
|
611
|
+
// VULNERABLE: Obfuscation disabled
|
|
612
|
+
android {
|
|
613
|
+
buildTypes {
|
|
614
|
+
release {
|
|
615
|
+
isMinifyEnabled = false // No shrinking or obfuscation
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
```groovy
|
|
622
|
+
// SECURE: Full R8 optimization enabled
|
|
623
|
+
android {
|
|
624
|
+
buildTypes {
|
|
625
|
+
release {
|
|
626
|
+
isMinifyEnabled = true
|
|
627
|
+
isShrinkResources = true
|
|
628
|
+
proguardFiles(
|
|
629
|
+
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
630
|
+
"proguard-rules.pro"
|
|
631
|
+
)
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### VULN-03: Debuggable Release Build
|
|
638
|
+
|
|
639
|
+
**Risk:** Critical. A debuggable flag allows any user to attach a debugger, inspect
|
|
640
|
+
memory, and step through code.
|
|
641
|
+
|
|
642
|
+
```xml
|
|
643
|
+
<!-- VULNERABLE: AndroidManifest.xml -->
|
|
644
|
+
<application android:debuggable="true" ... >
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
```xml
|
|
648
|
+
<!-- SECURE: Never set debuggable in manifest; let build system handle it -->
|
|
649
|
+
<!-- build.gradle sets debuggable=false for release automatically -->
|
|
650
|
+
<application ... >
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
### VULN-04: Missing Runtime Integrity Checks
|
|
654
|
+
|
|
655
|
+
**Risk:** High. Without runtime verification, a repackaged app runs identically to the
|
|
656
|
+
original, enabling trojanized distribution.
|
|
657
|
+
|
|
658
|
+
### VULN-05: Exposed Debug Symbols
|
|
659
|
+
|
|
660
|
+
**Risk:** Medium. Debug symbols (DWARF, .dSYM) shipped in production binaries give
|
|
661
|
+
attackers a roadmap of every function name and variable.
|
|
662
|
+
|
|
663
|
+
- **iOS:** Ensure STRIP_INSTALLED_PRODUCT = YES and DEPLOYMENT_POSTPROCESSING = YES.
|
|
664
|
+
- **Android:** Ensure native libraries are stripped (default with release NDK builds).
|
|
665
|
+
|
|
666
|
+
### VULN-06: Unprotected Native Libraries
|
|
667
|
+
|
|
668
|
+
**Risk:** High. Shared libraries (.so files) shipped without symbol stripping or
|
|
669
|
+
integrity checks can be replaced or patched.
|
|
670
|
+
|
|
671
|
+
### VULN-07: Insecure Logging in Production
|
|
672
|
+
|
|
673
|
+
**Risk:** Medium. Verbose logging (Log.d, NSLog) in production reveals internal state,
|
|
674
|
+
API endpoints, tokens, and error details to any user with adb logcat or Console.app.
|
|
675
|
+
|
|
676
|
+
```kotlin
|
|
677
|
+
// VULNERABLE
|
|
678
|
+
Log.d("AUTH", "Token: $accessToken, User: $userId")
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
```kotlin
|
|
682
|
+
// SECURE: Use BuildConfig to gate logging; R8 strips Log calls via
|
|
683
|
+
// -assumenosideeffects rule
|
|
684
|
+
if (BuildConfig.DEBUG) {
|
|
685
|
+
Log.d("AUTH", "Authentication flow started")
|
|
686
|
+
}
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### VULN-08: No Certificate Pinning
|
|
690
|
+
|
|
691
|
+
**Risk:** High. Without certificate pinning, attackers with a proxy (mitmproxy, Charles)
|
|
692
|
+
can intercept all HTTPS traffic by installing a custom CA.
|
|
693
|
+
|
|
694
|
+
### VULN-09: Client-Only License Verification
|
|
695
|
+
|
|
696
|
+
**Risk:** Critical. License checks performed entirely on-device can be bypassed by
|
|
697
|
+
patching a single conditional branch.
|
|
698
|
+
|
|
699
|
+
### VULN-10: Unencrypted Local Storage of Secrets
|
|
700
|
+
|
|
701
|
+
**Risk:** Critical. Storing tokens, keys, or session data in SharedPreferences
|
|
702
|
+
(Android) or UserDefaults (iOS) in plaintext allows extraction on rooted/jailbroken
|
|
703
|
+
devices.
|
|
704
|
+
|
|
705
|
+
### VULN-11: Disabled ASLR or Stack Protections
|
|
706
|
+
|
|
707
|
+
**Risk:** Medium. Disabling Address Space Layout Randomization or stack canaries in
|
|
708
|
+
native code weakens exploit mitigations.
|
|
709
|
+
|
|
710
|
+
### VULN-12: Exposed WebView JavaScript Bridge
|
|
711
|
+
|
|
712
|
+
**Risk:** High. A WebView with addJavascriptInterface or unrestricted URL loading can
|
|
713
|
+
be exploited to call arbitrary native code through injected JavaScript.
|
|
714
|
+
|
|
715
|
+
### VULN-13: Backup Extraction of Sensitive Data
|
|
716
|
+
|
|
717
|
+
**Risk:** Medium. Android's allowBackup="true" (default) permits adb backup to extract
|
|
718
|
+
app data, including databases and preference files.
|
|
719
|
+
|
|
720
|
+
```xml
|
|
721
|
+
<!-- SECURE -->
|
|
722
|
+
<application android:allowBackup="false"
|
|
723
|
+
android:fullBackupContent="false" ... >
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### VULN-14: Weak or Missing Anti-Hook Protection
|
|
727
|
+
|
|
728
|
+
**Risk:** High. Without Frida/Xposed detection, attackers can hook any function at
|
|
729
|
+
runtime to bypass authentication, modify transactions, or extract encryption keys.
|
|
730
|
+
|
|
731
|
+
### VULN-15: Code Push Without Integrity Verification
|
|
732
|
+
|
|
733
|
+
**Risk:** High. Over-the-air code updates (React Native CodePush, Flutter Shorebird)
|
|
734
|
+
that lack signature verification allow attackers to push malicious updates via MITM.
|
|
735
|
+
|
|
736
|
+
---
|
|
737
|
+
|
|
738
|
+
## 5. Security Checklist
|
|
739
|
+
|
|
740
|
+
### Build-Time Protections
|
|
741
|
+
|
|
742
|
+
- [ ] R8/ProGuard enabled with `isMinifyEnabled = true` and `isShrinkResources = true`
|
|
743
|
+
- [ ] Custom ProGuard rules strip logging (`-assumenosideeffects`)
|
|
744
|
+
- [ ] `-repackageclasses` flattens package structure
|
|
745
|
+
- [ ] Debug symbols stripped from release builds
|
|
746
|
+
- [ ] `android:debuggable` is `false` in release (default behavior)
|
|
747
|
+
- [ ] `android:allowBackup="false"` set explicitly
|
|
748
|
+
- [ ] iOS: STRIP_INSTALLED_PRODUCT and DEPLOYMENT_POSTPROCESSING enabled
|
|
749
|
+
- [ ] No hardcoded secrets, API keys, or credentials in source code
|
|
750
|
+
- [ ] Sensitive strings encrypted or fetched from server at runtime
|
|
751
|
+
|
|
752
|
+
### Runtime Protections
|
|
753
|
+
|
|
754
|
+
- [ ] Root/jailbreak detection implemented with multiple checks
|
|
755
|
+
- [ ] Emulator detection active for sensitive features
|
|
756
|
+
- [ ] Debugger detection (isDebuggerConnected, TracerPid, ptrace denial)
|
|
757
|
+
- [ ] Frida/hooking framework detection (port scan, library scan, named pipes)
|
|
758
|
+
- [ ] Runtime signature/integrity verification of the APK/IPA
|
|
759
|
+
- [ ] Certificate pinning for all API connections
|
|
760
|
+
- [ ] Play Integrity API (Android) / App Attest (iOS) integrated
|
|
761
|
+
|
|
762
|
+
### Architecture Protections
|
|
763
|
+
|
|
764
|
+
- [ ] Sensitive logic moved to native code (NDK/C) where feasible
|
|
765
|
+
- [ ] Critical security decisions validated server-side
|
|
766
|
+
- [ ] RASP SDK integrated for comprehensive runtime monitoring
|
|
767
|
+
- [ ] Security checks scattered throughout codebase (not centralized)
|
|
768
|
+
- [ ] Graceful degradation on detection (not just crash -- report to server)
|
|
769
|
+
|
|
770
|
+
---
|
|
771
|
+
|
|
772
|
+
## 6. Tools and Automation
|
|
773
|
+
|
|
774
|
+
### 6.1 Obfuscation and Shielding
|
|
775
|
+
|
|
776
|
+
| Tool | Platform | Type | Key Features |
|
|
777
|
+
|------|----------|------|--------------|
|
|
778
|
+
| R8 | Android | Free (bundled) | Code shrinking, obfuscation, optimization |
|
|
779
|
+
| DexGuard | Android | Commercial | Polymorphic obfuscation, string encryption, RASP, class encryption |
|
|
780
|
+
| iXGuard | iOS | Commercial | Swift/ObjC obfuscation, control flow, RASP |
|
|
781
|
+
|
|
782
|
+
DexGuard and iXGuard, both from Guardsquare, apply polymorphic obfuscation so no two
|
|
783
|
+
protected builds look the same. They support native and cross-platform apps (Flutter,
|
|
784
|
+
React Native, Unity, Cordova, Ionic) and integrate into CI/CD pipelines as
|
|
785
|
+
post-processing steps.
|
|
786
|
+
|
|
787
|
+
### 6.2 RASP SDKs
|
|
788
|
+
|
|
789
|
+
| SDK | Vendor | Capabilities |
|
|
790
|
+
|-----|--------|-------------|
|
|
791
|
+
| freeRASP | Talsec | Root/jailbreak, hook, emulator, debug detection (open-source core) |
|
|
792
|
+
| Promon Shield | Promon | App shielding, code hardening, anti-repackaging |
|
|
793
|
+
| ThreatCast | Guardsquare | Real-time threat monitoring (pairs with DexGuard/iXGuard) |
|
|
794
|
+
| zDefend | Zimperium | On-device ML threat detection, RASP |
|
|
795
|
+
| Appdome | Appdome | No-code RASP integration, ML-based obfuscation |
|
|
796
|
+
|
|
797
|
+
### 6.3 Platform Attestation APIs
|
|
798
|
+
|
|
799
|
+
| API | Platform | Purpose |
|
|
800
|
+
|-----|----------|---------|
|
|
801
|
+
| Play Integrity API | Android | Device integrity, app licensing, account details |
|
|
802
|
+
| App Attest (DeviceCheck) | iOS | Binary integrity via Secure Enclave keypair |
|
|
803
|
+
| SafetyNet | Android | **Deprecated** -- fully removed May 2025 |
|
|
804
|
+
|
|
805
|
+
### 6.4 Analysis and Testing Tools
|
|
806
|
+
|
|
807
|
+
| Tool | Purpose |
|
|
808
|
+
|------|---------|
|
|
809
|
+
| MobSF | Automated mobile app security assessment (static + dynamic) |
|
|
810
|
+
| apktool | APK decompilation for testing your own protections |
|
|
811
|
+
| jadx | DEX decompilation -- verify obfuscation effectiveness |
|
|
812
|
+
| Frida | Test your own hooking defenses |
|
|
813
|
+
| objection | Automated runtime exploration -- verify RASP responses |
|
|
814
|
+
|
|
815
|
+
---
|
|
816
|
+
|
|
817
|
+
## 7. Platform-Specific Guidance
|
|
818
|
+
|
|
819
|
+
### 7.1 iOS (Xcode Build Settings)
|
|
820
|
+
|
|
821
|
+
Key Xcode build settings for binary hardening:
|
|
822
|
+
|
|
823
|
+
```
|
|
824
|
+
// Build Settings for Release
|
|
825
|
+
STRIP_INSTALLED_PRODUCT = YES
|
|
826
|
+
DEPLOYMENT_POSTPROCESSING = YES
|
|
827
|
+
GCC_GENERATE_DEBUGGING_SYMBOLS = NO
|
|
828
|
+
ENABLE_NS_ASSERTIONS = NO
|
|
829
|
+
DEBUG_INFORMATION_FORMAT = dwarf
|
|
830
|
+
SWIFT_COMPILATION_MODE = wholemodule
|
|
831
|
+
SWIFT_OPTIMIZATION_LEVEL = -Osize
|
|
832
|
+
GCC_OPTIMIZATION_LEVEL = s
|
|
833
|
+
ENABLE_BITCODE = NO // Deprecated since Xcode 14
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
**Entitlements hardening:**
|
|
837
|
+
- Remove `com.apple.security.get-task-allow` from release entitlements (allows
|
|
838
|
+
debugger attachment if present).
|
|
839
|
+
- Use `com.apple.developer.devicecheck.appattest-environment = production` for
|
|
840
|
+
App Attest.
|
|
841
|
+
|
|
842
|
+
**Swift/ObjC name mangling:** Swift naturally mangles symbol names more aggressively
|
|
843
|
+
than Objective-C. However, any method marked `@objc` or visible through the ObjC
|
|
844
|
+
runtime loses this protection. Minimize `@objc` exposure in security-critical code.
|
|
845
|
+
|
|
846
|
+
### 7.2 Android (Gradle and NDK)
|
|
847
|
+
|
|
848
|
+
```groovy
|
|
849
|
+
android {
|
|
850
|
+
buildTypes {
|
|
851
|
+
release {
|
|
852
|
+
isMinifyEnabled = true
|
|
853
|
+
isShrinkResources = true
|
|
854
|
+
proguardFiles(
|
|
855
|
+
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
856
|
+
"proguard-rules.pro"
|
|
857
|
+
)
|
|
858
|
+
ndk {
|
|
859
|
+
debugSymbolLevel = "NONE" // Strip native debug symbols
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
debug {
|
|
863
|
+
// Ensure debug builds are clearly distinguished
|
|
864
|
+
applicationIdSuffix = ".debug"
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// Disable backup
|
|
869
|
+
defaultConfig {
|
|
870
|
+
manifestPlaceholders["allowBackup"] = "false"
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// NDK: Use -O2 and stack protection for native code
|
|
874
|
+
externalNativeBuild {
|
|
875
|
+
cmake {
|
|
876
|
+
cppFlags("-O2", "-fstack-protector-strong", "-D_FORTIFY_SOURCE=2")
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
### 7.3 Flutter
|
|
883
|
+
|
|
884
|
+
Flutter compiles Dart to native ARM code (AOT) for release builds, which provides
|
|
885
|
+
some inherent protection over interpreted code. However, additional steps are needed:
|
|
886
|
+
|
|
887
|
+
```bash
|
|
888
|
+
# Build with obfuscation enabled
|
|
889
|
+
flutter build apk \
|
|
890
|
+
--release \
|
|
891
|
+
--obfuscate \
|
|
892
|
+
--split-debug-info=build/debug-info
|
|
893
|
+
|
|
894
|
+
flutter build ipa \
|
|
895
|
+
--release \
|
|
896
|
+
--obfuscate \
|
|
897
|
+
--split-debug-info=build/debug-info
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
**Limitations of Flutter's built-in obfuscation:**
|
|
901
|
+
- Only renames Dart symbols (class names, method names, variable names).
|
|
902
|
+
- Does NOT encrypt string literals or resources.
|
|
903
|
+
- Does NOT provide control flow obfuscation.
|
|
904
|
+
- Dart snapshots can still be analyzed with tools like `darter` or `blutter`.
|
|
905
|
+
|
|
906
|
+
**Recommendations:**
|
|
907
|
+
- Use `--split-debug-info` to store symbol maps separately (never ship them).
|
|
908
|
+
- Combine with platform-level protection (R8 for Android, Xcode settings for iOS).
|
|
909
|
+
- Consider commercial tools like DexGuard/iXGuard or Appdome that support Flutter.
|
|
910
|
+
- Move sensitive logic to platform channels (Kotlin/Swift or C via dart:ffi).
|
|
911
|
+
- Use the `flutter_jailbreak_detection` or `freeRASP` package for environment checks.
|
|
912
|
+
|
|
913
|
+
### 7.4 React Native
|
|
914
|
+
|
|
915
|
+
React Native poses unique challenges because JavaScript source is bundled inside the
|
|
916
|
+
binary and can be extracted and read.
|
|
917
|
+
|
|
918
|
+
**Hermes Engine (recommended):**
|
|
919
|
+
```javascript
|
|
920
|
+
// android/app/build.gradle
|
|
921
|
+
project.ext.react = [
|
|
922
|
+
enableHermes: true // Compiles JS to Hermes bytecode
|
|
923
|
+
]
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
Hermes compiles JavaScript to bytecode, making casual reading harder. However, Hermes
|
|
927
|
+
bytecode can be decompiled with tools like `hbc-decompiler`.
|
|
928
|
+
|
|
929
|
+
**Additional protections:**
|
|
930
|
+
- Use `react-native-obfuscating-transformer` with Metro bundler for JS obfuscation.
|
|
931
|
+
- Never store secrets in JavaScript -- use native modules for sensitive operations.
|
|
932
|
+
- If using CodePush (OTA updates), enable code signing to verify update integrity.
|
|
933
|
+
- Apply R8/ProGuard to the Android native layer.
|
|
934
|
+
- Apply Xcode build hardening to the iOS native layer.
|
|
935
|
+
- Consider `jsi` (JavaScript Interface) for performance-sensitive code to reduce
|
|
936
|
+
exposure of business logic in the JS bundle.
|
|
937
|
+
|
|
938
|
+
---
|
|
939
|
+
|
|
940
|
+
## 8. Incident Patterns
|
|
941
|
+
|
|
942
|
+
### 8.1 Repackaged App Detection
|
|
943
|
+
|
|
944
|
+
**Pattern:** Legitimate app is decompiled, modified (malware injected, ads replaced,
|
|
945
|
+
license checks removed), re-signed with attacker's certificate, distributed via
|
|
946
|
+
third-party stores or phishing.
|
|
947
|
+
|
|
948
|
+
**Detection signals:**
|
|
949
|
+
- APK/IPA signature does not match the developer's known certificate.
|
|
950
|
+
- Package hash differs from the version published on official stores.
|
|
951
|
+
- Server-side Play Integrity / App Attest validation fails.
|
|
952
|
+
- App reports a different signing certificate hash at startup.
|
|
953
|
+
|
|
954
|
+
**Response protocol:**
|
|
955
|
+
1. Server rejects API requests from unverified binaries.
|
|
956
|
+
2. Log device fingerprint and report to threat intelligence.
|
|
957
|
+
3. Notify affected users if credential compromise is suspected.
|
|
958
|
+
4. File takedown requests with hosting providers and stores.
|
|
959
|
+
|
|
960
|
+
### 8.2 Hooking Framework Detection
|
|
961
|
+
|
|
962
|
+
**Pattern:** Attacker uses Frida, Xposed, or Cydia Substrate to hook security-critical
|
|
963
|
+
functions at runtime (e.g., bypassing root detection, modifying transaction amounts,
|
|
964
|
+
extracting encryption keys from memory).
|
|
965
|
+
|
|
966
|
+
**Detection signals:**
|
|
967
|
+
- Frida server process running (port 27042 open, `frida-server` in process list).
|
|
968
|
+
- Suspicious libraries loaded (`frida-agent`, `MobileSubstrate`, `libcycript`).
|
|
969
|
+
- Xposed Framework installer app present on device.
|
|
970
|
+
- Named pipes associated with injection frameworks in /proc/self/fd.
|
|
971
|
+
- Method execution timing anomalies (hooked functions run slower).
|
|
972
|
+
|
|
973
|
+
**Response protocol:**
|
|
974
|
+
1. Terminate sensitive operations immediately.
|
|
975
|
+
2. Clear in-memory secrets (encryption keys, session tokens).
|
|
976
|
+
3. Report detection event to server with device fingerprint.
|
|
977
|
+
4. Degrade functionality (block transactions, require step-up authentication).
|
|
978
|
+
5. Do NOT simply crash -- attackers patch crash points. Instead, introduce subtle
|
|
979
|
+
behavioral changes that corrupt results silently while reporting to server.
|
|
980
|
+
|
|
981
|
+
### 8.3 Emulator/Simulator Abuse
|
|
982
|
+
|
|
983
|
+
**Pattern:** Attackers run apps in emulators to automate exploitation, credential
|
|
984
|
+
stuffing, or bonus/reward farming at scale.
|
|
985
|
+
|
|
986
|
+
**Detection signals:**
|
|
987
|
+
- Build properties indicate emulator (generic fingerprint, goldfish/ranchu hardware).
|
|
988
|
+
- Sensor data anomalies (accelerometer returns constant values).
|
|
989
|
+
- Battery status always "charging" with no temperature variation.
|
|
990
|
+
- Missing telephony or Bluetooth hardware.
|
|
991
|
+
|
|
992
|
+
**Response protocol:**
|
|
993
|
+
1. Restrict sensitive features (payments, account changes) on detected emulators.
|
|
994
|
+
2. Allow emulator usage for development builds (debug variant) only.
|
|
995
|
+
3. Rate-limit or challenge requests from suspected emulator instances.
|
|
996
|
+
|
|
997
|
+
---
|
|
998
|
+
|
|
999
|
+
## 9. Compliance and Standards
|
|
1000
|
+
|
|
1001
|
+
### 9.1 OWASP MASVS-RESILIENCE
|
|
1002
|
+
|
|
1003
|
+
The OWASP Mobile Application Security Verification Standard (MASVS) version 2.0
|
|
1004
|
+
defines the MASVS-RESILIENCE category with four control groups covering defense against
|
|
1005
|
+
reverse engineering and tampering:
|
|
1006
|
+
|
|
1007
|
+
| Control | Description |
|
|
1008
|
+
|---------|-------------|
|
|
1009
|
+
| MASVS-RESILIENCE-1 | The app implements anti-tampering mechanisms |
|
|
1010
|
+
| MASVS-RESILIENCE-2 | The app implements anti-static analysis mechanisms |
|
|
1011
|
+
| MASVS-RESILIENCE-3 | The app implements anti-dynamic analysis mechanisms |
|
|
1012
|
+
| MASVS-RESILIENCE-4 | The app implements device integrity verification |
|
|
1013
|
+
|
|
1014
|
+
**When MASVS-RESILIENCE applies:** The R (Resilience) requirements apply to apps where
|
|
1015
|
+
the binary itself is a high-value target: DRM-protected content, payment/banking apps,
|
|
1016
|
+
apps with proprietary algorithms, or apps where client-side logic bypass causes direct
|
|
1017
|
+
financial harm.
|
|
1018
|
+
|
|
1019
|
+
**MASTG mapping:** The OWASP Mobile Application Security Testing Guide (MASTG) provides
|
|
1020
|
+
specific test cases for each MASVS-RESILIENCE control, updated in June 2025 with new
|
|
1021
|
+
MAS profile mappings.
|
|
1022
|
+
|
|
1023
|
+
### 9.2 Financial App Regulatory Requirements
|
|
1024
|
+
|
|
1025
|
+
Financial services apps face additional regulatory requirements for binary protection:
|
|
1026
|
+
|
|
1027
|
+
**PCI DSS 4.0 (Requirement 6):**
|
|
1028
|
+
- Requirement 6.2.4: Software engineering techniques prevent common coding
|
|
1029
|
+
vulnerabilities.
|
|
1030
|
+
- Requirement 6.3.2: Custom application code reviewed for vulnerabilities before
|
|
1031
|
+
release.
|
|
1032
|
+
- Binary hardening is an expected control for apps handling cardholder data.
|
|
1033
|
+
|
|
1034
|
+
**PSD2 (EU Payment Services Directive):**
|
|
1035
|
+
- Strong Customer Authentication (SCA) requirements mandate that authentication
|
|
1036
|
+
elements are protected against compromise.
|
|
1037
|
+
- Mobile app integrity verification is expected for banking apps.
|
|
1038
|
+
|
|
1039
|
+
**DORA (Digital Operational Resilience Act, EU):**
|
|
1040
|
+
- Financial entities must ensure ICT systems are resilient against tampering.
|
|
1041
|
+
- Mobile banking apps are in scope for operational resilience testing.
|
|
1042
|
+
|
|
1043
|
+
**FFIEC (US) Mobile Banking Guidance:**
|
|
1044
|
+
- Recommends application-level security controls including code obfuscation,
|
|
1045
|
+
jailbreak/root detection, and app integrity verification.
|
|
1046
|
+
|
|
1047
|
+
**MAS TRM (Monetary Authority of Singapore):**
|
|
1048
|
+
- Technology Risk Management guidelines explicitly require mobile app hardening
|
|
1049
|
+
for financial institutions, including anti-tampering and anti-reverse engineering.
|
|
1050
|
+
|
|
1051
|
+
---
|
|
1052
|
+
|
|
1053
|
+
## 10. Code Examples: Vulnerable vs. Secure Pairs
|
|
1054
|
+
|
|
1055
|
+
### Example 1: APK Signature Verification
|
|
1056
|
+
|
|
1057
|
+
```kotlin
|
|
1058
|
+
// VULNERABLE: No runtime signature verification
|
|
1059
|
+
class App : Application() {
|
|
1060
|
+
override fun onCreate() {
|
|
1061
|
+
super.onCreate()
|
|
1062
|
+
// App starts without verifying its own integrity
|
|
1063
|
+
initializeServices()
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
```kotlin
|
|
1069
|
+
// SECURE: Verify APK signature at startup
|
|
1070
|
+
class App : Application() {
|
|
1071
|
+
override fun onCreate() {
|
|
1072
|
+
super.onCreate()
|
|
1073
|
+
if (!verifySignature()) {
|
|
1074
|
+
reportTamperingToServer()
|
|
1075
|
+
exitProcess(1)
|
|
1076
|
+
}
|
|
1077
|
+
initializeServices()
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
private fun verifySignature(): Boolean {
|
|
1081
|
+
return try {
|
|
1082
|
+
val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
1083
|
+
packageManager.getPackageInfo(
|
|
1084
|
+
packageName,
|
|
1085
|
+
PackageManager.GET_SIGNING_CERTIFICATES
|
|
1086
|
+
)
|
|
1087
|
+
} else {
|
|
1088
|
+
@Suppress("DEPRECATION")
|
|
1089
|
+
packageManager.getPackageInfo(
|
|
1090
|
+
packageName,
|
|
1091
|
+
PackageManager.GET_SIGNATURES
|
|
1092
|
+
)
|
|
1093
|
+
}
|
|
1094
|
+
val signatures = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
1095
|
+
packageInfo.signingInfo.apkContentsSigners
|
|
1096
|
+
} else {
|
|
1097
|
+
@Suppress("DEPRECATION")
|
|
1098
|
+
packageInfo.signatures
|
|
1099
|
+
}
|
|
1100
|
+
val md = java.security.MessageDigest.getInstance("SHA-256")
|
|
1101
|
+
val currentHash = android.util.Base64.encodeToString(
|
|
1102
|
+
md.digest(signatures[0].toByteArray()),
|
|
1103
|
+
android.util.Base64.NO_WRAP
|
|
1104
|
+
)
|
|
1105
|
+
currentHash == EXPECTED_SIGNATURE_HASH
|
|
1106
|
+
} catch (e: Exception) {
|
|
1107
|
+
false
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
companion object {
|
|
1112
|
+
// Store this hash in native code for additional protection
|
|
1113
|
+
private const val EXPECTED_SIGNATURE_HASH = "your-base64-sha256-hash"
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
### Example 2: Certificate Pinning
|
|
1119
|
+
|
|
1120
|
+
```kotlin
|
|
1121
|
+
// VULNERABLE: No certificate pinning, trusts all CAs
|
|
1122
|
+
val client = OkHttpClient.Builder().build()
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
```kotlin
|
|
1126
|
+
// SECURE: Certificate pinning with OkHttp
|
|
1127
|
+
val client = OkHttpClient.Builder()
|
|
1128
|
+
.certificatePinner(
|
|
1129
|
+
CertificatePinner.Builder()
|
|
1130
|
+
.add(
|
|
1131
|
+
"api.example.com",
|
|
1132
|
+
"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
|
|
1133
|
+
"sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB="
|
|
1134
|
+
)
|
|
1135
|
+
.build()
|
|
1136
|
+
)
|
|
1137
|
+
.build()
|
|
1138
|
+
```
|
|
1139
|
+
|
|
1140
|
+
### Example 3: iOS Integrity Check at Launch
|
|
1141
|
+
|
|
1142
|
+
```swift
|
|
1143
|
+
// VULNERABLE: No integrity checks
|
|
1144
|
+
@main
|
|
1145
|
+
struct MyApp: App {
|
|
1146
|
+
var body: some Scene {
|
|
1147
|
+
WindowGroup { ContentView() }
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
```swift
|
|
1153
|
+
// SECURE: Multi-layer integrity checks at launch
|
|
1154
|
+
@main
|
|
1155
|
+
struct MyApp: App {
|
|
1156
|
+
init() {
|
|
1157
|
+
guard !JailbreakDetector.isJailbroken() else {
|
|
1158
|
+
reportCompromisedEnvironment()
|
|
1159
|
+
fatalError("Unsupported device configuration")
|
|
1160
|
+
}
|
|
1161
|
+
guard !isBeingDebugged() else {
|
|
1162
|
+
reportDebugAttempt()
|
|
1163
|
+
fatalError("Debug session detected")
|
|
1164
|
+
}
|
|
1165
|
+
denyDebugger() // ptrace denial (see Section 3.1)
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
var body: some Scene {
|
|
1169
|
+
WindowGroup { ContentView() }
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
private func isBeingDebugged() -> Bool {
|
|
1173
|
+
var info = kinfo_proc()
|
|
1174
|
+
var size = MemoryLayout<kinfo_proc>.size
|
|
1175
|
+
var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()]
|
|
1176
|
+
sysctl(&mib, 4, &info, &size, nil, 0)
|
|
1177
|
+
return (info.kp_proc.p_flag & P_TRACED) != 0
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
```
|
|
1181
|
+
|
|
1182
|
+
### Example 4: Secure Storage of Sensitive Data
|
|
1183
|
+
|
|
1184
|
+
```kotlin
|
|
1185
|
+
// VULNERABLE: Plaintext SharedPreferences
|
|
1186
|
+
val prefs = getSharedPreferences("auth", MODE_PRIVATE)
|
|
1187
|
+
prefs.edit().putString("token", accessToken).apply()
|
|
1188
|
+
```
|
|
1189
|
+
|
|
1190
|
+
```kotlin
|
|
1191
|
+
// SECURE: EncryptedSharedPreferences with AndroidX Security
|
|
1192
|
+
val masterKey = MasterKey.Builder(context)
|
|
1193
|
+
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
|
|
1194
|
+
.build()
|
|
1195
|
+
|
|
1196
|
+
val securePrefs = EncryptedSharedPreferences.create(
|
|
1197
|
+
context,
|
|
1198
|
+
"secure_auth",
|
|
1199
|
+
masterKey,
|
|
1200
|
+
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
|
1201
|
+
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
|
1202
|
+
)
|
|
1203
|
+
securePrefs.edit().putString("token", accessToken).apply()
|
|
1204
|
+
```
|
|
1205
|
+
|
|
1206
|
+
---
|
|
1207
|
+
|
|
1208
|
+
## References and Sources
|
|
1209
|
+
|
|
1210
|
+
- [OWASP MASVS-RESILIENCE](https://mas.owasp.org/MASVS/11-MASVS-RESILIENCE/)
|
|
1211
|
+
- [OWASP MASVS Checklist](https://mas.owasp.org/checklists/MASVS-RESILIENCE/)
|
|
1212
|
+
- [Promon App Threat Report: Hooking Framework Detection 2024](https://promon.io/resources/downloads/app-threat-report-hooking-framework-frida-2024)
|
|
1213
|
+
- [Promon Mobile Malware Threats 2025](https://promon.io/security-news/mobile-malware-2025)
|
|
1214
|
+
- [Guardsquare DexGuard](https://www.guardsquare.com/dexguard)
|
|
1215
|
+
- [Guardsquare iXGuard](https://www.guardsquare.com/ixguard)
|
|
1216
|
+
- [Android Play Integrity API](https://developer.android.com/google/play/integrity)
|
|
1217
|
+
- [Apple App Attest Documentation](https://developer.apple.com/documentation/devicecheck/establishing-your-app-s-integrity)
|
|
1218
|
+
- [Apple DeviceCheck](https://developer.apple.com/documentation/devicecheck)
|
|
1219
|
+
- [Flutter: Obfuscate Dart Code](https://docs.flutter.dev/deployment/obfuscate)
|
|
1220
|
+
- [R8 Keep Rules -- Android Developers Blog](https://android-developers.googleblog.com/2025/11/configure-and-troubleshoot-r8-keep-rules.html)
|
|
1221
|
+
- [iOS Security Suite (GitHub)](https://github.com/securing/IOSSecuritySuite)
|
|
1222
|
+
- [RootBeer (GitHub)](https://github.com/scottyab/rootbeer)
|
|
1223
|
+
- [Talsec: Root Detection with Kotlin](https://docs.talsec.app/appsec-articles/articles/how-to-detect-root-using-kotlin)
|
|
1224
|
+
- [Talsec: Detect Hooking (Frida) using Swift](https://docs.talsec.app/appsec-articles/articles/how-to-detect-hooking-frida-using-swift)
|
|
1225
|
+
- [Czech Mobile Users NFC Attack -- The Hacker News](https://thehackernews.com/2024/08/czech-mobile-users-targeted-in-new.html)
|
|
1226
|
+
- [Play Integrity API Limitations -- Approov](https://approov.io/blog/limitations-of-google-play-integrity-api-ex-safetynet)
|
|
1227
|
+
- [Apple App Attest Limitations -- Approov](https://approov.io/blog/limitations-of-apple-devicecheck-and-apple-app-attest)
|
|
1228
|
+
- [Verimatrix: Repackaging Attacks](https://www.verimatrix.com/cybersecurity/knowledge-base/what-is-a-repackaging-attack/)
|
|
1229
|
+
- [Guardsquare: OWASP MASVS-RESILIENCE](https://help.guardsquare.com/en/articles/30268-the-role-of-mobile-app-protection-in-owasp-standards-masvs)
|