@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.
Files changed (629) hide show
  1. package/AGENTS.md +111 -0
  2. package/CHANGELOG.md +14 -0
  3. package/CONTRIBUTING.md +101 -0
  4. package/LICENSE +21 -0
  5. package/README.md +314 -0
  6. package/assets/composition-engine.mmd +34 -0
  7. package/assets/demo-script.sh +17 -0
  8. package/assets/logo-dark.svg +14 -0
  9. package/assets/logo.svg +14 -0
  10. package/assets/pipeline.mmd +39 -0
  11. package/assets/record-demo.sh +51 -0
  12. package/docs/README.md +51 -0
  13. package/docs/adapters/context-mode.md +60 -0
  14. package/docs/concepts/architecture.md +87 -0
  15. package/docs/concepts/artifact-model.md +60 -0
  16. package/docs/concepts/composition-engine.md +36 -0
  17. package/docs/concepts/indexing-and-recall.md +160 -0
  18. package/docs/concepts/observability.md +41 -0
  19. package/docs/concepts/roles-and-workflows.md +59 -0
  20. package/docs/concepts/terminology-policy.md +27 -0
  21. package/docs/getting-started/01-installation.md +78 -0
  22. package/docs/getting-started/02-first-run.md +102 -0
  23. package/docs/getting-started/03-adding-to-project.md +15 -0
  24. package/docs/getting-started/04-host-setup.md +15 -0
  25. package/docs/guides/ci-integration.md +15 -0
  26. package/docs/guides/creating-skills.md +15 -0
  27. package/docs/guides/expertise-module-authoring.md +15 -0
  28. package/docs/guides/hook-development.md +15 -0
  29. package/docs/guides/memory-and-learnings.md +34 -0
  30. package/docs/guides/multi-host-export.md +15 -0
  31. package/docs/guides/troubleshooting.md +101 -0
  32. package/docs/guides/writing-custom-roles.md +15 -0
  33. package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
  34. package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
  35. package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
  36. package/docs/readmes/INDEX.md +99 -0
  37. package/docs/readmes/features/expertise/README.md +171 -0
  38. package/docs/readmes/features/exports/README.md +222 -0
  39. package/docs/readmes/features/hooks/README.md +103 -0
  40. package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
  41. package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
  42. package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
  43. package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
  44. package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
  45. package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
  46. package/docs/readmes/features/hooks/session-start.md +119 -0
  47. package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
  48. package/docs/readmes/features/roles/README.md +157 -0
  49. package/docs/readmes/features/roles/clarifier.md +152 -0
  50. package/docs/readmes/features/roles/content-author.md +190 -0
  51. package/docs/readmes/features/roles/designer.md +193 -0
  52. package/docs/readmes/features/roles/executor.md +184 -0
  53. package/docs/readmes/features/roles/learner.md +210 -0
  54. package/docs/readmes/features/roles/planner.md +182 -0
  55. package/docs/readmes/features/roles/researcher.md +164 -0
  56. package/docs/readmes/features/roles/reviewer.md +184 -0
  57. package/docs/readmes/features/roles/specifier.md +162 -0
  58. package/docs/readmes/features/roles/verifier.md +215 -0
  59. package/docs/readmes/features/schemas/README.md +178 -0
  60. package/docs/readmes/features/skills/README.md +63 -0
  61. package/docs/readmes/features/skills/brainstorming.md +96 -0
  62. package/docs/readmes/features/skills/debugging.md +148 -0
  63. package/docs/readmes/features/skills/design.md +120 -0
  64. package/docs/readmes/features/skills/prepare-next.md +109 -0
  65. package/docs/readmes/features/skills/run-audit.md +159 -0
  66. package/docs/readmes/features/skills/scan-project.md +109 -0
  67. package/docs/readmes/features/skills/self-audit.md +176 -0
  68. package/docs/readmes/features/skills/tdd.md +137 -0
  69. package/docs/readmes/features/skills/using-skills.md +92 -0
  70. package/docs/readmes/features/skills/verification.md +120 -0
  71. package/docs/readmes/features/skills/writing-plans.md +104 -0
  72. package/docs/readmes/features/tooling/README.md +320 -0
  73. package/docs/readmes/features/workflows/README.md +186 -0
  74. package/docs/readmes/features/workflows/author.md +181 -0
  75. package/docs/readmes/features/workflows/clarify.md +154 -0
  76. package/docs/readmes/features/workflows/design-review.md +171 -0
  77. package/docs/readmes/features/workflows/design.md +169 -0
  78. package/docs/readmes/features/workflows/discover.md +162 -0
  79. package/docs/readmes/features/workflows/execute.md +173 -0
  80. package/docs/readmes/features/workflows/learn.md +167 -0
  81. package/docs/readmes/features/workflows/plan-review.md +165 -0
  82. package/docs/readmes/features/workflows/plan.md +170 -0
  83. package/docs/readmes/features/workflows/prepare-next.md +167 -0
  84. package/docs/readmes/features/workflows/review.md +169 -0
  85. package/docs/readmes/features/workflows/run-audit.md +191 -0
  86. package/docs/readmes/features/workflows/spec-challenge.md +159 -0
  87. package/docs/readmes/features/workflows/specify.md +160 -0
  88. package/docs/readmes/features/workflows/verify.md +177 -0
  89. package/docs/readmes/packages/README.md +50 -0
  90. package/docs/readmes/packages/ajv.md +117 -0
  91. package/docs/readmes/packages/context-mode.md +118 -0
  92. package/docs/readmes/packages/gray-matter.md +116 -0
  93. package/docs/readmes/packages/node-test.md +137 -0
  94. package/docs/readmes/packages/yaml.md +112 -0
  95. package/docs/reference/configuration-reference.md +159 -0
  96. package/docs/reference/expertise-index.md +52 -0
  97. package/docs/reference/git-flow.md +43 -0
  98. package/docs/reference/hooks.md +87 -0
  99. package/docs/reference/host-exports.md +50 -0
  100. package/docs/reference/launch-checklist.md +172 -0
  101. package/docs/reference/marketplace-listings.md +76 -0
  102. package/docs/reference/release-process.md +34 -0
  103. package/docs/reference/roles-reference.md +77 -0
  104. package/docs/reference/skills.md +33 -0
  105. package/docs/reference/templates.md +29 -0
  106. package/docs/reference/tooling-cli.md +94 -0
  107. package/docs/truth-claims.yaml +222 -0
  108. package/expertise/PROGRESS.md +63 -0
  109. package/expertise/README.md +18 -0
  110. package/expertise/antipatterns/PROGRESS.md +56 -0
  111. package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
  112. package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
  113. package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
  114. package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
  115. package/expertise/antipatterns/backend/index.md +24 -0
  116. package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
  117. package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
  118. package/expertise/antipatterns/code/async-antipatterns.md +622 -0
  119. package/expertise/antipatterns/code/code-smells.md +1186 -0
  120. package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
  121. package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
  122. package/expertise/antipatterns/code/index.md +27 -0
  123. package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
  124. package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
  125. package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
  126. package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
  127. package/expertise/antipatterns/design/dark-patterns.md +1121 -0
  128. package/expertise/antipatterns/design/index.md +22 -0
  129. package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
  130. package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
  131. package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
  132. package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
  133. package/expertise/antipatterns/frontend/index.md +23 -0
  134. package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
  135. package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
  136. package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
  137. package/expertise/antipatterns/index.md +31 -0
  138. package/expertise/antipatterns/performance/index.md +20 -0
  139. package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
  140. package/expertise/antipatterns/performance/premature-optimization.md +623 -0
  141. package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
  142. package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
  143. package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
  144. package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
  145. package/expertise/antipatterns/process/index.md +23 -0
  146. package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
  147. package/expertise/antipatterns/security/index.md +20 -0
  148. package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
  149. package/expertise/antipatterns/security/security-theater.md +843 -0
  150. package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
  151. package/expertise/architecture/PROGRESS.md +70 -0
  152. package/expertise/architecture/data/caching-architecture.md +671 -0
  153. package/expertise/architecture/data/data-consistency.md +574 -0
  154. package/expertise/architecture/data/data-modeling.md +536 -0
  155. package/expertise/architecture/data/event-streams-and-queues.md +634 -0
  156. package/expertise/architecture/data/index.md +25 -0
  157. package/expertise/architecture/data/search-architecture.md +663 -0
  158. package/expertise/architecture/data/sql-vs-nosql.md +708 -0
  159. package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
  160. package/expertise/architecture/decisions/build-vs-buy.md +616 -0
  161. package/expertise/architecture/decisions/index.md +23 -0
  162. package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
  163. package/expertise/architecture/decisions/technology-selection.md +616 -0
  164. package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
  165. package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
  166. package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
  167. package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
  168. package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
  169. package/expertise/architecture/distributed/index.md +25 -0
  170. package/expertise/architecture/distributed/saga-pattern.md +797 -0
  171. package/expertise/architecture/foundations/architectural-thinking.md +460 -0
  172. package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
  173. package/expertise/architecture/foundations/design-principles-solid.md +649 -0
  174. package/expertise/architecture/foundations/domain-driven-design.md +719 -0
  175. package/expertise/architecture/foundations/index.md +25 -0
  176. package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
  177. package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
  178. package/expertise/architecture/index.md +34 -0
  179. package/expertise/architecture/integration/api-design-graphql.md +638 -0
  180. package/expertise/architecture/integration/api-design-grpc.md +804 -0
  181. package/expertise/architecture/integration/api-design-rest.md +892 -0
  182. package/expertise/architecture/integration/index.md +25 -0
  183. package/expertise/architecture/integration/third-party-integration.md +795 -0
  184. package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
  185. package/expertise/architecture/integration/websockets-realtime.md +791 -0
  186. package/expertise/architecture/mobile-architecture/index.md +22 -0
  187. package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
  188. package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
  189. package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
  190. package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
  191. package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
  192. package/expertise/architecture/patterns/event-driven.md +797 -0
  193. package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
  194. package/expertise/architecture/patterns/index.md +27 -0
  195. package/expertise/architecture/patterns/layered-architecture.md +736 -0
  196. package/expertise/architecture/patterns/microservices.md +753 -0
  197. package/expertise/architecture/patterns/modular-monolith.md +692 -0
  198. package/expertise/architecture/patterns/monolith.md +626 -0
  199. package/expertise/architecture/patterns/plugin-architecture.md +735 -0
  200. package/expertise/architecture/patterns/serverless.md +780 -0
  201. package/expertise/architecture/scaling/database-scaling.md +615 -0
  202. package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
  203. package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
  204. package/expertise/architecture/scaling/index.md +24 -0
  205. package/expertise/architecture/scaling/multi-tenancy.md +800 -0
  206. package/expertise/architecture/scaling/stateless-design.md +787 -0
  207. package/expertise/backend/embedded-firmware.md +625 -0
  208. package/expertise/backend/go.md +853 -0
  209. package/expertise/backend/index.md +24 -0
  210. package/expertise/backend/java-spring.md +448 -0
  211. package/expertise/backend/node-typescript.md +625 -0
  212. package/expertise/backend/python-fastapi.md +724 -0
  213. package/expertise/backend/rust.md +458 -0
  214. package/expertise/backend/solidity.md +711 -0
  215. package/expertise/composition-map.yaml +443 -0
  216. package/expertise/content/foundations/content-modeling.md +395 -0
  217. package/expertise/content/foundations/editorial-standards.md +449 -0
  218. package/expertise/content/foundations/index.md +24 -0
  219. package/expertise/content/foundations/microcopy.md +455 -0
  220. package/expertise/content/foundations/terminology-governance.md +509 -0
  221. package/expertise/content/index.md +34 -0
  222. package/expertise/content/patterns/accessibility-copy.md +518 -0
  223. package/expertise/content/patterns/index.md +24 -0
  224. package/expertise/content/patterns/notification-content.md +433 -0
  225. package/expertise/content/patterns/sample-content.md +486 -0
  226. package/expertise/content/patterns/state-copy.md +439 -0
  227. package/expertise/design/PROGRESS.md +58 -0
  228. package/expertise/design/disciplines/dark-mode-theming.md +577 -0
  229. package/expertise/design/disciplines/design-systems.md +595 -0
  230. package/expertise/design/disciplines/index.md +25 -0
  231. package/expertise/design/disciplines/information-architecture.md +800 -0
  232. package/expertise/design/disciplines/interaction-design.md +788 -0
  233. package/expertise/design/disciplines/responsive-design.md +552 -0
  234. package/expertise/design/disciplines/usability-testing.md +516 -0
  235. package/expertise/design/disciplines/user-research.md +792 -0
  236. package/expertise/design/foundations/accessibility-design.md +796 -0
  237. package/expertise/design/foundations/color-theory.md +797 -0
  238. package/expertise/design/foundations/iconography.md +795 -0
  239. package/expertise/design/foundations/index.md +26 -0
  240. package/expertise/design/foundations/motion-and-animation.md +653 -0
  241. package/expertise/design/foundations/rtl-design.md +585 -0
  242. package/expertise/design/foundations/spacing-and-layout.md +607 -0
  243. package/expertise/design/foundations/typography.md +800 -0
  244. package/expertise/design/foundations/visual-hierarchy.md +761 -0
  245. package/expertise/design/index.md +32 -0
  246. package/expertise/design/patterns/authentication-flows.md +474 -0
  247. package/expertise/design/patterns/content-consumption.md +789 -0
  248. package/expertise/design/patterns/data-display.md +618 -0
  249. package/expertise/design/patterns/e-commerce.md +1494 -0
  250. package/expertise/design/patterns/feedback-and-states.md +642 -0
  251. package/expertise/design/patterns/forms-and-input.md +819 -0
  252. package/expertise/design/patterns/gamification.md +801 -0
  253. package/expertise/design/patterns/index.md +31 -0
  254. package/expertise/design/patterns/microinteractions.md +449 -0
  255. package/expertise/design/patterns/navigation.md +800 -0
  256. package/expertise/design/patterns/notifications.md +705 -0
  257. package/expertise/design/patterns/onboarding.md +700 -0
  258. package/expertise/design/patterns/search-and-filter.md +601 -0
  259. package/expertise/design/patterns/settings-and-preferences.md +768 -0
  260. package/expertise/design/patterns/social-and-community.md +748 -0
  261. package/expertise/design/platforms/desktop-native.md +612 -0
  262. package/expertise/design/platforms/index.md +25 -0
  263. package/expertise/design/platforms/mobile-android.md +825 -0
  264. package/expertise/design/platforms/mobile-cross-platform.md +983 -0
  265. package/expertise/design/platforms/mobile-ios.md +699 -0
  266. package/expertise/design/platforms/tablet.md +794 -0
  267. package/expertise/design/platforms/web-dashboard.md +790 -0
  268. package/expertise/design/platforms/web-responsive.md +550 -0
  269. package/expertise/design/psychology/behavioral-nudges.md +449 -0
  270. package/expertise/design/psychology/cognitive-load.md +1191 -0
  271. package/expertise/design/psychology/error-psychology.md +778 -0
  272. package/expertise/design/psychology/index.md +22 -0
  273. package/expertise/design/psychology/persuasive-design.md +736 -0
  274. package/expertise/design/psychology/user-mental-models.md +623 -0
  275. package/expertise/design/tooling/open-pencil.md +266 -0
  276. package/expertise/frontend/angular.md +1073 -0
  277. package/expertise/frontend/desktop-electron.md +546 -0
  278. package/expertise/frontend/flutter.md +782 -0
  279. package/expertise/frontend/index.md +27 -0
  280. package/expertise/frontend/native-android.md +409 -0
  281. package/expertise/frontend/native-ios.md +490 -0
  282. package/expertise/frontend/react-native.md +1160 -0
  283. package/expertise/frontend/react.md +808 -0
  284. package/expertise/frontend/vue.md +1089 -0
  285. package/expertise/humanize/domain-rules-code.md +79 -0
  286. package/expertise/humanize/domain-rules-content.md +67 -0
  287. package/expertise/humanize/domain-rules-technical-docs.md +56 -0
  288. package/expertise/humanize/index.md +35 -0
  289. package/expertise/humanize/self-audit-checklist.md +87 -0
  290. package/expertise/humanize/sentence-patterns.md +218 -0
  291. package/expertise/humanize/vocabulary-blacklist.md +105 -0
  292. package/expertise/i18n/PROGRESS.md +65 -0
  293. package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
  294. package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
  295. package/expertise/i18n/advanced/complex-scripts.md +30 -0
  296. package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
  297. package/expertise/i18n/advanced/testing-i18n.md +28 -0
  298. package/expertise/i18n/content/content-adaptation.md +23 -0
  299. package/expertise/i18n/content/locale-specific-formatting.md +23 -0
  300. package/expertise/i18n/content/machine-translation-integration.md +28 -0
  301. package/expertise/i18n/content/translation-management.md +29 -0
  302. package/expertise/i18n/foundations/date-time-calendars.md +67 -0
  303. package/expertise/i18n/foundations/i18n-architecture.md +272 -0
  304. package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
  305. package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
  306. package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
  307. package/expertise/i18n/foundations/string-externalization.md +236 -0
  308. package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
  309. package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
  310. package/expertise/i18n/index.md +38 -0
  311. package/expertise/i18n/platform/backend-i18n.md +31 -0
  312. package/expertise/i18n/platform/flutter-i18n.md +148 -0
  313. package/expertise/i18n/platform/native-android-i18n.md +36 -0
  314. package/expertise/i18n/platform/native-ios-i18n.md +36 -0
  315. package/expertise/i18n/platform/react-i18n.md +103 -0
  316. package/expertise/i18n/platform/web-css-i18n.md +81 -0
  317. package/expertise/i18n/rtl/arabic-specific.md +175 -0
  318. package/expertise/i18n/rtl/hebrew-specific.md +149 -0
  319. package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
  320. package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
  321. package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
  322. package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
  323. package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
  324. package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
  325. package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
  326. package/expertise/i18n/rtl/rtl-typography.md +160 -0
  327. package/expertise/index.md +113 -0
  328. package/expertise/index.yaml +216 -0
  329. package/expertise/infrastructure/cloud-aws.md +597 -0
  330. package/expertise/infrastructure/cloud-gcp.md +599 -0
  331. package/expertise/infrastructure/cybersecurity.md +816 -0
  332. package/expertise/infrastructure/database-mongodb.md +447 -0
  333. package/expertise/infrastructure/database-postgres.md +400 -0
  334. package/expertise/infrastructure/devops-cicd.md +787 -0
  335. package/expertise/infrastructure/index.md +27 -0
  336. package/expertise/performance/PROGRESS.md +50 -0
  337. package/expertise/performance/backend/api-latency.md +1204 -0
  338. package/expertise/performance/backend/background-jobs.md +506 -0
  339. package/expertise/performance/backend/connection-pooling.md +1209 -0
  340. package/expertise/performance/backend/database-query-optimization.md +515 -0
  341. package/expertise/performance/backend/index.md +23 -0
  342. package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
  343. package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
  344. package/expertise/performance/foundations/caching-strategies.md +489 -0
  345. package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
  346. package/expertise/performance/foundations/index.md +24 -0
  347. package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
  348. package/expertise/performance/foundations/memory-management.md +964 -0
  349. package/expertise/performance/foundations/performance-budgets.md +1314 -0
  350. package/expertise/performance/index.md +31 -0
  351. package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
  352. package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
  353. package/expertise/performance/infrastructure/index.md +22 -0
  354. package/expertise/performance/infrastructure/load-balancing.md +1081 -0
  355. package/expertise/performance/infrastructure/observability.md +1079 -0
  356. package/expertise/performance/mobile/index.md +23 -0
  357. package/expertise/performance/mobile/mobile-animations.md +544 -0
  358. package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
  359. package/expertise/performance/mobile/mobile-network.md +452 -0
  360. package/expertise/performance/mobile/mobile-rendering.md +599 -0
  361. package/expertise/performance/mobile/mobile-startup-time.md +505 -0
  362. package/expertise/performance/platform-specific/flutter-performance.md +647 -0
  363. package/expertise/performance/platform-specific/index.md +22 -0
  364. package/expertise/performance/platform-specific/node-performance.md +1307 -0
  365. package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
  366. package/expertise/performance/platform-specific/react-performance.md +1403 -0
  367. package/expertise/performance/web/bundle-optimization.md +1239 -0
  368. package/expertise/performance/web/image-and-media.md +636 -0
  369. package/expertise/performance/web/index.md +24 -0
  370. package/expertise/performance/web/network-optimization.md +1133 -0
  371. package/expertise/performance/web/rendering-performance.md +1098 -0
  372. package/expertise/performance/web/ssr-and-hydration.md +918 -0
  373. package/expertise/performance/web/web-vitals.md +1374 -0
  374. package/expertise/quality/accessibility.md +985 -0
  375. package/expertise/quality/evidence-based-verification.md +499 -0
  376. package/expertise/quality/index.md +24 -0
  377. package/expertise/quality/ml-model-audit.md +614 -0
  378. package/expertise/quality/performance.md +600 -0
  379. package/expertise/quality/testing-api.md +891 -0
  380. package/expertise/quality/testing-mobile.md +496 -0
  381. package/expertise/quality/testing-web.md +849 -0
  382. package/expertise/security/PROGRESS.md +54 -0
  383. package/expertise/security/agentic-identity.md +540 -0
  384. package/expertise/security/compliance-frameworks.md +601 -0
  385. package/expertise/security/data/data-encryption.md +364 -0
  386. package/expertise/security/data/data-privacy-gdpr.md +692 -0
  387. package/expertise/security/data/database-security.md +1171 -0
  388. package/expertise/security/data/index.md +22 -0
  389. package/expertise/security/data/pii-handling.md +531 -0
  390. package/expertise/security/foundations/authentication.md +1041 -0
  391. package/expertise/security/foundations/authorization.md +603 -0
  392. package/expertise/security/foundations/cryptography.md +1001 -0
  393. package/expertise/security/foundations/index.md +25 -0
  394. package/expertise/security/foundations/owasp-top-10.md +1354 -0
  395. package/expertise/security/foundations/secrets-management.md +1217 -0
  396. package/expertise/security/foundations/secure-sdlc.md +700 -0
  397. package/expertise/security/foundations/supply-chain-security.md +698 -0
  398. package/expertise/security/index.md +31 -0
  399. package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
  400. package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
  401. package/expertise/security/infrastructure/container-security.md +721 -0
  402. package/expertise/security/infrastructure/incident-response.md +1295 -0
  403. package/expertise/security/infrastructure/index.md +24 -0
  404. package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
  405. package/expertise/security/infrastructure/network-security.md +1337 -0
  406. package/expertise/security/mobile/index.md +23 -0
  407. package/expertise/security/mobile/mobile-android-security.md +1218 -0
  408. package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
  409. package/expertise/security/mobile/mobile-data-storage.md +1265 -0
  410. package/expertise/security/mobile/mobile-ios-security.md +1401 -0
  411. package/expertise/security/mobile/mobile-network-security.md +1520 -0
  412. package/expertise/security/smart-contract-security.md +594 -0
  413. package/expertise/security/testing/index.md +22 -0
  414. package/expertise/security/testing/penetration-testing.md +1258 -0
  415. package/expertise/security/testing/security-code-review.md +1765 -0
  416. package/expertise/security/testing/threat-modeling.md +1074 -0
  417. package/expertise/security/testing/vulnerability-scanning.md +1062 -0
  418. package/expertise/security/web/api-security.md +586 -0
  419. package/expertise/security/web/cors-and-headers.md +433 -0
  420. package/expertise/security/web/csrf.md +562 -0
  421. package/expertise/security/web/file-upload.md +1477 -0
  422. package/expertise/security/web/index.md +25 -0
  423. package/expertise/security/web/injection.md +1375 -0
  424. package/expertise/security/web/session-management.md +1101 -0
  425. package/expertise/security/web/xss.md +1158 -0
  426. package/exports/README.md +17 -0
  427. package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
  428. package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
  429. package/exports/hosts/claude/.claude/agents/designer.md +55 -0
  430. package/exports/hosts/claude/.claude/agents/executor.md +55 -0
  431. package/exports/hosts/claude/.claude/agents/learner.md +51 -0
  432. package/exports/hosts/claude/.claude/agents/planner.md +53 -0
  433. package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
  434. package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
  435. package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
  436. package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
  437. package/exports/hosts/claude/.claude/commands/author.md +42 -0
  438. package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
  439. package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
  440. package/exports/hosts/claude/.claude/commands/design.md +44 -0
  441. package/exports/hosts/claude/.claude/commands/discover.md +37 -0
  442. package/exports/hosts/claude/.claude/commands/execute.md +48 -0
  443. package/exports/hosts/claude/.claude/commands/learn.md +38 -0
  444. package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
  445. package/exports/hosts/claude/.claude/commands/plan.md +39 -0
  446. package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
  447. package/exports/hosts/claude/.claude/commands/review.md +40 -0
  448. package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
  449. package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
  450. package/exports/hosts/claude/.claude/commands/specify.md +38 -0
  451. package/exports/hosts/claude/.claude/commands/verify.md +37 -0
  452. package/exports/hosts/claude/.claude/settings.json +34 -0
  453. package/exports/hosts/claude/CLAUDE.md +19 -0
  454. package/exports/hosts/claude/export.manifest.json +38 -0
  455. package/exports/hosts/claude/host-package.json +67 -0
  456. package/exports/hosts/codex/AGENTS.md +19 -0
  457. package/exports/hosts/codex/export.manifest.json +38 -0
  458. package/exports/hosts/codex/host-package.json +41 -0
  459. package/exports/hosts/cursor/.cursor/hooks.json +16 -0
  460. package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
  461. package/exports/hosts/cursor/export.manifest.json +38 -0
  462. package/exports/hosts/cursor/host-package.json +42 -0
  463. package/exports/hosts/gemini/GEMINI.md +19 -0
  464. package/exports/hosts/gemini/export.manifest.json +38 -0
  465. package/exports/hosts/gemini/host-package.json +41 -0
  466. package/hooks/README.md +18 -0
  467. package/hooks/definitions/loop_cap_guard.yaml +21 -0
  468. package/hooks/definitions/post_tool_capture.yaml +24 -0
  469. package/hooks/definitions/pre_compact_summary.yaml +19 -0
  470. package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
  471. package/hooks/definitions/protected_path_write_guard.yaml +19 -0
  472. package/hooks/definitions/session_start.yaml +19 -0
  473. package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
  474. package/hooks/loop-cap-guard +17 -0
  475. package/hooks/post-tool-lint +36 -0
  476. package/hooks/protected-path-write-guard +17 -0
  477. package/hooks/session-start +41 -0
  478. package/llms-full.txt +2355 -0
  479. package/llms.txt +43 -0
  480. package/package.json +79 -0
  481. package/roles/README.md +20 -0
  482. package/roles/clarifier.md +42 -0
  483. package/roles/content-author.md +63 -0
  484. package/roles/designer.md +55 -0
  485. package/roles/executor.md +55 -0
  486. package/roles/learner.md +51 -0
  487. package/roles/planner.md +53 -0
  488. package/roles/researcher.md +43 -0
  489. package/roles/reviewer.md +54 -0
  490. package/roles/specifier.md +47 -0
  491. package/roles/verifier.md +71 -0
  492. package/schemas/README.md +24 -0
  493. package/schemas/accepted-learning.schema.json +20 -0
  494. package/schemas/author-artifact.schema.json +156 -0
  495. package/schemas/clarification.schema.json +19 -0
  496. package/schemas/design-artifact.schema.json +80 -0
  497. package/schemas/docs-claim.schema.json +18 -0
  498. package/schemas/export-manifest.schema.json +20 -0
  499. package/schemas/hook.schema.json +67 -0
  500. package/schemas/host-export-package.schema.json +18 -0
  501. package/schemas/implementation-plan.schema.json +19 -0
  502. package/schemas/proposed-learning.schema.json +19 -0
  503. package/schemas/research.schema.json +18 -0
  504. package/schemas/review.schema.json +29 -0
  505. package/schemas/run-manifest.schema.json +18 -0
  506. package/schemas/spec-challenge.schema.json +18 -0
  507. package/schemas/spec.schema.json +20 -0
  508. package/schemas/usage.schema.json +102 -0
  509. package/schemas/verification-proof.schema.json +29 -0
  510. package/schemas/wazir-manifest.schema.json +173 -0
  511. package/skills/README.md +40 -0
  512. package/skills/brainstorming/SKILL.md +77 -0
  513. package/skills/debugging/SKILL.md +50 -0
  514. package/skills/design/SKILL.md +61 -0
  515. package/skills/dispatching-parallel-agents/SKILL.md +128 -0
  516. package/skills/executing-plans/SKILL.md +70 -0
  517. package/skills/finishing-a-development-branch/SKILL.md +169 -0
  518. package/skills/humanize/SKILL.md +123 -0
  519. package/skills/init-pipeline/SKILL.md +124 -0
  520. package/skills/prepare-next/SKILL.md +20 -0
  521. package/skills/receiving-code-review/SKILL.md +123 -0
  522. package/skills/requesting-code-review/SKILL.md +105 -0
  523. package/skills/requesting-code-review/code-reviewer.md +108 -0
  524. package/skills/run-audit/SKILL.md +197 -0
  525. package/skills/scan-project/SKILL.md +41 -0
  526. package/skills/self-audit/SKILL.md +153 -0
  527. package/skills/subagent-driven-development/SKILL.md +154 -0
  528. package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
  529. package/skills/subagent-driven-development/implementer-prompt.md +102 -0
  530. package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
  531. package/skills/tdd/SKILL.md +23 -0
  532. package/skills/using-git-worktrees/SKILL.md +163 -0
  533. package/skills/using-skills/SKILL.md +95 -0
  534. package/skills/verification/SKILL.md +22 -0
  535. package/skills/wazir/SKILL.md +463 -0
  536. package/skills/writing-plans/SKILL.md +30 -0
  537. package/skills/writing-skills/SKILL.md +157 -0
  538. package/skills/writing-skills/anthropic-best-practices.md +122 -0
  539. package/skills/writing-skills/persuasion-principles.md +50 -0
  540. package/templates/README.md +20 -0
  541. package/templates/artifacts/README.md +10 -0
  542. package/templates/artifacts/accepted-learning.md +19 -0
  543. package/templates/artifacts/accepted-learning.template.json +12 -0
  544. package/templates/artifacts/author.md +74 -0
  545. package/templates/artifacts/author.template.json +19 -0
  546. package/templates/artifacts/clarification.md +21 -0
  547. package/templates/artifacts/clarification.template.json +12 -0
  548. package/templates/artifacts/execute-notes.md +19 -0
  549. package/templates/artifacts/implementation-plan.md +21 -0
  550. package/templates/artifacts/implementation-plan.template.json +11 -0
  551. package/templates/artifacts/learning-proposal.md +19 -0
  552. package/templates/artifacts/next-run-handoff.md +21 -0
  553. package/templates/artifacts/plan-review.md +19 -0
  554. package/templates/artifacts/proposed-learning.template.json +12 -0
  555. package/templates/artifacts/research.md +21 -0
  556. package/templates/artifacts/research.template.json +12 -0
  557. package/templates/artifacts/review-findings.md +19 -0
  558. package/templates/artifacts/review.template.json +11 -0
  559. package/templates/artifacts/run-manifest.template.json +8 -0
  560. package/templates/artifacts/spec-challenge.md +19 -0
  561. package/templates/artifacts/spec-challenge.template.json +11 -0
  562. package/templates/artifacts/spec.md +21 -0
  563. package/templates/artifacts/spec.template.json +12 -0
  564. package/templates/artifacts/verification-proof.md +19 -0
  565. package/templates/artifacts/verification-proof.template.json +11 -0
  566. package/templates/examples/accepted-learning.example.json +14 -0
  567. package/templates/examples/author.example.json +152 -0
  568. package/templates/examples/clarification.example.json +15 -0
  569. package/templates/examples/docs-claim.example.json +8 -0
  570. package/templates/examples/export-manifest.example.json +7 -0
  571. package/templates/examples/host-export-package.example.json +11 -0
  572. package/templates/examples/implementation-plan.example.json +17 -0
  573. package/templates/examples/proposed-learning.example.json +13 -0
  574. package/templates/examples/research.example.json +15 -0
  575. package/templates/examples/research.example.md +6 -0
  576. package/templates/examples/review.example.json +17 -0
  577. package/templates/examples/run-manifest.example.json +9 -0
  578. package/templates/examples/spec-challenge.example.json +14 -0
  579. package/templates/examples/spec.example.json +21 -0
  580. package/templates/examples/verification-proof.example.json +21 -0
  581. package/templates/examples/wazir-manifest.example.yaml +65 -0
  582. package/templates/task-definition-schema.md +99 -0
  583. package/tooling/README.md +20 -0
  584. package/tooling/src/adapters/context-mode.js +50 -0
  585. package/tooling/src/capture/command.js +376 -0
  586. package/tooling/src/capture/store.js +99 -0
  587. package/tooling/src/capture/usage.js +270 -0
  588. package/tooling/src/checks/branches.js +50 -0
  589. package/tooling/src/checks/brand-truth.js +110 -0
  590. package/tooling/src/checks/changelog.js +231 -0
  591. package/tooling/src/checks/command-registry.js +36 -0
  592. package/tooling/src/checks/commits.js +102 -0
  593. package/tooling/src/checks/docs-drift.js +103 -0
  594. package/tooling/src/checks/docs-truth.js +201 -0
  595. package/tooling/src/checks/runtime-surface.js +156 -0
  596. package/tooling/src/cli.js +116 -0
  597. package/tooling/src/command-options.js +56 -0
  598. package/tooling/src/commands/validate.js +320 -0
  599. package/tooling/src/doctor/command.js +91 -0
  600. package/tooling/src/export/command.js +77 -0
  601. package/tooling/src/export/compiler.js +498 -0
  602. package/tooling/src/guards/loop-cap-guard.js +52 -0
  603. package/tooling/src/guards/protected-path-write-guard.js +67 -0
  604. package/tooling/src/index/command.js +152 -0
  605. package/tooling/src/index/storage.js +1061 -0
  606. package/tooling/src/index/summarizers.js +261 -0
  607. package/tooling/src/loaders.js +18 -0
  608. package/tooling/src/project-root.js +22 -0
  609. package/tooling/src/recall/command.js +225 -0
  610. package/tooling/src/schema-validator.js +30 -0
  611. package/tooling/src/state-root.js +40 -0
  612. package/tooling/src/status/command.js +71 -0
  613. package/wazir.manifest.yaml +135 -0
  614. package/workflows/README.md +19 -0
  615. package/workflows/author.md +42 -0
  616. package/workflows/clarify.md +38 -0
  617. package/workflows/design-review.md +46 -0
  618. package/workflows/design.md +44 -0
  619. package/workflows/discover.md +37 -0
  620. package/workflows/execute.md +48 -0
  621. package/workflows/learn.md +38 -0
  622. package/workflows/plan-review.md +42 -0
  623. package/workflows/plan.md +39 -0
  624. package/workflows/prepare-next.md +37 -0
  625. package/workflows/review.md +40 -0
  626. package/workflows/run-audit.md +41 -0
  627. package/workflows/spec-challenge.md +41 -0
  628. package/workflows/specify.md +38 -0
  629. package/workflows/verify.md +37 -0
@@ -0,0 +1,1401 @@
1
+ # Mobile iOS Security — Expertise Module
2
+
3
+ > This module equips AI agents with deep knowledge of iOS application security:
4
+ > threat landscape, platform security model, secure implementation patterns,
5
+ > vulnerability catalog, tooling, and compliance standards. All guidance targets
6
+ > iOS 16+ / Swift 5.9+ and reflects OWASP MASVS v2, OWASP Mobile Top 10 (2024),
7
+ > and Apple Platform Security Guide (January 2026 edition).
8
+
9
+ ---
10
+
11
+ ## 1. Threat Landscape
12
+
13
+ ### 1.1 iOS-Specific Attack Vectors
14
+
15
+ **Jailbreak Exploitation**
16
+ Jailbreaking removes iOS sandbox restrictions, granting root access and enabling
17
+ unsigned code execution. Tools like unc0ver, checkra1n, and Dopamine exploit
18
+ kernel vulnerabilities to disable code signing enforcement. On a jailbroken
19
+ device, attackers can inspect Keychain contents, hook Objective-C methods via
20
+ Cydia Substrate, bypass SSL pinning, and extract decrypted IPA binaries.
21
+
22
+ **Insecure Data Storage**
23
+ Data stored in UserDefaults, plist files, SQLite databases, or the app's
24
+ Documents directory without Data Protection is accessible via device backups,
25
+ forensic tools, or jailbroken file managers. Sensitive data in Core Data stores
26
+ without NSFileProtectionComplete can be read when the device is locked.
27
+
28
+ **IPC Attacks (URL Scheme Hijacking)**
29
+ Custom URL schemes lack ownership verification. Any app can register the same
30
+ scheme, leading to URL scheme hijacking where a malicious app intercepts
31
+ deep links meant for a legitimate app. Since Apple documentation states "if
32
+ more than one third-party app registers to handle the same URL scheme, there
33
+ is currently no process for determining which app will be given that scheme,"
34
+ this creates a race condition exploitable for credential theft and session
35
+ hijacking.
36
+
37
+ **Reverse Engineering**
38
+ Despite Mach-O binary compilation, iOS apps can be decrypted (using tools like
39
+ Clutch or frida-ios-dump), decompiled (Hopper, IDA Pro, Ghidra), and analyzed.
40
+ Hardcoded API keys, encryption keys, and business logic become exposed.
41
+ Objective-C runtime metadata makes method swizzling trivial; pure Swift is
42
+ harder to instrument but not immune.
43
+
44
+ **Side-Loading Risks (EU DMA)**
45
+ Since iOS 17.4 (March 2024), the EU Digital Markets Act requires Apple to allow
46
+ alternative app marketplaces and sideloading. Apps distributed outside the App
47
+ Store undergo Apple Notarization (a baseline integrity check) but bypass the
48
+ full App Review process. This opens vectors for:
49
+ - Malware distribution through less-vetted marketplaces
50
+ - Modified apps with injected payloads
51
+ - Phishing apps mimicking legitimate services
52
+ - Reduced user trust signals compared to App Store verification
53
+
54
+ Source: Apple Newsroom, "Apple announces changes to iOS in the European Union"
55
+ (January 2024); Apple, "Complying with the DMA" developer documentation.
56
+
57
+ ### 1.2 Real-World Incidents
58
+
59
+ **NSO Pegasus / FORCEDENTRY (2021-2025)**
60
+ The FORCEDENTRY exploit chain (CVE-2021-30860) used a zero-click iMessage
61
+ vulnerability to deploy NSO Group's Pegasus spyware. It bypassed Apple's
62
+ BlastDoor sandbox by exploiting an integer overflow in CoreGraphics PDF
63
+ parsing. Google Project Zero called it "one of the most technically
64
+ sophisticated exploits ever seen." The exploit required zero user interaction —
65
+ receiving a crafted iMessage was sufficient for full device compromise.
66
+
67
+ In December 2024, a US court ruled NSO Group liable for hacking 1,400 WhatsApp
68
+ users. In May 2025, NSO was ordered to pay $167 million in damages.
69
+
70
+ Source: Citizen Lab, "BLASTPASS" (September 2023); Google Project Zero deep
71
+ dive (December 2021).
72
+
73
+ **BLASTPASS (September 2023)**
74
+ Another NSO exploit chain (CVE-2023-41064, CVE-2023-41061) used PassKit
75
+ attachments with malicious images to achieve zero-click code execution on
76
+ iOS 16.6. Apple patched in iOS 16.6.1 and introduced Lockdown Mode hardening.
77
+
78
+ **XcodeGhost Supply Chain Attack (2015)**
79
+ A trojanized Xcode IDE distributed through Chinese cloud services injected
80
+ malicious code into 2,500+ apps, affecting 128 million users. The malware
81
+ collected device info, prompted fake authentication dialogs, and hijacked URL
82
+ schemes. This incident led to OWASP Mobile Top 10 2024 elevating "Inadequate
83
+ Supply Chain Security" to M2.
84
+
85
+ Source: Palo Alto Networks Unit 42; Apple Epic v. Apple trial documents (2021).
86
+
87
+ **App Store Malware (Ongoing)**
88
+ Despite App Review, malware periodically reaches the App Store:
89
+ - 2024: Cryptocurrency drainer apps mimicking legitimate wallets
90
+ - 2023: VPN apps exfiltrating user data to unauthorized servers
91
+ - 2022: Fleeceware apps using misleading subscriptions
92
+ - Clipboard-reading apps exploiting pre-iOS 14 lack of paste notifications
93
+
94
+ Source: Kaspersky Mobile Threat Report 2024; Apple Transparency Report.
95
+
96
+ **Operation Triangulation (2023)**
97
+ Kaspersky discovered an advanced iOS attack chain exploiting four zero-day
98
+ vulnerabilities (including CVE-2023-41990 in the TrueType font processor).
99
+ The attack used invisible iMessage attachments to achieve code execution,
100
+ escalate privileges, and deploy spyware — all without user interaction.
101
+
102
+ Source: Kaspersky, "Operation Triangulation" (December 2023).
103
+
104
+ ---
105
+
106
+ ## 2. Core Security Principles
107
+
108
+ ### 2.1 iOS Security Model
109
+
110
+ **App Sandbox**
111
+ Every third-party iOS app runs in a sandboxed process with a unique filesystem
112
+ container. Apps cannot access other apps' data, system files, or hardware
113
+ directly. The sandbox enforces:
114
+ - Filesystem isolation (each app has private Documents, Library, tmp)
115
+ - IPC restrictions (only via system-mediated mechanisms)
116
+ - Hardware access gating (camera, microphone, location require entitlements)
117
+ - Network socket restrictions
118
+
119
+ **Code Signing**
120
+ All executable code on iOS must be signed by a trusted certificate:
121
+ - App Store apps: signed by Apple after review
122
+ - Enterprise apps: signed with enterprise distribution certificate
123
+ - Development: signed with developer certificate + provisioning profile
124
+ Runtime enforcement (via AMFI — Apple Mobile File Integrity) kills processes
125
+ with invalid signatures. This prevents code injection and unauthorized
126
+ binary modification at the kernel level.
127
+
128
+ **Entitlements**
129
+ Entitlements are key-value pairs embedded in the code signature that declare
130
+ app capabilities (push notifications, Keychain access groups, HealthKit, etc.).
131
+ Since they are cryptographically signed, they cannot be modified post-signing.
132
+ The kernel and system daemons check entitlements before granting access to
133
+ protected resources.
134
+
135
+ **Address Space Layout Randomization (ASLR)**
136
+ iOS randomizes the memory layout of processes at launch, making exploitation
137
+ of memory corruption vulnerabilities significantly harder. Combined with
138
+ Pointer Authentication Codes (PAC) on A12+ chips, this provides strong
139
+ runtime exploit mitigation.
140
+
141
+ ### 2.2 Data Protection API
142
+
143
+ iOS Data Protection encrypts files using per-file keys derived from the
144
+ device passcode and hardware UID. Four protection classes exist:
145
+
146
+ | Class | Constant | Availability | Use Case |
147
+ |-------|----------|--------------|----------|
148
+ | Complete Protection | `NSFileProtectionComplete` | Only when unlocked | Highly sensitive data (health, financial) |
149
+ | Complete Unless Open | `NSFileProtectionCompleteUnlessOpen` | Open files accessible while locked | Background file transfers |
150
+ | Until First Auth | `NSFileProtectionCompleteUntilFirstUserAuthentication` | After first unlock (default) | Data needed by background services |
151
+ | No Protection | `NSFileProtectionNone` | Always accessible | Non-sensitive cached data only |
152
+
153
+ **Best practice:** Set `NSFileProtectionComplete` as the default for the entire
154
+ app via the entitlements file, then downgrade individual files only when
155
+ background access is genuinely required.
156
+
157
+ ### 2.3 Keychain Services
158
+
159
+ The iOS Keychain provides hardware-backed encrypted storage for small secrets
160
+ (passwords, tokens, keys). Items are encrypted using AES-256-GCM with keys
161
+ derived from the Secure Enclave.
162
+
163
+ **Keychain Accessibility Classes:**
164
+
165
+ | Class | Constant | Security Level |
166
+ |-------|----------|----------------|
167
+ | When Passcode Set, This Device | `kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` | Highest — requires passcode; no backup migration |
168
+ | When Unlocked, This Device | `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` | High — no backup migration |
169
+ | When Unlocked | `kSecAttrAccessibleWhenUnlocked` | Medium — migrates to new device via backup |
170
+ | After First Unlock, This Device | `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly` | Lower — accessible while locked after boot |
171
+ | After First Unlock | `kSecAttrAccessibleAfterFirstUnlock` | Lowest recommended — background access + migration |
172
+
173
+ **Best practice:** Use `kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` for
174
+ authentication tokens and sensitive credentials. This ensures the item is
175
+ only accessible when the device has a passcode set, is unlocked, and cannot
176
+ be extracted via backup or device migration.
177
+
178
+ ### 2.4 App Transport Security (ATS)
179
+
180
+ ATS enforces HTTPS for all network connections made via URLSession. Since
181
+ iOS 9, ATS is enabled by default and requires:
182
+ - TLS 1.2 or later
183
+ - Forward secrecy cipher suites (ECDHE)
184
+ - Certificates with SHA-256+ signatures and RSA 2048+ / ECC 256+ keys
185
+
186
+ ATS exceptions must be declared in Info.plist and are scrutinized during
187
+ App Review. Apple rejects apps with `NSAllowsArbitraryLoads = YES` without
188
+ valid justification.
189
+
190
+ ### 2.5 Certificate Pinning
191
+
192
+ Certificate pinning restricts which TLS certificates the app trusts beyond
193
+ the system trust store. Two approaches:
194
+
195
+ - **Public key pinning:** Pin the Subject Public Key Info (SPKI) hash.
196
+ Survives certificate rotation if the same key pair is reused.
197
+ - **Certificate pinning:** Pin the full leaf or intermediate certificate.
198
+ Requires app update when certificates rotate.
199
+
200
+ Apple's recommendation: Pin CA public keys rather than leaf certificates, and
201
+ always include a backup pin. iOS requires at least two SPKI hashes when using
202
+ the Info.plist-based `NSPinnedDomains` configuration.
203
+
204
+ ### 2.6 Biometric Authentication
205
+
206
+ Face ID and Touch ID are mediated by the Secure Enclave, which stores
207
+ biometric templates in encrypted form inaccessible to the application
208
+ processor. The LocalAuthentication framework provides:
209
+
210
+ - `LAContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics)` —
211
+ biometric-only verification
212
+ - `LAContext.evaluatePolicy(.deviceOwnerAuthentication)` — biometric with
213
+ device passcode fallback
214
+
215
+ **Critical principle:** Biometric checks alone are a UX convenience, not a
216
+ security boundary. True security requires binding Keychain items to biometric
217
+ access controls so the Secure Enclave gates key release:
218
+
219
+ ```
220
+ Access control flag: .biometryCurrentSet + .privateKeyUsage
221
+ ```
222
+
223
+ This ensures that if biometric enrollment changes (e.g., new fingerprint
224
+ added), the Keychain item becomes inaccessible, forcing re-authentication.
225
+
226
+ ---
227
+
228
+ ## 3. Implementation Patterns
229
+
230
+ ### 3.1 Secure Keychain Wrapper (Swift)
231
+
232
+ ```swift
233
+ import Security
234
+ import Foundation
235
+
236
+ enum KeychainError: Error {
237
+ case duplicateItem
238
+ case itemNotFound
239
+ case unexpectedStatus(OSStatus)
240
+ case encodingError
241
+ }
242
+
243
+ struct KeychainManager {
244
+
245
+ // MARK: - Save
246
+
247
+ static func save(
248
+ key: String,
249
+ data: Data,
250
+ accessibility: CFString = kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
251
+ ) throws {
252
+ let query: [String: Any] = [
253
+ kSecClass as String: kSecClassGenericPassword,
254
+ kSecAttrAccount as String: key,
255
+ kSecValueData as String: data,
256
+ kSecAttrAccessible as String: accessibility
257
+ ]
258
+
259
+ let status = SecItemAdd(query as CFDictionary, nil)
260
+
261
+ switch status {
262
+ case errSecSuccess:
263
+ return
264
+ case errSecDuplicateItem:
265
+ // Update existing item
266
+ let updateQuery: [String: Any] = [
267
+ kSecClass as String: kSecClassGenericPassword,
268
+ kSecAttrAccount as String: key
269
+ ]
270
+ let updateAttributes: [String: Any] = [
271
+ kSecValueData as String: data,
272
+ kSecAttrAccessible as String: accessibility
273
+ ]
274
+ let updateStatus = SecItemUpdate(
275
+ updateQuery as CFDictionary,
276
+ updateAttributes as CFDictionary
277
+ )
278
+ guard updateStatus == errSecSuccess else {
279
+ throw KeychainError.unexpectedStatus(updateStatus)
280
+ }
281
+ default:
282
+ throw KeychainError.unexpectedStatus(status)
283
+ }
284
+ }
285
+
286
+ // MARK: - Retrieve
287
+
288
+ static func retrieve(key: String) throws -> Data {
289
+ let query: [String: Any] = [
290
+ kSecClass as String: kSecClassGenericPassword,
291
+ kSecAttrAccount as String: key,
292
+ kSecReturnData as String: true,
293
+ kSecMatchLimit as String: kSecMatchLimitOne
294
+ ]
295
+
296
+ var result: AnyObject?
297
+ let status = SecItemCopyMatching(query as CFDictionary, &result)
298
+
299
+ guard status == errSecSuccess, let data = result as? Data else {
300
+ if status == errSecItemNotFound {
301
+ throw KeychainError.itemNotFound
302
+ }
303
+ throw KeychainError.unexpectedStatus(status)
304
+ }
305
+ return data
306
+ }
307
+
308
+ // MARK: - Delete
309
+
310
+ static func delete(key: String) throws {
311
+ let query: [String: Any] = [
312
+ kSecClass as String: kSecClassGenericPassword,
313
+ kSecAttrAccount as String: key
314
+ ]
315
+ let status = SecItemDelete(query as CFDictionary)
316
+ guard status == errSecSuccess || status == errSecItemNotFound else {
317
+ throw KeychainError.unexpectedStatus(status)
318
+ }
319
+ }
320
+ }
321
+ ```
322
+
323
+ ### 3.2 Biometric-Protected Keychain Item
324
+
325
+ ```swift
326
+ import Security
327
+ import LocalAuthentication
328
+
329
+ func saveBiometricProtectedToken(_ token: Data, account: String) throws {
330
+ let access = SecAccessControlCreateWithFlags(
331
+ kCFAllocatorDefault,
332
+ kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
333
+ [.biometryCurrentSet, .privateKeyUsage],
334
+ nil
335
+ )
336
+
337
+ guard let accessControl = access else {
338
+ throw KeychainError.unexpectedStatus(errSecParam)
339
+ }
340
+
341
+ let context = LAContext()
342
+ context.touchIDAuthenticationAllowableReuseDuration = 0 // Force fresh auth
343
+
344
+ let query: [String: Any] = [
345
+ kSecClass as String: kSecClassGenericPassword,
346
+ kSecAttrAccount as String: account,
347
+ kSecValueData as String: token,
348
+ kSecAttrAccessControl as String: accessControl,
349
+ kSecUseAuthenticationContext as String: context
350
+ ]
351
+
352
+ let status = SecItemAdd(query as CFDictionary, nil)
353
+ guard status == errSecSuccess else {
354
+ throw KeychainError.unexpectedStatus(status)
355
+ }
356
+ }
357
+
358
+ func retrieveBiometricProtectedToken(account: String) throws -> Data {
359
+ let context = LAContext()
360
+ context.localizedReason = "Authenticate to access your secure token"
361
+
362
+ let query: [String: Any] = [
363
+ kSecClass as String: kSecClassGenericPassword,
364
+ kSecAttrAccount as String: account,
365
+ kSecReturnData as String: true,
366
+ kSecMatchLimit as String: kSecMatchLimitOne,
367
+ kSecUseAuthenticationContext as String: context
368
+ ]
369
+
370
+ var result: AnyObject?
371
+ let status = SecItemCopyMatching(query as CFDictionary, &result)
372
+
373
+ guard status == errSecSuccess, let data = result as? Data else {
374
+ throw KeychainError.unexpectedStatus(status)
375
+ }
376
+ return data
377
+ }
378
+ ```
379
+
380
+ ### 3.3 Certificate Pinning (URLSession)
381
+
382
+ ```swift
383
+ import Foundation
384
+ import CryptoKit
385
+
386
+ class PinnedSessionDelegate: NSObject, URLSessionDelegate {
387
+
388
+ // SHA-256 hashes of Subject Public Key Info (SPKI)
389
+ private let pinnedHashes: Set<String> = [
390
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", // Primary
391
+ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=" // Backup
392
+ ]
393
+
394
+ func urlSession(
395
+ _ session: URLSession,
396
+ didReceive challenge: URLAuthenticationChallenge,
397
+ completionHandler: @escaping (
398
+ URLSession.AuthChallengeDisposition, URLCredential?
399
+ ) -> Void
400
+ ) {
401
+ guard challenge.protectionSpace.authenticationMethod
402
+ == NSURLAuthenticationMethodServerTrust,
403
+ let serverTrust = challenge.protectionSpace.serverTrust
404
+ else {
405
+ completionHandler(.cancelAuthenticationChallenge, nil)
406
+ return
407
+ }
408
+
409
+ // Evaluate standard trust
410
+ var error: CFError?
411
+ guard SecTrustEvaluateWithError(serverTrust, &error) else {
412
+ completionHandler(.cancelAuthenticationChallenge, nil)
413
+ return
414
+ }
415
+
416
+ // Extract and verify public key hash
417
+ guard let serverCertificate = SecTrustGetCertificateAtIndex(
418
+ serverTrust, 0
419
+ ) else {
420
+ completionHandler(.cancelAuthenticationChallenge, nil)
421
+ return
422
+ }
423
+
424
+ guard let serverPublicKey = SecCertificateCopyKey(serverCertificate),
425
+ let serverPublicKeyData = SecKeyCopyExternalRepresentation(
426
+ serverPublicKey, nil
427
+ ) as Data?
428
+ else {
429
+ completionHandler(.cancelAuthenticationChallenge, nil)
430
+ return
431
+ }
432
+
433
+ let hash = SHA256.hash(data: serverPublicKeyData)
434
+ let hashBase64 = Data(hash).base64EncodedString()
435
+
436
+ if pinnedHashes.contains(hashBase64) {
437
+ completionHandler(
438
+ .useCredential,
439
+ URLCredential(trust: serverTrust)
440
+ )
441
+ } else {
442
+ completionHandler(.cancelAuthenticationChallenge, nil)
443
+ }
444
+ }
445
+ }
446
+
447
+ // Usage
448
+ let session = URLSession(
449
+ configuration: .default,
450
+ delegate: PinnedSessionDelegate(),
451
+ delegateQueue: nil
452
+ )
453
+ ```
454
+
455
+ **Info.plist Alternative (NSPinnedDomains — iOS 14+):**
456
+ ```xml
457
+ <key>NSAppTransportSecurity</key>
458
+ <dict>
459
+ <key>NSPinnedDomains</key>
460
+ <dict>
461
+ <key>api.example.com</key>
462
+ <dict>
463
+ <key>NSIncludesSubdomains</key>
464
+ <true/>
465
+ <key>NSPinnedCAIdentity</key>
466
+ <array>
467
+ <dict>
468
+ <key>SPKI-SHA256-BASE64</key>
469
+ <string>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</string>
470
+ </dict>
471
+ <dict>
472
+ <key>SPKI-SHA256-BASE64</key>
473
+ <string>BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=</string>
474
+ </dict>
475
+ </array>
476
+ </dict>
477
+ </dict>
478
+ </dict>
479
+ ```
480
+
481
+ ### 3.4 Secure WKWebView Configuration
482
+
483
+ ```swift
484
+ import WebKit
485
+
486
+ func createSecureWebView() -> WKWebView {
487
+ let config = WKWebViewConfiguration()
488
+ let prefs = WKWebpagePreferences()
489
+
490
+ // Disable JavaScript unless explicitly needed
491
+ prefs.allowsContentJavaScript = false
492
+ config.defaultWebpagePreferences = prefs
493
+
494
+ // Prevent file:// access
495
+ config.preferences.setValue(false, forKey: "allowFileAccessFromFileURLs")
496
+
497
+ // Disable universal file access
498
+ config.preferences.setValue(
499
+ false, forKey: "allowUniversalAccessFromFileURLs"
500
+ )
501
+
502
+ // Restrict media playback
503
+ config.allowsInlineMediaPlayback = false
504
+ config.mediaTypesRequiringUserActionForPlayback = .all
505
+
506
+ let webView = WKWebView(frame: .zero, configuration: config)
507
+
508
+ // Set navigation delegate for URL validation
509
+ webView.navigationDelegate = self
510
+ return webView
511
+ }
512
+
513
+ // MARK: - WKNavigationDelegate — URL allowlisting
514
+
515
+ extension SecureWebViewController: WKNavigationDelegate {
516
+ func webView(
517
+ _ webView: WKWebView,
518
+ decidePolicyFor navigationAction: WKNavigationAction,
519
+ decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
520
+ ) {
521
+ guard let url = navigationAction.request.url,
522
+ let scheme = url.scheme,
523
+ ["https"].contains(scheme),
524
+ allowedHosts.contains(url.host ?? "")
525
+ else {
526
+ decisionHandler(.cancel)
527
+ return
528
+ }
529
+ decisionHandler(.allow)
530
+ }
531
+ }
532
+ ```
533
+
534
+ ### 3.5 Jailbreak Detection
535
+
536
+ ```swift
537
+ import Foundation
538
+ import UIKit
539
+ import Darwin
540
+
541
+ struct JailbreakDetector {
542
+
543
+ static func isJailbroken() -> Bool {
544
+ #if targetEnvironment(simulator)
545
+ return false
546
+ #else
547
+ return checkSuspiciousPaths()
548
+ || checkSuspiciousURLSchemes()
549
+ || checkWriteOutsideSandbox()
550
+ || checkFork()
551
+ || checkDylibs()
552
+ #endif
553
+ }
554
+
555
+ // MARK: - Check 1: Suspicious file paths
556
+
557
+ private static func checkSuspiciousPaths() -> Bool {
558
+ let paths = [
559
+ "/Applications/Cydia.app",
560
+ "/Applications/Sileo.app",
561
+ "/Applications/Zebra.app",
562
+ "/Library/MobileSubstrate/MobileSubstrate.dylib",
563
+ "/usr/sbin/sshd",
564
+ "/usr/bin/ssh",
565
+ "/etc/apt",
566
+ "/var/lib/cydia",
567
+ "/private/var/stash",
568
+ "/usr/libexec/cydia",
569
+ "/var/jb" // rootless jailbreak path
570
+ ]
571
+ return paths.contains { FileManager.default.fileExists(atPath: $0) }
572
+ }
573
+
574
+ // MARK: - Check 2: URL schemes for jailbreak tools
575
+
576
+ private static func checkSuspiciousURLSchemes() -> Bool {
577
+ let schemes = [
578
+ "cydia://package/com.example",
579
+ "sileo://package/com.example",
580
+ "zbra://packages/com.example",
581
+ "filza://view"
582
+ ]
583
+ return schemes.contains { urlString in
584
+ guard let url = URL(string: urlString) else { return false }
585
+ return UIApplication.shared.canOpenURL(url)
586
+ }
587
+ }
588
+
589
+ // MARK: - Check 3: Write outside sandbox
590
+
591
+ private static func checkWriteOutsideSandbox() -> Bool {
592
+ let testPath = "/private/jailbreak_test_\(UUID().uuidString)"
593
+ do {
594
+ try "test".write(
595
+ toFile: testPath,
596
+ atomically: true,
597
+ encoding: .utf8
598
+ )
599
+ try FileManager.default.removeItem(atPath: testPath)
600
+ return true // Should not succeed on non-jailbroken device
601
+ } catch {
602
+ return false
603
+ }
604
+ }
605
+
606
+ // MARK: - Check 4: Fork availability
607
+
608
+ private static func checkFork() -> Bool {
609
+ let pid = fork()
610
+ if pid >= 0 {
611
+ // fork succeeded — jailbroken (sandbox should prevent fork)
612
+ if pid > 0 { kill(pid, SIGTERM) }
613
+ return true
614
+ }
615
+ return false
616
+ }
617
+
618
+ // MARK: - Check 5: Suspicious dynamic libraries
619
+
620
+ private static func checkDylibs() -> Bool {
621
+ let suspiciousLibs = [
622
+ "SubstrateLoader", "SSLKillSwitch", "MobileSubstrate",
623
+ "TweakInject", "CydiaSubstrate", "FridaGadget",
624
+ "libcycript", "frida-agent"
625
+ ]
626
+ let count = _dyld_image_count()
627
+ for i in 0..<count {
628
+ guard let name = _dyld_get_image_name(i) else { continue }
629
+ let imageName = String(cString: name)
630
+ if suspiciousLibs.contains(where: { imageName.contains($0) }) {
631
+ return true
632
+ }
633
+ }
634
+ return false
635
+ }
636
+ }
637
+ ```
638
+
639
+ **Important caveat:** All client-side jailbreak detection can be bypassed by a
640
+ determined attacker (e.g., using Liberty Lite, Shadow, or A-Bypass). Jailbreak
641
+ detection raises the cost of attack but is not a security guarantee. Critical
642
+ security decisions should be validated server-side.
643
+
644
+ ### 3.6 App Attest / DeviceCheck
645
+
646
+ ```swift
647
+ import DeviceCheck
648
+
649
+ // MARK: - App Attest (iOS 14+)
650
+
651
+ func attestKey() async throws -> String {
652
+ let service = DCAppAttestService.shared
653
+
654
+ guard service.isSupported else {
655
+ throw AppAttestError.unsupported
656
+ }
657
+
658
+ // Generate a new cryptographic key
659
+ let keyId = try await service.generateKey()
660
+
661
+ // Create attestation with server-generated challenge
662
+ let challenge = try await fetchChallengeFromServer()
663
+ let challengeHash = Data(SHA256.hash(data: challenge))
664
+ let attestation = try await service.attestKey(
665
+ keyId, clientDataHash: challengeHash
666
+ )
667
+
668
+ // Send attestation to server for verification
669
+ try await sendAttestationToServer(
670
+ keyId: keyId,
671
+ attestation: attestation
672
+ )
673
+ return keyId
674
+ }
675
+
676
+ // MARK: - Assert Request Integrity
677
+
678
+ func assertRequest(
679
+ keyId: String, requestData: Data
680
+ ) async throws -> Data {
681
+ let service = DCAppAttestService.shared
682
+ let requestHash = Data(SHA256.hash(data: requestData))
683
+ let assertion = try await service.generateAssertion(
684
+ keyId, clientDataHash: requestHash
685
+ )
686
+ return assertion
687
+ }
688
+
689
+ // MARK: - DeviceCheck (per-device flags)
690
+
691
+ func setDeviceFlag() async throws {
692
+ let device = DCDevice.current
693
+
694
+ guard device.isSupported else { return }
695
+
696
+ let token = try await device.generateToken()
697
+ // Send token to your server; server calls Apple's API
698
+ // to query/update two bits of per-device state
699
+ try await sendDeviceTokenToServer(token)
700
+ }
701
+ ```
702
+
703
+ ### 3.7 Secure Enclave Key Generation
704
+
705
+ ```swift
706
+ import Security
707
+ import CryptoKit
708
+
709
+ func generateSecureEnclaveKey(tag: String) throws -> SecKey {
710
+ let access = SecAccessControlCreateWithFlags(
711
+ kCFAllocatorDefault,
712
+ kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
713
+ [.privateKeyUsage, .biometryCurrentSet],
714
+ nil
715
+ )!
716
+
717
+ let attributes: [String: Any] = [
718
+ kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
719
+ kSecAttrKeySizeInBits as String: 256,
720
+ kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave,
721
+ kSecPrivateKeyAttrs as String: [
722
+ kSecAttrIsPermanent as String: true,
723
+ kSecAttrApplicationTag as String: tag.data(using: .utf8)!,
724
+ kSecAttrAccessControl as String: access
725
+ ]
726
+ ]
727
+
728
+ var error: Unmanaged<CFError>?
729
+ guard let privateKey = SecKeyCreateRandomKey(
730
+ attributes as CFDictionary, &error
731
+ ) else {
732
+ throw error!.takeRetainedValue() as Error
733
+ }
734
+ return privateKey
735
+ }
736
+
737
+ // Sign data with Secure Enclave key
738
+ func signWithSecureEnclave(key: SecKey, data: Data) throws -> Data {
739
+ var error: Unmanaged<CFError>?
740
+ guard let signature = SecKeyCreateSignature(
741
+ key,
742
+ .ecdsaSignatureMessageX962SHA256,
743
+ data as CFData,
744
+ &error
745
+ ) as Data? else {
746
+ throw error!.takeRetainedValue() as Error
747
+ }
748
+ return signature
749
+ }
750
+ ```
751
+
752
+ ---
753
+
754
+ ## 4. Vulnerability Catalog
755
+
756
+ ### V01: Sensitive Data in UserDefaults
757
+ - **Risk:** UserDefaults stores data in plaintext plist files within the app
758
+ sandbox. Accessible via device backups, forensic extraction, or jailbreak.
759
+ - **Impact:** Exposure of tokens, PII, session identifiers.
760
+ - **Fix:** Store secrets in Keychain with appropriate accessibility class.
761
+ - **MASVS:** MASVS-STORAGE
762
+
763
+ ### V02: Screenshots Exposing Sensitive Data
764
+ - **Risk:** iOS captures a screenshot when the app enters background
765
+ (for the app switcher). Sensitive screens (banking, health data) are
766
+ stored as images in the app sandbox.
767
+ - **Impact:** Visual exposure of confidential information.
768
+ - **Fix:** Implement `applicationWillResignActive` to overlay a blur or
769
+ placeholder view. Use `UITextField.isSecureTextEntry` for sensitive fields.
770
+ - **MASVS:** MASVS-STORAGE
771
+
772
+ ### V03: Pasteboard / Clipboard Leaks
773
+ - **Risk:** Data copied to `UIPasteboard.general` is accessible to all apps.
774
+ Pre-iOS 14, clipboard reads were silent. Research by Mysk (2020) documented
775
+ dozens of popular apps silently reading clipboard contents.
776
+ - **Impact:** Credential theft, location tracking via photo GPS metadata.
777
+ - **Fix:** Use app-specific `UIPasteboard(name:create:)` for internal copy.
778
+ Mark items as `localOnly` and set expiration. For sensitive fields, disable
779
+ copy via `UIMenuController` customization.
780
+ - **MASVS:** MASVS-STORAGE, MASVS-PRIVACY
781
+
782
+ ### V04: Insecure IPC via Custom URL Schemes
783
+ - **Risk:** URL scheme hijacking (see Section 1.1). Sensitive data passed
784
+ via URL query parameters is logged in system logs and accessible to
785
+ intercepting apps.
786
+ - **Impact:** Authentication token theft, session hijacking.
787
+ - **Fix:** Migrate to Universal Links (HTTPS-based, verified via
788
+ apple-app-site-association file). If URL schemes are required, validate
789
+ the `sourceApplication` parameter and never pass secrets in URLs.
790
+ - **MASVS:** MASVS-PLATFORM
791
+
792
+ ### V05: Missing or Misconfigured ATS
793
+ - **Risk:** `NSAllowsArbitraryLoads = YES` disables ATS globally,
794
+ permitting plaintext HTTP. Per-domain exceptions
795
+ (`NSExceptionAllowsInsecureHTTPLoads`) weaken specific connections.
796
+ - **Impact:** Man-in-the-middle attacks, credential interception.
797
+ - **Fix:** Remove all ATS exceptions. If exceptions are required (e.g.,
798
+ third-party CDN), use the narrowest scope (`NSExceptionDomains` with
799
+ specific domains). Apple App Review scrutinizes blanket ATS exemptions.
800
+ - **MASVS:** MASVS-NETWORK
801
+
802
+ ### V06: Weak Keychain Accessibility
803
+ - **Risk:** Using `kSecAttrAccessibleAlways` (deprecated) or
804
+ `kSecAttrAccessibleAfterFirstUnlock` makes Keychain items accessible
805
+ when the device is locked and extractable via backups.
806
+ - **Impact:** Token theft from device backups or locked-device attacks.
807
+ - **Fix:** Use `kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` for
808
+ credentials. Add `kSecAttrAccessControl` with `.biometryCurrentSet`
809
+ for high-value secrets.
810
+ - **MASVS:** MASVS-STORAGE
811
+
812
+ ### V07: Missing Jailbreak Detection
813
+ - **Risk:** Jailbroken devices bypass sandbox, code signing, and Data
814
+ Protection. Apps running on jailbroken devices are vulnerable to
815
+ runtime manipulation, Keychain dumping, and method hooking.
816
+ - **Impact:** Complete compromise of client-side security controls.
817
+ - **Fix:** Implement layered jailbreak detection (Section 3.5). Combine
818
+ with server-side risk scoring. For high-security apps, refuse to
819
+ operate on jailbroken devices.
820
+ - **MASVS:** MASVS-RESILIENCE
821
+
822
+ ### V08: Debug Logging in Production
823
+ - **Risk:** `NSLog`, `print`, and `os_log` output is readable via
824
+ Console.app on connected Mac or via syslog on jailbroken devices.
825
+ Sensitive data (tokens, user input, API responses) in logs leaks
826
+ to anyone with device access.
827
+ - **Impact:** Credential exposure, PII leakage.
828
+ - **Fix:** Use a logging framework with log levels (os_log with
829
+ `.private` redaction). Wrap sensitive logging in `#if DEBUG`.
830
+ Strip NSLog calls in release builds via compiler flags.
831
+ - **MASVS:** MASVS-STORAGE
832
+
833
+ ### V09: Hardcoded Secrets and API Keys
834
+ - **Risk:** API keys, encryption keys, and credentials embedded in
835
+ source code are extractable via binary analysis (strings, class-dump,
836
+ Hopper). Even obfuscation only slows extraction.
837
+ - **Impact:** Backend compromise, unauthorized API access.
838
+ - **Fix:** Fetch secrets from a secure backend at runtime. Use
839
+ configuration endpoints with App Attest. For required embedded keys,
840
+ use xcconfig files excluded from VCS and obfuscation.
841
+ - **MASVS:** MASVS-CRYPTO, MASVS-RESILIENCE
842
+
843
+ ### V10: Insecure WebView Configuration
844
+ - **Risk:** WKWebView with JavaScript enabled and permissive file access
845
+ can be exploited for cross-site scripting, local file exfiltration,
846
+ or JavaScript bridge abuse.
847
+ - **Impact:** Data theft, phishing within app context.
848
+ - **Fix:** Follow Section 3.4 pattern. Restrict to HTTPS URLs.
849
+ Implement Content Security Policy headers. Use
850
+ `WKScriptMessageHandler` with strict input validation for
851
+ JavaScript-to-native bridges.
852
+ - **MASVS:** MASVS-PLATFORM
853
+
854
+ ### V11: Insufficient Certificate Validation
855
+ - **Risk:** Not implementing certificate pinning allows MITM attacks
856
+ with rogue certificates (e.g., corporate proxy, compromised CA).
857
+ Trusting self-signed certificates in production bypasses the entire
858
+ TLS trust model.
859
+ - **Impact:** Complete interception of API traffic.
860
+ - **Fix:** Implement SPKI pinning (Section 3.3) or use NSPinnedDomains.
861
+ Never override `URLAuthenticationChallenge` to blindly trust all
862
+ certificates in production builds.
863
+ - **MASVS:** MASVS-NETWORK
864
+
865
+ ### V12: Unprotected Biometric Authentication
866
+ - **Risk:** Using `evaluatePolicy` alone without Keychain access
867
+ control provides only a boolean result that can be bypassed via
868
+ method swizzling or Frida hooking (`LAContext.evaluatePolicy` → true).
869
+ - **Impact:** Authentication bypass on jailbroken or instrumented devices.
870
+ - **Fix:** Bind Keychain items to biometric access control (Section 3.2)
871
+ so the Secure Enclave gates key release. Never rely solely on the
872
+ boolean result of `evaluatePolicy`.
873
+ - **MASVS:** MASVS-AUTH
874
+
875
+ ### V13: Improper Credential Storage
876
+ - **Risk:** Storing OAuth tokens in app files, Core Data, or Realm
877
+ without encryption. Using symmetric encryption with hardcoded keys.
878
+ - **Impact:** Token theft, account takeover.
879
+ - **Fix:** Store all credentials in Keychain. Use refresh token rotation.
880
+ Implement token binding to device identity via App Attest.
881
+ - **MASVS:** MASVS-STORAGE, MASVS-AUTH
882
+
883
+ ### V14: Missing Binary Protections
884
+ - **Risk:** Without obfuscation, stripped symbols, and anti-tampering
885
+ checks, the app binary is easily reverse-engineered. Attackers can
886
+ patch logic, disable security checks, or clone the app.
887
+ - **Impact:** IP theft, circumvention of licensing/payment logic.
888
+ - **Fix:** Enable bitcode. Strip debug symbols in release. Use
889
+ commercial obfuscators (SwiftShield, iXGuard). Implement integrity
890
+ checks on binary hash at runtime. Use App Attest for server-side
891
+ app integrity verification.
892
+ - **MASVS:** MASVS-RESILIENCE
893
+
894
+ ### V15: Insecure Backup Data
895
+ - **Risk:** iTunes/Finder backups include app sandbox contents.
896
+ Unencrypted backups on a computer expose all files without Data
897
+ Protection. iCloud backup may include Keychain items with permissive
898
+ accessibility.
899
+ - **Impact:** Offline extraction of app data and credentials.
900
+ - **Fix:** Exclude sensitive files with
901
+ `URLResourceValues.isExcludedFromBackup = true`. Use
902
+ `ThisDeviceOnly` Keychain accessibility. Apply NSFileProtectionComplete
903
+ to sensitive files.
904
+ - **MASVS:** MASVS-STORAGE
905
+
906
+ ---
907
+
908
+ ## 5. Security Checklist
909
+
910
+ ### Data Protection
911
+ - [ ] All secrets stored in Keychain (never UserDefaults, plist, or files)
912
+ - [ ] Keychain items use `kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly`
913
+ - [ ] NSFileProtectionComplete set as default file protection level
914
+ - [ ] Sensitive files excluded from device backups
915
+ - [ ] Background screenshot protection implemented (blur/placeholder)
916
+ - [ ] Pasteboard usage restricted (local-only, expiring, or disabled)
917
+ - [ ] No sensitive data in debug/production logs
918
+
919
+ ### Network Security
920
+ - [ ] ATS enabled with no blanket exceptions
921
+ - [ ] Certificate pinning implemented for critical API endpoints
922
+ - [ ] At least two SPKI pins configured (primary + backup)
923
+ - [ ] Certificate rotation plan documented and tested
924
+ - [ ] No hardcoded API endpoints — use server-driven configuration
925
+
926
+ ### Authentication
927
+ - [ ] Biometric auth bound to Keychain access controls (not boolean-only)
928
+ - [ ] Session tokens use short expiry with refresh token rotation
929
+ - [ ] OAuth PKCE flow for authorization code exchange
930
+ - [ ] Re-authentication required for sensitive operations
931
+ - [ ] Face ID usage description present in Info.plist
932
+
933
+ ### Platform Security
934
+ - [ ] Universal Links preferred over custom URL schemes
935
+ - [ ] URL scheme handlers validate `sourceApplication`
936
+ - [ ] WKWebView configured with minimal privileges (JS disabled if unused)
937
+ - [ ] WebView navigation restricted to allowlisted HTTPS domains
938
+ - [ ] Inter-app data sharing uses App Groups with minimal scope
939
+
940
+ ### Binary Protection
941
+ - [ ] Jailbreak detection implemented with multiple checks
942
+ - [ ] Debug detection (ptrace anti-attach) in release builds
943
+ - [ ] App Attest / DeviceCheck integrated for server-side integrity
944
+ - [ ] Debug symbols stripped from release binaries
945
+ - [ ] No hardcoded secrets in source code or binaries
946
+
947
+ ### Build & Release
948
+ - [ ] Xcode "Validate App" run before every submission
949
+ - [ ] Compiler stack protector enabled (`-fstack-protector-all`)
950
+ - [ ] Position Independent Executable (PIE) enabled (default for iOS)
951
+ - [ ] Automatic Reference Counting (ARC) enabled (prevents use-after-free)
952
+ - [ ] Third-party dependencies audited and version-pinned
953
+ - [ ] SBOM generated for supply chain tracking
954
+
955
+ ---
956
+
957
+ ## 6. Tools & Automation
958
+
959
+ ### Static Analysis
960
+
961
+ | Tool | Purpose | Integration |
962
+ |------|---------|-------------|
963
+ | **Semgrep** (with Swift rules) | SAST for Swift — detects insecure storage, missing pinning, hardcoded secrets | CI/CD pipeline, pre-commit hooks |
964
+ | **SwiftLint** | Code style + custom security rules | Xcode build phase, CI |
965
+ | **DeepSource** | Automated code review with Swift security analyzers | GitHub/GitLab integration |
966
+ | **Snyk** | Dependency vulnerability scanning (CocoaPods, SPM) | CI/CD, IDE plugin |
967
+ | **Xcode Analyzer** | Static analysis built into Xcode (Cmd+Shift+B with analysis) | IDE-integrated |
968
+
969
+ ### Dynamic Analysis
970
+
971
+ | Tool | Purpose | Requirement |
972
+ |------|---------|-------------|
973
+ | **MobSF** | Automated static + dynamic analysis of IPA files | Docker or local install |
974
+ | **Frida** | Dynamic instrumentation — hook functions, bypass checks, inspect runtime | Jailbroken device or Frida gadget injection |
975
+ | **Objection** | Runtime exploration powered by Frida — Keychain dump, SSL bypass, jailbreak bypass | Jailbroken device recommended |
976
+ | **Burp Suite** | HTTP/S traffic interception and manipulation | Proxy configuration |
977
+ | **Charles Proxy** | HTTPS debugging proxy with SSL proxying | Certificate trust on device |
978
+
979
+ ### Apple-Provided Tools
980
+
981
+ | Tool | Purpose |
982
+ |------|---------|
983
+ | **Xcode Instruments** | Memory leak detection, performance profiling, network inspection |
984
+ | **App Attest** | Cryptographic device/app integrity verification |
985
+ | **DeviceCheck** | Per-device state flags (2 bits) persisted by Apple |
986
+ | **Xcode Organizer** | Crash reports, energy diagnostics, disk usage |
987
+ | **Managed App Configuration** | MDM-based secure configuration delivery |
988
+
989
+ ### Recommended CI/CD Security Pipeline
990
+
991
+ ```
992
+ Build → SwiftLint → Semgrep SAST → Snyk SCA → Unit Tests
993
+ → Archive IPA → MobSF Static Scan → App Attest Integration Test
994
+ → TestFlight / App Store Connect
995
+ ```
996
+
997
+ ---
998
+
999
+ ## 7. Platform-Specific Guidance
1000
+
1001
+ ### 7.1 Swift Security Patterns
1002
+
1003
+ **Value Types Over Reference Types:**
1004
+ Prefer structs for sensitive data models. Value types are stack-allocated
1005
+ (short-lived in memory) and copied on assignment, reducing the window for
1006
+ memory inspection attacks compared to heap-allocated class instances.
1007
+
1008
+ **Access Control:**
1009
+ Use `private` and `fileprivate` aggressively for security-sensitive
1010
+ properties. Mark security classes as `final` to prevent subclass overrides.
1011
+
1012
+ **Secure String Handling:**
1013
+ ```swift
1014
+ // INSECURE: String persists in memory
1015
+ let password = "secret123"
1016
+
1017
+ // SECURE: Use Data, zero out after use
1018
+ var sensitiveData = "secret123".data(using: .utf8)!
1019
+ defer {
1020
+ sensitiveData.resetBytes(in: 0..<sensitiveData.count)
1021
+ }
1022
+ // Use sensitiveData for authentication, then it is zeroed
1023
+ ```
1024
+
1025
+ **Result Type for Security Operations:**
1026
+ ```swift
1027
+ enum AuthResult {
1028
+ case authenticated(token: String)
1029
+ case biometricFailed(LAError)
1030
+ case keychainError(OSStatus)
1031
+ case jailbreakDetected
1032
+ }
1033
+ // Exhaustive switch forces handling all security-relevant outcomes
1034
+ ```
1035
+
1036
+ ### 7.2 SwiftUI Security
1037
+
1038
+ **Redacted Content in App Switcher:**
1039
+ ```swift
1040
+ struct ContentView: View {
1041
+ @Environment(\.scenePhase) var scenePhase
1042
+ @State private var isBlurred = false
1043
+
1044
+ var body: some View {
1045
+ SensitiveContentView()
1046
+ .blur(radius: isBlurred ? 30 : 0)
1047
+ .onChange(of: scenePhase) { _, newPhase in
1048
+ isBlurred = (newPhase != .active)
1049
+ }
1050
+ }
1051
+ }
1052
+ ```
1053
+
1054
+ **Secure Text Input:**
1055
+ ```swift
1056
+ SecureField("Password", text: $password)
1057
+ .textContentType(.password)
1058
+ .autocorrectionDisabled()
1059
+ .textInputAutocapitalization(.never)
1060
+ ```
1061
+
1062
+ **Preventing Screenshot Capture (iOS 17+):**
1063
+ ```swift
1064
+ // Leverage UITextField.isSecureTextEntry behavior
1065
+ // by embedding a secure text field technique in SwiftUI
1066
+ struct ScreenshotProtectedView<Content: View>: UIViewRepresentable {
1067
+ let content: Content
1068
+
1069
+ func makeUIView(context: Context) -> UIView {
1070
+ let secureField = UITextField()
1071
+ secureField.isSecureTextEntry = true
1072
+ // The secure field's layer prevents screenshots
1073
+ let containerView = secureField.layer.sublayers?.first?.delegate
1074
+ as? UIView ?? UIView()
1075
+ return containerView
1076
+ }
1077
+ }
1078
+ ```
1079
+
1080
+ ### 7.3 UIKit Security
1081
+
1082
+ **Secure View Controller Lifecycle:**
1083
+ ```swift
1084
+ class SecureViewController: UIViewController {
1085
+ private let blurView = UIVisualEffectView(
1086
+ effect: UIBlurEffect(style: .systemUltraThinMaterial)
1087
+ )
1088
+
1089
+ override func viewDidLoad() {
1090
+ super.viewDidLoad()
1091
+ NotificationCenter.default.addObserver(
1092
+ self,
1093
+ selector: #selector(willResignActive),
1094
+ name: UIApplication.willResignActiveNotification,
1095
+ object: nil
1096
+ )
1097
+ NotificationCenter.default.addObserver(
1098
+ self,
1099
+ selector: #selector(didBecomeActive),
1100
+ name: UIApplication.didBecomeActiveNotification,
1101
+ object: nil
1102
+ )
1103
+ }
1104
+
1105
+ @objc private func willResignActive() {
1106
+ blurView.frame = view.bounds
1107
+ view.addSubview(blurView)
1108
+ }
1109
+
1110
+ @objc private func didBecomeActive() {
1111
+ blurView.removeFromSuperview()
1112
+ }
1113
+ }
1114
+ ```
1115
+
1116
+ ### 7.4 Xcode Build Settings for Security
1117
+
1118
+ | Setting | Value | Purpose |
1119
+ |---------|-------|---------|
1120
+ | `ENABLE_BITCODE` | `YES` (deprecated iOS 16+) | App thinning, additional optimization |
1121
+ | `GCC_GENERATE_DEBUGGING_SYMBOLS` | `NO` (Release) | Strip debug symbols |
1122
+ | `STRIP_INSTALLED_PRODUCT` | `YES` | Remove symbol tables from release binary |
1123
+ | `DEPLOYMENT_POSTPROCESSING` | `YES` | Enable post-processing including stripping |
1124
+ | `DEBUG_INFORMATION_FORMAT` | `dwarf` (Release) | No dSYM in final binary |
1125
+ | `GCC_PREPROCESSOR_DEFINITIONS` | `NDEBUG=1` (Release) | Disable assert() in release |
1126
+ | `SWIFT_OPTIMIZATION_LEVEL` | `-O` or `-Osize` | Optimized code, harder to reverse-engineer |
1127
+ | `ENABLE_TESTABILITY` | `NO` (Release) | Prevent internal access from test bundles |
1128
+ | `OTHER_LDFLAGS` | `-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null` | Mark binary as restricted (anti-DYLD_INSERT) |
1129
+
1130
+ ### 7.5 App Store Review Security Requirements
1131
+
1132
+ Apple App Review enforces these security requirements:
1133
+ - **ATS compliance:** Justified exceptions only; blanket disabling rejected
1134
+ - **Privacy manifest:** Required since Spring 2024 for apps using tracking
1135
+ APIs, required reason APIs (UserDefaults timestamps, file attributes, etc.)
1136
+ - **Privacy nutrition labels:** Accurate data collection declarations
1137
+ - **Login with Apple:** Required if app offers third-party social login
1138
+ - **Minimum permissions:** Camera, location, contacts — must justify each
1139
+ - **Data deletion:** Apps collecting user data must offer account deletion
1140
+ - **Encryption declarations:** Export compliance documentation for custom crypto
1141
+
1142
+ ---
1143
+
1144
+ ## 8. Incident Patterns
1145
+
1146
+ ### 8.1 Data Leak Detection
1147
+
1148
+ **Indicators of data exposure:**
1149
+ - Unexplained increase in account takeover attempts
1150
+ - User reports of personalized phishing targeting app-specific data
1151
+ - API traffic from unexpected geographic locations or device profiles
1152
+ - Anomalous Keychain access patterns in security logs
1153
+ - Backup files appearing on unauthorized services
1154
+
1155
+ **Investigation steps:**
1156
+ 1. Enable App Attest to verify app integrity on API requests
1157
+ 2. Check server logs for requests missing valid attestation assertions
1158
+ 3. Audit Keychain accessibility classes in production builds
1159
+ 4. Review Data Protection levels on all files in app sandbox
1160
+ 5. Scan for sensitive data in device backups using iMazing or
1161
+ libimobiledevice tools
1162
+ 6. Check if debug logging was inadvertently enabled in release
1163
+
1164
+ ### 8.2 Unauthorized Access via IPC
1165
+
1166
+ **Attack scenario:** Malicious app registers the same URL scheme as the
1167
+ target app, intercepting OAuth callbacks containing authorization codes.
1168
+
1169
+ **Detection:**
1170
+ - Monitor for duplicate URL scheme registrations on user devices
1171
+ - Server-side correlation of authorization code redemption with expected
1172
+ redirect URIs (Universal Links eliminate this attack)
1173
+ - App Attest-based client identity verification
1174
+
1175
+ **Response:**
1176
+ 1. Immediately migrate from custom URL schemes to Universal Links
1177
+ 2. Invalidate all active sessions / tokens issued during compromise window
1178
+ 3. Implement PKCE (which binds the authorization code to the requesting app)
1179
+ 4. Deploy App Attest for API authentication
1180
+ 5. Notify affected users and require password reset
1181
+
1182
+ ### 8.3 Jailbreak-Based Exploitation Response
1183
+
1184
+ **Detection signals:**
1185
+ - Server receives requests from apps with tampered signatures
1186
+ - App Attest assertions fail validation
1187
+ - Unusual API call patterns (automated scraping, rate limit violations)
1188
+
1189
+ **Response:**
1190
+ 1. Flag device via DeviceCheck (set fraud bit)
1191
+ 2. Restrict access from flagged devices (read-only, degraded functionality)
1192
+ 3. Require step-up authentication for sensitive operations
1193
+ 4. Log and analyze the attack patterns for future detection rules
1194
+ 5. Consider reporting to Apple if it involves App Store policy violations
1195
+
1196
+ ---
1197
+
1198
+ ## 9. Compliance & Standards
1199
+
1200
+ ### 9.1 OWASP MASVS v2 (2023-2024)
1201
+
1202
+ The Mobile Application Security Verification Standard defines eight control
1203
+ categories. Key requirements for iOS:
1204
+
1205
+ | Category | Key Controls |
1206
+ |----------|--------------|
1207
+ | **MASVS-STORAGE** | No sensitive data in logs, backups, clipboard; Keychain for secrets; Data Protection on files |
1208
+ | **MASVS-CRYPTO** | No hardcoded keys; use platform crypto (CryptoKit, Security.framework); minimum AES-256 |
1209
+ | **MASVS-AUTH** | Biometric bound to Keychain; session management server-side; re-auth for sensitive ops |
1210
+ | **MASVS-NETWORK** | TLS 1.2+; certificate pinning; no cleartext HTTP; ATS enforced |
1211
+ | **MASVS-PLATFORM** | Universal Links over URL schemes; secure WebView; input validation on IPC |
1212
+ | **MASVS-CODE** | Dependency management; no debug code in release; stack canaries; binary integrity |
1213
+ | **MASVS-RESILIENCE** | Jailbreak detection; anti-debugging; obfuscation; App Attest |
1214
+ | **MASVS-PRIVACY** | Privacy manifest; minimal data collection; consent management; data deletion |
1215
+
1216
+ Source: https://mas.owasp.org/MASVS/
1217
+
1218
+ ### 9.2 OWASP Mobile Top 10 (2024)
1219
+
1220
+ | # | Risk | iOS Relevance |
1221
+ |---|------|---------------|
1222
+ | M1 | Improper Credential Usage | Hardcoded keys, insecure Keychain accessibility |
1223
+ | M2 | Inadequate Supply Chain Security | Untrusted CocoaPods/SPM dependencies, XcodeGhost-type attacks |
1224
+ | M3 | Insecure Authentication/Authorization | Boolean-only biometric checks, missing server-side validation |
1225
+ | M4 | Insufficient Input/Output Validation | WebView JavaScript injection, URL scheme parameter injection |
1226
+ | M5 | Insecure Communication | Missing ATS, no certificate pinning, cleartext fallback |
1227
+ | M6 | Inadequate Privacy Controls | Excessive permissions, missing privacy manifest, tracking without consent |
1228
+ | M7 | Insufficient Binary Protections | No obfuscation, debug symbols in release, no integrity checks |
1229
+ | M8 | Security Misconfiguration | ATS exceptions, permissive entitlements, debug flags |
1230
+ | M9 | Insecure Data Storage | UserDefaults for secrets, unprotected SQLite, background screenshots |
1231
+ | M10 | Insufficient Cryptography | Custom crypto implementations, weak algorithms, hardcoded IVs |
1232
+
1233
+ Source: https://owasp.org/www-project-mobile-top-10/
1234
+
1235
+ ### 9.3 Apple Platform Security Guide
1236
+
1237
+ Apple publishes the Apple Platform Security guide (updated January 2026),
1238
+ covering:
1239
+ - Hardware security (Secure Enclave, Secure Boot, hardware key storage)
1240
+ - System security (kernel integrity protection, signed system volume)
1241
+ - Data protection (per-file encryption, Keychain architecture)
1242
+ - App security (code signing, sandboxing, entitlements)
1243
+ - Network security (ATS, VPN, Wi-Fi security)
1244
+ - Biometric security (Face ID / Touch ID architecture)
1245
+
1246
+ Source: https://support.apple.com/guide/security/welcome/web
1247
+
1248
+ ### 9.4 Regulatory Compliance
1249
+
1250
+ | Regulation | iOS Requirements |
1251
+ |-----------|------------------|
1252
+ | **GDPR** | Privacy manifest, data minimization, right to deletion, consent before tracking |
1253
+ | **CCPA/CPRA** | Opt-out of data sale, data access/deletion API, privacy policy |
1254
+ | **HIPAA** | NSFileProtectionComplete, encrypted Keychain, audit logging, BAA with Apple |
1255
+ | **PCI DSS** | No card data in logs/screenshots, encrypted storage, certificate pinning |
1256
+ | **SOC 2** | Access controls, encryption at rest and in transit, incident response |
1257
+
1258
+ ---
1259
+
1260
+ ## 10. Insecure vs. Secure Code Examples
1261
+
1262
+ ### Example 1: Token Storage
1263
+
1264
+ ```swift
1265
+ // INSECURE — token in UserDefaults (plaintext plist)
1266
+ UserDefaults.standard.set(authToken, forKey: "auth_token")
1267
+ let token = UserDefaults.standard.string(forKey: "auth_token")
1268
+
1269
+ // SECURE — token in Keychain with strong protection
1270
+ try KeychainManager.save(
1271
+ key: "auth_token",
1272
+ data: authToken.data(using: .utf8)!,
1273
+ accessibility: kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
1274
+ )
1275
+ let tokenData = try KeychainManager.retrieve(key: "auth_token")
1276
+ ```
1277
+
1278
+ ### Example 2: Network Request
1279
+
1280
+ ```swift
1281
+ // INSECURE — HTTP, no pinning, ATS disabled
1282
+ // Info.plist: NSAllowsArbitraryLoads = YES
1283
+ let url = URL(string: "http://api.example.com/login")!
1284
+ URLSession.shared.dataTask(with: url) { data, _, _ in
1285
+ // Process response
1286
+ }
1287
+
1288
+ // SECURE — HTTPS, pinned session, ATS enforced
1289
+ let url = URL(string: "https://api.example.com/login")!
1290
+ let session = URLSession(
1291
+ configuration: .default,
1292
+ delegate: PinnedSessionDelegate(),
1293
+ delegateQueue: nil
1294
+ )
1295
+ session.dataTask(with: url) { data, response, error in
1296
+ guard let httpResponse = response as? HTTPURLResponse,
1297
+ (200...299).contains(httpResponse.statusCode)
1298
+ else { return }
1299
+ // Process response
1300
+ }
1301
+ ```
1302
+
1303
+ ### Example 3: Biometric Authentication
1304
+
1305
+ ```swift
1306
+ // INSECURE — boolean-only check, bypassable via Frida
1307
+ let context = LAContext()
1308
+ context.evaluatePolicy(
1309
+ .deviceOwnerAuthenticationWithBiometrics,
1310
+ localizedReason: "Authenticate"
1311
+ ) { success, error in
1312
+ if success {
1313
+ self.grantAccess() // Attacker hooks this to always execute
1314
+ }
1315
+ }
1316
+
1317
+ // SECURE — biometric gates Keychain key release via Secure Enclave
1318
+ do {
1319
+ let tokenData = try retrieveBiometricProtectedToken(
1320
+ account: "session_token"
1321
+ )
1322
+ // Token only available after successful biometric verification
1323
+ // by the Secure Enclave — cannot be bypassed by hooking
1324
+ grantAccess(with: tokenData)
1325
+ } catch {
1326
+ handleAuthenticationFailure(error)
1327
+ }
1328
+ ```
1329
+
1330
+ ### Example 4: Logging
1331
+
1332
+ ```swift
1333
+ // INSECURE — sensitive data in production logs
1334
+ NSLog("User login: email=\(email), token=\(authToken)")
1335
+ print("API Response: \(responseBody)")
1336
+
1337
+ // SECURE — private redaction, debug-only logging
1338
+ import os.log
1339
+
1340
+ private let logger = Logger(
1341
+ subsystem: Bundle.main.bundleIdentifier!,
1342
+ category: "auth"
1343
+ )
1344
+
1345
+ logger.info("User login: email=\(email, privacy: .private)")
1346
+ #if DEBUG
1347
+ logger.debug("API Response: \(responseBody, privacy: .private)")
1348
+ #endif
1349
+ ```
1350
+
1351
+ ### Example 5: Deep Linking
1352
+
1353
+ ```swift
1354
+ // INSECURE — custom URL scheme with sensitive data
1355
+ // myapp://auth?token=eyJhbGciOiJIUzI1NiIs...
1356
+ func application(
1357
+ _ app: UIApplication,
1358
+ open url: URL,
1359
+ options: [UIApplication.OpenURLOptionsKey: Any]
1360
+ ) -> Bool {
1361
+ let token = url.queryParameters["token"] // Token exposed in URL
1362
+ authenticate(with: token)
1363
+ return true
1364
+ }
1365
+
1366
+ // SECURE — Universal Links with server-side validation
1367
+ // https://example.com/auth/callback?code=TEMP_CODE
1368
+ func application(
1369
+ _ application: UIApplication,
1370
+ continue userActivity: NSUserActivity,
1371
+ restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
1372
+ ) -> Bool {
1373
+ guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
1374
+ let url = userActivity.webpageURL,
1375
+ url.host == "example.com"
1376
+ else { return false }
1377
+
1378
+ // Exchange temporary code for token server-side (PKCE)
1379
+ let code = url.queryParameters["code"]
1380
+ exchangeCodeForToken(code, codeVerifier: storedCodeVerifier)
1381
+ return true
1382
+ }
1383
+ ```
1384
+
1385
+ ---
1386
+
1387
+ ## References
1388
+
1389
+ - OWASP Mobile Top 10 (2024): https://owasp.org/www-project-mobile-top-10/
1390
+ - OWASP MASVS v2: https://mas.owasp.org/MASVS/
1391
+ - OWASP MASTG: https://mas.owasp.org/MASTG/
1392
+ - Apple Platform Security Guide: https://support.apple.com/guide/security/welcome/web
1393
+ - Apple Developer — App Attest: https://developer.apple.com/documentation/devicecheck
1394
+ - Apple Developer — Keychain Services: https://developer.apple.com/documentation/security/keychain_services
1395
+ - Apple Developer — LocalAuthentication: https://developer.apple.com/documentation/localauthentication
1396
+ - Apple Developer — Certificate Pinning: https://developer.apple.com/news/?id=g9ejcf8y
1397
+ - Google Project Zero — NSO Zero-Click: https://projectzero.google/2021/12/a-deep-dive-into-nso-zero-click.html
1398
+ - Citizen Lab — BLASTPASS: https://citizenlab.ca/2023/09/blastpass-nso-group-iphone-zero-click-zero-day-exploit-captured-in-the-wild/
1399
+ - NowSecure — Keychain Best Practices: https://books.nowsecure.com/secure-mobile-development/en/ios/use-the-keychain-carefully.html
1400
+ - HackTricks — iOS Pentesting: https://book.hacktricks.xyz/mobile-pentesting/ios-pentesting
1401
+ - MobSF: https://github.com/MobSF/Mobile-Security-Framework-MobSF