@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,1101 @@
1
+ # Session Management Security
2
+
3
+ > Expertise module for AI agents implementing secure session handling.
4
+ > Sources: OWASP Session Management Cheat Sheet, NIST SP 800-63B, PCI-DSS 4.0, CWE/CVE databases, PortSwigger research, vendor advisories (2024-2026).
5
+
6
+ ---
7
+
8
+ ## 1. Threat Landscape
9
+
10
+ ### 1.1 Attack Categories
11
+
12
+ | Attack | Description | Prevalence |
13
+ |--------|-------------|------------|
14
+ | Session Hijacking | Attacker steals a valid session token and replays it to impersonate the victim | Critical — rising sharply with infostealer malware |
15
+ | Session Fixation | Attacker sets a known session ID before the victim authenticates, then reuses it | High — CVE-2024-7341 (Keycloak), CVE-2024-38513 (GoFiber) |
16
+ | Session Prediction | Attacker guesses or brute-forces session IDs due to weak entropy | Medium — still found in custom frameworks |
17
+ | Cookie Theft via XSS | Injected script reads `document.cookie` and exfiltrates session tokens | Critical — primary vector when HttpOnly is missing |
18
+ | CSRF via Weak Session Config | Cross-site requests ride on ambient cookies lacking SameSite protection | High — mitigated by SameSite=Lax default in modern browsers |
19
+ | Token Replay (MFA Bypass) | Stolen session tokens bypass MFA because authentication already completed | Critical — 17 billion stolen cookie records recaptured from dark web in 2024 |
20
+
21
+ ### 1.2 Real-World Breaches
22
+
23
+ **Chrome Extension Supply Chain Attack (December 2024):**
24
+ Attackers injected malicious code into legitimate Chrome browser extensions used by enterprises for social media advertising. The compromised extensions exfiltrated browser cookies and session tokens during a 25-hour window, granting attackers access to authenticated sessions on Facebook Ads and AI platforms. Multiple companies were affected before the extensions were revoked.
25
+
26
+ **Keycloak SAML Session Fixation (CVE-2024-7341):**
27
+ Keycloak's SAML adapter failed to rotate the session ID at login time. An attacker who obtained a pre-authentication session cookie could wait for the victim to authenticate, then reuse the same cookie to access the victim's authenticated session. Affected all Keycloak versions using SAML adapters until patched.
28
+
29
+ **GoFiber Session Fixation (CVE-2024-38513):**
30
+ GoFiber versions prior to 2.52.5 allowed attackers to supply arbitrary `session_id` values. Because the framework accepted attacker-controlled session identifiers without regeneration, authenticated sessions could be hijacked after a victim logged in with the attacker-supplied ID.
31
+
32
+ **Ivanti EPM Stored XSS to Session Hijacking (CVE-2025-10573, CVSS 9.6):**
33
+ Ivanti Endpoint Manager versions through 2024 SU4 allowed unauthenticated JavaScript injection. Attackers leveraged stored XSS to steal admin session cookies, escalating to full endpoint management control.
34
+
35
+ **Microsoft 365 & Okta Token Theft Campaigns (2024-2025):**
36
+ Adversary-in-the-middle (AiTM) phishing kits like EvilProxy and Evilginx captured session tokens after victims completed MFA. Stolen tokens were replayed from attacker infrastructure, bypassing conditional access policies. Multiple Fortune 500 companies reported unauthorized access to email and cloud resources.
37
+
38
+ ### 1.3 Trends
39
+
40
+ - **Infostealer malware dominance:** Lumma, RisePro, Vidar, Stealc, and RedLine shifted focus from password theft to session cookie/token exfiltration. Over 17 billion stolen cookie records were found on dark web markets in 2024.
41
+ - **Post-MFA session theft:** Attackers increasingly target the session layer because stealing a live session bypasses all authentication controls including MFA.
42
+ - **Identity-based hijacking:** Modern session hijacking is no longer network-based (sniffing). It is identity-based, performed over the public internet against cloud applications using stolen cookies, tokens, and session IDs.
43
+ - **Browser extension as attack vector:** Supply chain attacks on browser extensions provide direct access to cookies and session storage within the browser context.
44
+
45
+ ---
46
+
47
+ ## 2. Core Security Principles
48
+
49
+ ### 2.1 Session ID Entropy
50
+
51
+ Session identifiers MUST be cryptographically random and unpredictable.
52
+
53
+ - **Minimum 128 bits of entropy** (OWASP recommendation). This translates to at least 32 hexadecimal characters or 22 base64 characters.
54
+ - Use a CSPRNG (Cryptographically Secure Pseudo-Random Number Generator): `crypto.randomBytes()` in Node.js, `secrets.token_hex()` in Python, `SecureRandom` in Java.
55
+ - NEVER derive session IDs from user data (username, email, timestamp, sequential counters).
56
+ - NEVER expose session IDs in URLs, error messages, or logs.
57
+
58
+ ### 2.2 Secure Cookie Attributes
59
+
60
+ Every session cookie MUST set all of the following attributes:
61
+
62
+ | Attribute | Value | Purpose |
63
+ |-----------|-------|---------|
64
+ | `HttpOnly` | `true` | Prevents JavaScript access — blocks XSS-based cookie theft |
65
+ | `Secure` | `true` | Cookie transmitted only over HTTPS — blocks network sniffing |
66
+ | `SameSite` | `Strict` or `Lax` | Restricts cross-origin cookie sending — mitigates CSRF |
67
+ | `Path` | `/` (or narrowest scope) | Limits cookie scope to intended paths |
68
+ | `Domain` | Omit or set to exact domain | Prevents cookie leakage to subdomains when omitted |
69
+ | `Max-Age` / `Expires` | Set explicit value | Controls cookie lifetime — avoid persistent session cookies |
70
+
71
+ **SameSite values explained:**
72
+ - `Strict`: Cookie never sent on cross-site requests. Strongest protection but breaks legitimate cross-site navigation (e.g., links from email).
73
+ - `Lax` (browser default since Chrome 80): Cookie sent on top-level GET navigations from external sites but not on POST or subresource requests. Good balance for most applications.
74
+ - `None`: Cookie sent on all cross-site requests. Requires `Secure` flag. Only use when cross-origin cookie sharing is genuinely needed (e.g., embedded iframes, OAuth flows).
75
+
76
+ ### 2.3 Session Expiration
77
+
78
+ Implement both idle and absolute timeouts:
79
+
80
+ - **Idle timeout:** Destroy session after a period of inactivity (15 minutes for high-security systems per NIST SP 800-63B and PCI-DSS 4.0 Requirement 8.2.8; 30 minutes for general applications).
81
+ - **Absolute timeout:** Destroy session after a maximum lifetime regardless of activity (4-8 hours typical; 24 hours maximum for low-risk applications).
82
+ - **Server-side enforcement:** NEVER rely solely on cookie expiration. The server must track last-activity timestamps and reject expired sessions.
83
+
84
+ ### 2.4 Session Rotation on Auth State Change
85
+
86
+ Regenerate the session ID whenever the authentication or privilege state changes:
87
+
88
+ - On successful login (prevents session fixation).
89
+ - On privilege escalation (e.g., entering an admin panel).
90
+ - On password change or MFA enrollment.
91
+ - On any sensitive operation requiring re-authentication.
92
+
93
+ The old session ID must be invalidated server-side immediately after rotation.
94
+
95
+ ### 2.5 Server-Side Session Storage
96
+
97
+ - Store session data server-side (Redis, database, encrypted file store). The cookie should contain only the session ID.
98
+ - NEVER store sensitive data (roles, permissions, user attributes) solely in client-side cookies or tokens without server-side validation.
99
+ - Sign session cookies with HMAC to detect tampering (express-session does this by default with the `secret` option).
100
+
101
+ ---
102
+
103
+ ## 3. Implementation Patterns
104
+
105
+ ### 3.1 Server-Side Sessions with Express and Redis
106
+
107
+ ```typescript
108
+ // SECURE: Express session with Redis store
109
+ import express from 'express';
110
+ import session from 'express-session';
111
+ import { createClient } from 'redis';
112
+ import RedisStore from 'connect-redis';
113
+
114
+ const app = express();
115
+
116
+ const redisClient = createClient({
117
+ url: process.env.REDIS_URL,
118
+ socket: {
119
+ tls: true, // Encrypt Redis connection in production
120
+ rejectUnauthorized: true,
121
+ },
122
+ });
123
+ await redisClient.connect();
124
+
125
+ app.use(session({
126
+ store: new RedisStore({
127
+ client: redisClient,
128
+ prefix: 'sess:', // Namespace session keys
129
+ ttl: 1800, // 30 minutes server-side TTL
130
+ }),
131
+ name: '__Host-sid', // __Host- prefix enforces Secure + Path=/
132
+ secret: process.env.SESSION_SECRET, // Min 256-bit secret; rotate periodically
133
+ resave: false, // Do not save session if unmodified
134
+ saveUninitialized: false, // Do not create session until data stored
135
+ cookie: {
136
+ httpOnly: true,
137
+ secure: true, // HTTPS only
138
+ sameSite: 'lax',
139
+ maxAge: 1800000, // 30 minutes in milliseconds
140
+ path: '/',
141
+ domain: undefined, // Omit to restrict to exact origin
142
+ },
143
+ rolling: true, // Reset expiry on each request (idle timeout)
144
+ }));
145
+ ```
146
+
147
+ ### 3.2 Session Rotation on Login
148
+
149
+ ```typescript
150
+ // SECURE: Regenerate session ID after authentication
151
+ app.post('/login', async (req, res) => {
152
+ const user = await authenticate(req.body.email, req.body.password);
153
+ if (!user) {
154
+ return res.status(401).json({ error: 'Invalid credentials' });
155
+ }
156
+
157
+ // Regenerate session to prevent fixation attacks
158
+ req.session.regenerate((err) => {
159
+ if (err) {
160
+ return res.status(500).json({ error: 'Session error' });
161
+ }
162
+ req.session.userId = user.id;
163
+ req.session.role = user.role;
164
+ req.session.loginTime = Date.now(); // Track absolute timeout
165
+ req.session.lastActivity = Date.now(); // Track idle timeout
166
+
167
+ req.session.save((err) => {
168
+ if (err) {
169
+ return res.status(500).json({ error: 'Session save error' });
170
+ }
171
+ res.json({ message: 'Login successful' });
172
+ });
173
+ });
174
+ });
175
+ ```
176
+
177
+ ### 3.3 Session Rotation on Privilege Escalation
178
+
179
+ ```typescript
180
+ // SECURE: Rotate session before granting elevated privileges
181
+ app.post('/admin/elevate', requireAuth, async (req, res) => {
182
+ const verified = await verifyMFA(req.session.userId, req.body.mfaCode);
183
+ if (!verified) {
184
+ return res.status(403).json({ error: 'MFA verification failed' });
185
+ }
186
+
187
+ const oldSessionData = { ...req.session };
188
+ req.session.regenerate((err) => {
189
+ if (err) return res.status(500).json({ error: 'Session error' });
190
+
191
+ // Restore user data with elevated flag
192
+ req.session.userId = oldSessionData.userId;
193
+ req.session.role = oldSessionData.role;
194
+ req.session.isElevated = true;
195
+ req.session.elevatedAt = Date.now();
196
+ req.session.save(() => res.json({ message: 'Privileges elevated' }));
197
+ });
198
+ });
199
+ ```
200
+
201
+ ### 3.4 Concurrent Session Limits
202
+
203
+ ```typescript
204
+ // SECURE: Limit active sessions per user
205
+ const MAX_SESSIONS_PER_USER = 3;
206
+
207
+ async function enforceSessionLimit(userId: string, currentSessionId: string): Promise<void> {
208
+ const sessionKeys = await redisClient.keys(`sess:user:${userId}:*`);
209
+
210
+ if (sessionKeys.length >= MAX_SESSIONS_PER_USER) {
211
+ // Sort by creation time, remove oldest sessions
212
+ const sessions = await Promise.all(
213
+ sessionKeys.map(async (key) => ({
214
+ key,
215
+ data: JSON.parse(await redisClient.get(key) || '{}'),
216
+ }))
217
+ );
218
+ sessions.sort((a, b) => (a.data.loginTime || 0) - (b.data.loginTime || 0));
219
+
220
+ // Destroy oldest sessions exceeding the limit
221
+ const toRemove = sessions.slice(0, sessions.length - MAX_SESSIONS_PER_USER + 1);
222
+ for (const session of toRemove) {
223
+ if (session.key !== `sess:user:${userId}:${currentSessionId}`) {
224
+ await redisClient.del(session.key);
225
+ }
226
+ }
227
+ }
228
+
229
+ // Register current session
230
+ await redisClient.set(
231
+ `sess:user:${userId}:${currentSessionId}`,
232
+ JSON.stringify({ loginTime: Date.now() }),
233
+ { EX: 1800 }
234
+ );
235
+ }
236
+ ```
237
+
238
+ ### 3.5 Secure Remember-Me Implementation
239
+
240
+ ```typescript
241
+ // SECURE: Remember-me with separate long-lived token (NOT the session cookie)
242
+ import crypto from 'crypto';
243
+
244
+ interface RememberMeToken {
245
+ selector: string; // Lookup key (indexed, not secret)
246
+ validator: string; // Secret token (hashed in DB)
247
+ userId: string;
248
+ expiresAt: Date;
249
+ }
250
+
251
+ async function createRememberMeToken(userId: string): Promise<string> {
252
+ const selector = crypto.randomBytes(16).toString('hex');
253
+ const validator = crypto.randomBytes(32).toString('hex');
254
+ const hashedValidator = crypto
255
+ .createHash('sha256')
256
+ .update(validator)
257
+ .digest('hex');
258
+
259
+ await db.rememberMeTokens.create({
260
+ selector,
261
+ validator: hashedValidator, // Store HASH, not plaintext
262
+ userId,
263
+ expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
264
+ });
265
+
266
+ // Return selector:validator as cookie value
267
+ return `${selector}:${validator}`;
268
+ }
269
+
270
+ async function validateRememberMe(token: string): Promise<string | null> {
271
+ const [selector, validator] = token.split(':');
272
+ if (!selector || !validator) return null;
273
+
274
+ const record = await db.rememberMeTokens.findOne({
275
+ where: { selector, expiresAt: { $gt: new Date() } },
276
+ });
277
+ if (!record) return null;
278
+
279
+ const hashedValidator = crypto
280
+ .createHash('sha256')
281
+ .update(validator)
282
+ .digest('hex');
283
+
284
+ // Constant-time comparison to prevent timing attacks
285
+ if (!crypto.timingSafeEqual(
286
+ Buffer.from(hashedValidator),
287
+ Buffer.from(record.validator)
288
+ )) {
289
+ return null;
290
+ }
291
+
292
+ // Rotate the token on use (one-time use)
293
+ await db.rememberMeTokens.destroy({ where: { selector } });
294
+ return record.userId;
295
+ }
296
+ ```
297
+
298
+ ### 3.6 JWT as Sessions — Tradeoffs
299
+
300
+ JWTs are NOT recommended as session tokens for most web applications. Use them only when statelessness is a hard architectural requirement (e.g., microservices, cross-domain SSO).
301
+
302
+ | Aspect | Server-Side Sessions | JWT Sessions |
303
+ |--------|---------------------|--------------|
304
+ | Revocation | Immediate (delete from store) | Requires blocklist or short expiry |
305
+ | Scalability | Requires shared store (Redis) | Stateless — no shared store |
306
+ | Size | Small cookie (~32 bytes) | Large cookie (1-2 KB+) |
307
+ | Security | Server controls all data | Claims visible in Base64 payload |
308
+ | Logout | Instant invalidation | Token valid until expiry unless blocklisted |
309
+ | Replay | Detectable via server state | No built-in replay detection |
310
+
311
+ **If you must use JWTs:**
312
+ - Use short-lived access tokens (5-15 minutes).
313
+ - Implement refresh token rotation with one-time-use enforcement.
314
+ - Maintain a server-side blocklist for revocation (defeats the stateless benefit).
315
+ - Never store JWTs in `localStorage` (XSS-vulnerable). Use HttpOnly cookies.
316
+ - Validate signature, `iss`, `aud`, `exp`, and `nbf` claims on every request.
317
+ - Pin the algorithm server-side — never trust the `alg` header from the token.
318
+
319
+ ### 3.7 JWT Refresh Token Flow
320
+
321
+ ```typescript
322
+ // SECURE: JWT refresh token rotation
323
+ import jwt from 'jsonwebtoken';
324
+
325
+ const ACCESS_TOKEN_TTL = '15m';
326
+ const REFRESH_TOKEN_TTL = '7d';
327
+
328
+ async function issueTokenPair(userId: string): Promise<{
329
+ accessToken: string;
330
+ refreshToken: string;
331
+ }> {
332
+ const accessToken = jwt.sign(
333
+ { sub: userId, type: 'access' },
334
+ process.env.JWT_ACCESS_SECRET!,
335
+ {
336
+ expiresIn: ACCESS_TOKEN_TTL,
337
+ algorithm: 'RS256', // Asymmetric — use private key to sign
338
+ issuer: 'https://app.example.com',
339
+ audience: 'https://api.example.com',
340
+ }
341
+ );
342
+
343
+ const refreshTokenId = crypto.randomBytes(32).toString('hex');
344
+ const refreshToken = jwt.sign(
345
+ { sub: userId, jti: refreshTokenId, type: 'refresh' },
346
+ process.env.JWT_REFRESH_SECRET!,
347
+ { expiresIn: REFRESH_TOKEN_TTL, algorithm: 'RS256' }
348
+ );
349
+
350
+ // Store refresh token metadata server-side for rotation tracking
351
+ await db.refreshTokens.create({
352
+ id: refreshTokenId,
353
+ userId,
354
+ family: refreshTokenId, // Token family for rotation detection
355
+ expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
356
+ });
357
+
358
+ return { accessToken, refreshToken };
359
+ }
360
+
361
+ async function rotateRefreshToken(oldRefreshToken: string): Promise<{
362
+ accessToken: string;
363
+ refreshToken: string;
364
+ } | null> {
365
+ let payload: jwt.JwtPayload;
366
+ try {
367
+ payload = jwt.verify(oldRefreshToken, process.env.JWT_REFRESH_SECRET!, {
368
+ algorithms: ['RS256'], // Pin algorithm — reject HS256
369
+ issuer: 'https://app.example.com',
370
+ }) as jwt.JwtPayload;
371
+ } catch {
372
+ return null; // Invalid or expired token
373
+ }
374
+
375
+ const storedToken = await db.refreshTokens.findOne({
376
+ where: { id: payload.jti },
377
+ });
378
+
379
+ if (!storedToken) {
380
+ // Token reuse detected — possible theft. Revoke entire family.
381
+ await db.refreshTokens.destroy({
382
+ where: { family: payload.jti },
383
+ });
384
+ // Alert security team
385
+ await alertSecurityTeam('Refresh token reuse detected', {
386
+ userId: payload.sub,
387
+ tokenId: payload.jti,
388
+ });
389
+ return null;
390
+ }
391
+
392
+ // Invalidate old refresh token (one-time use)
393
+ await db.refreshTokens.destroy({ where: { id: payload.jti } });
394
+
395
+ // Issue new pair
396
+ return issueTokenPair(payload.sub as string);
397
+ }
398
+ ```
399
+
400
+ ### 3.8 Session Logout and Revocation
401
+
402
+ ```typescript
403
+ // SECURE: Complete session destruction
404
+ app.post('/logout', requireAuth, (req, res) => {
405
+ const sessionId = req.sessionID;
406
+
407
+ req.session.destroy((err) => {
408
+ if (err) {
409
+ return res.status(500).json({ error: 'Logout failed' });
410
+ }
411
+
412
+ // Clear the session cookie explicitly
413
+ res.clearCookie('__Host-sid', {
414
+ httpOnly: true,
415
+ secure: true,
416
+ sameSite: 'lax',
417
+ path: '/',
418
+ });
419
+
420
+ // Also remove remember-me cookie if present
421
+ res.clearCookie('remember_me', {
422
+ httpOnly: true,
423
+ secure: true,
424
+ sameSite: 'lax',
425
+ path: '/',
426
+ });
427
+
428
+ res.json({ message: 'Logged out' });
429
+ });
430
+ });
431
+
432
+ // SECURE: Revoke all sessions for a user (e.g., password change, account compromise)
433
+ async function revokeAllSessions(userId: string): Promise<void> {
434
+ const keys = await redisClient.keys(`sess:*`);
435
+ for (const key of keys) {
436
+ const data = await redisClient.get(key);
437
+ if (data) {
438
+ const session = JSON.parse(data);
439
+ if (session.userId === userId) {
440
+ await redisClient.del(key);
441
+ }
442
+ }
443
+ }
444
+ // Also revoke all refresh tokens
445
+ await db.refreshTokens.destroy({ where: { userId } });
446
+ // Also revoke all remember-me tokens
447
+ await db.rememberMeTokens.destroy({ where: { userId } });
448
+ }
449
+ ```
450
+
451
+ ---
452
+
453
+ ## 4. Vulnerability Catalog
454
+
455
+ ### V-01: Predictable Session IDs (CWE-330)
456
+ **Risk:** Session prediction / brute-force.
457
+ ```typescript
458
+ // VULNERABLE: Sequential or timestamp-based session IDs
459
+ const sessionId = `session_${Date.now()}_${counter++}`;
460
+
461
+ // SECURE: Cryptographically random session ID
462
+ import crypto from 'crypto';
463
+ const sessionId = crypto.randomBytes(32).toString('hex'); // 256-bit entropy
464
+ ```
465
+
466
+ ### V-02: Missing HttpOnly Flag (CWE-1004)
467
+ **Risk:** XSS-based cookie theft via `document.cookie`.
468
+ ```typescript
469
+ // VULNERABLE
470
+ res.cookie('sid', sessionId, { httpOnly: false });
471
+
472
+ // SECURE
473
+ res.cookie('sid', sessionId, { httpOnly: true, secure: true, sameSite: 'lax' });
474
+ ```
475
+
476
+ ### V-03: Missing Secure Flag (CWE-614)
477
+ **Risk:** Session cookie transmitted over HTTP, vulnerable to network sniffing.
478
+ ```typescript
479
+ // VULNERABLE: Cookie sent over HTTP
480
+ app.use(session({ cookie: { secure: false } }));
481
+
482
+ // SECURE: Cookie restricted to HTTPS
483
+ app.use(session({ cookie: { secure: true } }));
484
+ ```
485
+
486
+ ### V-04: Session Fixation — No Rotation on Login (CWE-384)
487
+ **Risk:** Attacker sets session ID before authentication, hijacks post-login session.
488
+ ```typescript
489
+ // VULNERABLE: No session regeneration after login
490
+ app.post('/login', (req, res) => {
491
+ const user = authenticate(req.body);
492
+ req.session.userId = user.id; // Same session ID as before login!
493
+ res.redirect('/dashboard');
494
+ });
495
+
496
+ // SECURE: Regenerate session on login
497
+ app.post('/login', (req, res) => {
498
+ const user = authenticate(req.body);
499
+ req.session.regenerate((err) => { // New session ID issued
500
+ req.session.userId = user.id;
501
+ req.session.save(() => res.redirect('/dashboard'));
502
+ });
503
+ });
504
+ ```
505
+
506
+ ### V-05: Session ID in URL (CWE-598)
507
+ **Risk:** Session ID leaked via Referer headers, browser history, proxy logs, shared links.
508
+ ```
509
+ // VULNERABLE
510
+ https://app.example.com/dashboard?sid=abc123def456
511
+
512
+ // SECURE: Session ID in HttpOnly cookie only — never in URL
513
+ ```
514
+
515
+ ### V-06: Overly Long Session Expiration (CWE-613)
516
+ **Risk:** Extended attack window for stolen session tokens.
517
+ ```typescript
518
+ // VULNERABLE: Session valid for 30 days with no idle timeout
519
+ app.use(session({ cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 } }));
520
+
521
+ // SECURE: 30-minute idle timeout + 8-hour absolute timeout
522
+ app.use(session({
523
+ cookie: { maxAge: 1800000 },
524
+ rolling: true,
525
+ }));
526
+ // Plus server-side absolute timeout check in middleware
527
+ ```
528
+
529
+ ### V-07: No Absolute Session Timeout (CWE-613)
530
+ **Risk:** Rolling idle timeout can be kept alive indefinitely by automated requests.
531
+ ```typescript
532
+ // VULNERABLE: Only idle timeout, no absolute limit
533
+ function checkSession(req, res, next) {
534
+ if (Date.now() - req.session.lastActivity > IDLE_TIMEOUT) {
535
+ return req.session.destroy(() => res.status(401).end());
536
+ }
537
+ req.session.lastActivity = Date.now();
538
+ next();
539
+ }
540
+
541
+ // SECURE: Both idle AND absolute timeout
542
+ function checkSession(req, res, next) {
543
+ const now = Date.now();
544
+ if (now - req.session.lastActivity > IDLE_TIMEOUT) {
545
+ return req.session.destroy(() => res.status(401).json({ error: 'Session expired' }));
546
+ }
547
+ if (now - req.session.loginTime > ABSOLUTE_TIMEOUT) {
548
+ return req.session.destroy(() => res.status(401).json({ error: 'Session expired' }));
549
+ }
550
+ req.session.lastActivity = now;
551
+ next();
552
+ }
553
+ ```
554
+
555
+ ### V-08: Insecure Remember-Me (CWE-640)
556
+ **Risk:** Remember-me token that is just a plaintext user ID or re-uses the session cookie.
557
+ ```typescript
558
+ // VULNERABLE: Predictable remember-me token
559
+ res.cookie('remember', Buffer.from(user.id).toString('base64'), {
560
+ maxAge: 30 * 24 * 60 * 60 * 1000,
561
+ });
562
+
563
+ // SECURE: Cryptographic selector:validator pattern with hashed storage
564
+ // (See section 3.5 for full implementation)
565
+ ```
566
+
567
+ ### V-09: JWT Without Revocation Mechanism (CWE-613)
568
+ **Risk:** Stolen JWT valid until expiry; no way to invalidate compromised tokens.
569
+ ```typescript
570
+ // VULNERABLE: Long-lived JWT with no revocation
571
+ const token = jwt.sign({ userId }, secret, { expiresIn: '30d' });
572
+
573
+ // SECURE: Short-lived access token + refresh rotation + server-side blocklist
574
+ const accessToken = jwt.sign({ sub: userId }, secret, { expiresIn: '15m' });
575
+ // Plus refresh token rotation (see section 3.7)
576
+ ```
577
+
578
+ ### V-10: Algorithm Confusion in JWT (CWE-327)
579
+ **Risk:** Attacker changes `alg` header from RS256 to HS256, signs with public key.
580
+ ```typescript
581
+ // VULNERABLE: Trusting the alg header from the token
582
+ const payload = jwt.verify(token, publicKey);
583
+
584
+ // SECURE: Pin algorithm server-side
585
+ const payload = jwt.verify(token, publicKey, { algorithms: ['RS256'] });
586
+ ```
587
+
588
+ ### V-11: Session Data in localStorage (CWE-922)
589
+ **Risk:** Any XSS vulnerability exposes all data in localStorage.
590
+ ```typescript
591
+ // VULNERABLE: Storing tokens in localStorage
592
+ localStorage.setItem('authToken', token);
593
+
594
+ // SECURE: Store in HttpOnly cookie (inaccessible to JavaScript)
595
+ // Or keep access token in memory only (cleared on tab close)
596
+ ```
597
+
598
+ ### V-12: Missing SameSite Attribute (CWE-1275)
599
+ **Risk:** Cookie sent with cross-site requests, enabling CSRF attacks.
600
+ ```typescript
601
+ // VULNERABLE (legacy browsers without SameSite default)
602
+ res.cookie('sid', sessionId, { httpOnly: true, secure: true });
603
+
604
+ // SECURE
605
+ res.cookie('sid', sessionId, { httpOnly: true, secure: true, sameSite: 'lax' });
606
+ ```
607
+
608
+ ### V-13: Insufficient Session Destruction on Logout (CWE-613)
609
+ **Risk:** Server-side session persists after user clicks logout.
610
+ ```typescript
611
+ // VULNERABLE: Clear cookie but leave server-side session intact
612
+ app.post('/logout', (req, res) => {
613
+ res.clearCookie('sid');
614
+ res.redirect('/login');
615
+ });
616
+
617
+ // SECURE: Destroy server-side session AND clear cookie
618
+ app.post('/logout', (req, res) => {
619
+ req.session.destroy(() => {
620
+ res.clearCookie('__Host-sid', {
621
+ httpOnly: true, secure: true, sameSite: 'lax', path: '/',
622
+ });
623
+ res.redirect('/login');
624
+ });
625
+ });
626
+ ```
627
+
628
+ ### V-14: No Concurrent Session Control (CWE-307)
629
+ **Risk:** Unlimited sessions allow undetected parallel use of stolen credentials.
630
+ ```
631
+ // VULNERABLE: No limit on active sessions per user
632
+
633
+ // SECURE: Track and limit active sessions (see section 3.4)
634
+ // Alert user when new session is created from unexpected location
635
+ ```
636
+
637
+ ### V-15: Session Cookie Without __Host- Prefix (CWE-784)
638
+ **Risk:** Cookie can be overwritten by subdomain or non-secure context.
639
+ ```typescript
640
+ // VULNERABLE: Regular cookie name
641
+ res.cookie('sid', value, { secure: true, path: '/' });
642
+
643
+ // SECURE: __Host- prefix enforces Secure + Path=/ + no Domain attribute
644
+ res.cookie('__Host-sid', value, { secure: true, path: '/', httpOnly: true });
645
+ ```
646
+
647
+ ---
648
+
649
+ ## 5. Security Checklist
650
+
651
+ ### Cookie Configuration
652
+ - [ ] `HttpOnly` flag set on all session cookies
653
+ - [ ] `Secure` flag set on all session cookies
654
+ - [ ] `SameSite` attribute set to `Strict` or `Lax`
655
+ - [ ] `__Host-` prefix used for session cookie name
656
+ - [ ] `Domain` attribute omitted (restricts to exact origin)
657
+ - [ ] `Path` set to narrowest required scope
658
+
659
+ ### Session ID Security
660
+ - [ ] Session IDs generated with CSPRNG (minimum 128-bit entropy)
661
+ - [ ] Session IDs never appear in URLs, logs, or error messages
662
+ - [ ] Session IDs are not derived from user data or timestamps
663
+ - [ ] Session cookie value is signed (HMAC) to detect tampering
664
+
665
+ ### Session Lifecycle
666
+ - [ ] Session ID regenerated on login (prevents fixation)
667
+ - [ ] Session ID regenerated on privilege escalation
668
+ - [ ] Session ID regenerated on password change
669
+ - [ ] Idle timeout enforced server-side (15-30 minutes)
670
+ - [ ] Absolute timeout enforced server-side (4-8 hours)
671
+ - [ ] Session fully destroyed on logout (server-side + cookie cleared)
672
+ - [ ] All sessions revoked on password change / account compromise
673
+
674
+ ### Session Storage
675
+ - [ ] Session data stored server-side (Redis, database) — not in cookies
676
+ - [ ] Redis connection encrypted with TLS in production
677
+ - [ ] Session store uses key prefix and dedicated database number
678
+ - [ ] Session secrets rotated periodically (support multiple secrets)
679
+
680
+ ### Concurrent Sessions & Monitoring
681
+ - [ ] Maximum concurrent sessions enforced per user
682
+ - [ ] Users notified of new session creation from new device/location
683
+ - [ ] Concurrent sessions from different IPs flagged for review
684
+ - [ ] Session creation/destruction events logged for audit
685
+
686
+ ### JWT-Specific (if applicable)
687
+ - [ ] Access token lifetime 15 minutes or less
688
+ - [ ] Refresh token rotation with one-time use
689
+ - [ ] Token family tracking for reuse detection
690
+ - [ ] Algorithm pinned server-side (`algorithms: ['RS256']`)
691
+ - [ ] All claims validated (`iss`, `aud`, `exp`, `nbf`, `sub`)
692
+ - [ ] JWTs stored in HttpOnly cookies, not localStorage
693
+ - [ ] Server-side blocklist for immediate revocation
694
+
695
+ ---
696
+
697
+ ## 6. Tools & Automation
698
+
699
+ ### 6.1 Session Token Analysis
700
+
701
+ | Tool | Purpose | Usage |
702
+ |------|---------|-------|
703
+ | **Burp Suite Sequencer** | Analyze randomness/entropy of session tokens | Capture tokens via Proxy, send to Sequencer, run statistical analysis (FIPS tests, character-level analysis) |
704
+ | **Burp Suite Intruder** | Test session fixation and rotation | Replay pre-auth session IDs post-login to verify regeneration |
705
+ | **Burp Suite Repeater** | Manipulate and replay session cookies | Modify cookie attributes, test logout effectiveness |
706
+
707
+ ### 6.2 Cookie Security Scanners
708
+
709
+ | Tool | Purpose | Command / URL |
710
+ |------|---------|---------------|
711
+ | **Mozilla Observatory** | Scan cookie and header security | `observatory.mozilla.org` or CLI: `observatory <domain>` |
712
+ | **SecurityHeaders.com** | Check response headers including Set-Cookie | `securityheaders.com/?q=<domain>` |
713
+ | **CookieServe** | Analyze cookie attributes for a domain | `cookieserve.com` |
714
+ | **curl** | Manual cookie attribute inspection | `curl -I -v https://example.com/login 2>&1 \| grep -i set-cookie` |
715
+
716
+ ### 6.3 Automated Security Testing
717
+
718
+ | Tool | Purpose | Notes |
719
+ |------|---------|-------|
720
+ | **OWASP ZAP** | Automated session management testing | Session management scanner, cookie checks, active scan rules |
721
+ | **Nikto** | Web server scanner | Checks for session-related misconfigurations |
722
+ | **testssl.sh** | TLS configuration testing | Verifies HTTPS enforcement for Secure cookies |
723
+ | **eslint-plugin-security** | Static analysis for Node.js | Flags insecure cookie configurations in code |
724
+ | **semgrep** | Custom rules for session patterns | Write rules to detect missing HttpOnly, session fixation patterns |
725
+
726
+ ### 6.4 Runtime Monitoring
727
+
728
+ | Tool | Purpose |
729
+ |------|---------|
730
+ | **Splunk** | Detect concurrent sessions from different IPs (built-in detection rules for AWS, Azure AD, O365) |
731
+ | **Elastic SIEM** | Session anomaly detection with ML-based behavioral analysis |
732
+ | **Datadog ASM** | Application-level session attack detection |
733
+ | **AWS GuardDuty** | Detect compromised credentials via session anomalies |
734
+
735
+ ---
736
+
737
+ ## 7. Platform-Specific Guidance
738
+
739
+ ### 7.1 Web Applications — Storage Comparison
740
+
741
+ | Storage | XSS Accessible | CSRF Risk | Capacity | Persistence | Recommendation |
742
+ |---------|---------------|-----------|----------|-------------|----------------|
743
+ | HttpOnly Cookie | No | Yes (mitigated by SameSite) | ~4 KB | Configurable | **Recommended for session IDs** |
744
+ | localStorage | Yes | No | ~5-10 MB | Until cleared | **Never for session tokens** |
745
+ | sessionStorage | Yes | No | ~5-10 MB | Tab lifetime | Acceptable for non-sensitive temporary data only |
746
+ | In-memory (JS variable) | Yes (if XSS) | No | Unlimited | Page lifetime | Acceptable for short-lived access tokens in SPAs |
747
+
748
+ **Rule:** Session identifiers and authentication tokens belong in HttpOnly cookies. Period.
749
+
750
+ ### 7.2 Single-Page Applications (SPAs)
751
+
752
+ SPAs present unique session management challenges:
753
+
754
+ **Recommended architecture — Backend-For-Frontend (BFF):**
755
+ 1. The BFF acts as a confidential OAuth client, keeping tokens server-side.
756
+ 2. The SPA communicates with the BFF using HttpOnly session cookies.
757
+ 3. The BFF proxies API requests, attaching access tokens from its server-side store.
758
+ 4. Token refresh happens server-side, invisible to the browser.
759
+
760
+ ```
761
+ [Browser/SPA] <--HttpOnly cookie--> [BFF Server] <--Access Token--> [API Server]
762
+ ```
763
+
764
+ **If BFF is not feasible (public client SPA):**
765
+ - Use Authorization Code Flow with PKCE.
766
+ - Store access tokens in memory only (JavaScript closure or module scope).
767
+ - Use refresh token rotation with one-time-use tokens.
768
+ - Set refresh token as HttpOnly cookie with strict SameSite.
769
+ - Implement silent refresh before access token expiry.
770
+ - Note: Third-party cookie blocking in Safari and upcoming Chrome changes affect silent refresh via iframes. Plan for BFF migration.
771
+
772
+ **Content Security Policy for SPAs:**
773
+ ```
774
+ Content-Security-Policy: default-src 'self'; script-src 'self'; connect-src 'self' https://api.example.com; frame-ancestors 'none';
775
+ ```
776
+
777
+ ### 7.3 Mobile Applications
778
+
779
+ **iOS — Keychain Services:**
780
+ ```swift
781
+ // SECURE: Store session token in iOS Keychain
782
+ import Security
783
+
784
+ func storeToken(_ token: String, forKey key: String) -> Bool {
785
+ let data = token.data(using: .utf8)!
786
+ let query: [String: Any] = [
787
+ kSecClass as String: kSecClassGenericPassword,
788
+ kSecAttrAccount as String: key,
789
+ kSecValueData as String: data,
790
+ kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
791
+ ]
792
+ SecItemDelete(query as CFDictionary) // Remove existing
793
+ let status = SecItemAdd(query as CFDictionary, nil)
794
+ return status == errSecSuccess
795
+ }
796
+ ```
797
+
798
+ **Android — EncryptedSharedPreferences with Keystore:**
799
+ ```kotlin
800
+ // SECURE: Store session token with Android Keystore-backed encryption
801
+ import androidx.security.crypto.EncryptedSharedPreferences
802
+ import androidx.security.crypto.MasterKey
803
+
804
+ val masterKey = MasterKey.Builder(context)
805
+ .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
806
+ .build()
807
+
808
+ val prefs = EncryptedSharedPreferences.create(
809
+ context,
810
+ "secure_session_prefs",
811
+ masterKey,
812
+ EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
813
+ EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
814
+ )
815
+
816
+ prefs.edit().putString("session_token", token).apply()
817
+ ```
818
+
819
+ **Mobile session management rules:**
820
+ - Never store tokens in plaintext SharedPreferences or UserDefaults.
821
+ - Use hardware-backed encryption (Secure Enclave on iOS, Hardware Security Module on Android).
822
+ - Set `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` on iOS to prevent iCloud Keychain sync and lock-screen access.
823
+ - Implement certificate pinning to prevent AiTM token interception.
824
+ - Support remote session revocation via push notification or next-request check.
825
+ - Enforce biometric re-authentication for sensitive operations.
826
+
827
+ ---
828
+
829
+ ## 8. Incident Patterns
830
+
831
+ ### 8.1 Session Hijacking Detection
832
+
833
+ **Indicators of Compromise:**
834
+ - Same session ID used from multiple IP addresses within a short time window (< 5 minutes).
835
+ - Geographically impossible travel: session used from two locations farther apart than possible given the time interval.
836
+ - User-Agent string change within the same session.
837
+ - Sudden spike in API requests from a session that was previously idle.
838
+ - Session used outside the user's established behavioral baseline (unusual hours, unusual endpoints).
839
+
840
+ **Detection Queries (Splunk example):**
841
+ ```spl
842
+ index=web_logs sourcetype=access_combined
843
+ | stats dc(client_ip) as unique_ips, values(client_ip) as ip_list by session_id
844
+ | where unique_ips > 1
845
+ | lookup geoip ip_list OUTPUT lat, lon, country
846
+ | eval distance=haversine(lat_1, lon_1, lat_2, lon_2)
847
+ | where distance > 500
848
+ | table session_id, ip_list, unique_ips, distance
849
+ ```
850
+
851
+ ### 8.2 Concurrent Session Anomalies
852
+
853
+ **Detection logic:**
854
+ 1. Track `(user_id, session_id, ip_address, user_agent, geo)` for every authenticated request.
855
+ 2. Alert when a user has active sessions from more than N distinct IP addresses simultaneously.
856
+ 3. Alert when a new session is created from a geo-location inconsistent with the user's history.
857
+ 4. Correlate with known infostealer malware indicators (e.g., sessions originating from residential proxy networks).
858
+
859
+ ### 8.3 Incident Response Steps
860
+
861
+ **Immediate (0-15 minutes):**
862
+ 1. Revoke all active sessions for the affected user (`revokeAllSessions(userId)`).
863
+ 2. Invalidate all refresh tokens and remember-me tokens.
864
+ 3. Force password reset and MFA re-enrollment.
865
+ 4. Block the attacker's IP/session from the WAF.
866
+
867
+ **Short-term (15-60 minutes):**
868
+ 5. Analyze access logs to determine scope: what data was accessed, what actions were taken.
869
+ 6. Check if the stolen session was used to modify account settings (email, MFA, password).
870
+ 7. Revert any unauthorized changes to the account.
871
+ 8. Notify the affected user via a verified out-of-band channel.
872
+
873
+ **Investigation (1-24 hours):**
874
+ 9. Determine the theft vector: XSS, malware, phishing proxy, network interception, or insider.
875
+ 10. If XSS: identify and patch the injection point, scan for similar vulnerabilities.
876
+ 11. If infostealer: coordinate with endpoint security team for device remediation.
877
+ 12. If phishing proxy: report phishing domain, update email filters.
878
+ 13. Review session management configuration for gaps identified during the incident.
879
+
880
+ **Post-incident:**
881
+ 14. Implement additional controls based on root cause (e.g., add device binding, IP pinning, anomaly detection).
882
+ 15. Update detection rules to catch similar attacks earlier.
883
+ 16. Conduct lessons-learned review and update this playbook.
884
+
885
+ ---
886
+
887
+ ## 9. Compliance & Standards
888
+
889
+ ### 9.1 OWASP Top 10 — A07:2021 Identification and Authentication Failures
890
+
891
+ Session management falls under A07:2021. Key requirements:
892
+ - Session IDs must not be exposed in URLs.
893
+ - Session IDs must be rotated after successful login.
894
+ - Sessions must be properly invalidated during logout and idle timeout.
895
+ - Session IDs must have sufficient entropy to resist prediction attacks.
896
+
897
+ ### 9.2 NIST SP 800-63B — Digital Identity Guidelines
898
+
899
+ - **Session binding:** Bind session to the authenticated subscriber. Session secrets must be at least 64 bits of entropy (OWASP recommends 128-bit minimum).
900
+ - **Reauthentication:** Require reauthentication after 15 minutes of inactivity for AAL2 (multi-factor) and AAL3 (hardware token) sessions.
901
+ - **Session limits:** Set absolute session lifetime limits. Reauthentication required periodically even for active sessions.
902
+ - **Storage:** Session secrets stored in secure, httpOnly cookies. Must be sent only over authenticated, protected (TLS) channels.
903
+
904
+ ### 9.3 PCI-DSS 4.0
905
+
906
+ - **Requirement 8.2.8 (mandatory since March 31, 2025):** If a user session has been idle for more than 15 minutes, the user must re-authenticate. This applies to all access to the Cardholder Data Environment (CDE).
907
+ - **Requirement 8.3:** Multi-factor authentication required for all personnel with access to the CDE. Each session (VPN, CDE application) requires its own MFA challenge.
908
+ - **Requirement 8.6:** System and application accounts used for automated access must have session controls including regular credential rotation and monitoring.
909
+ - **Replay protection:** Methods to defend against replay attacks include unique session identifiers, timestamps, and time-based one-time passwords.
910
+
911
+ ### 9.4 CWE References Summary
912
+
913
+ | CWE | Name | Section |
914
+ |-----|------|---------|
915
+ | CWE-330 | Use of Insufficiently Random Values | V-01 |
916
+ | CWE-1004 | Sensitive Cookie Without HttpOnly Flag | V-02 |
917
+ | CWE-614 | Sensitive Cookie in HTTPS Session Without Secure Attribute | V-03 |
918
+ | CWE-384 | Session Fixation | V-04 |
919
+ | CWE-598 | Use of GET Request Method With Sensitive Query Strings | V-05 |
920
+ | CWE-613 | Insufficient Session Expiration | V-06, V-07, V-09, V-13 |
921
+ | CWE-640 | Weak Password Recovery Mechanism for Forgotten Password | V-08 |
922
+ | CWE-327 | Use of a Broken or Risky Cryptographic Algorithm | V-10 |
923
+ | CWE-922 | Insecure Storage of Sensitive Information | V-11 |
924
+ | CWE-1275 | Sensitive Cookie with Improper SameSite Attribute | V-12 |
925
+ | CWE-784 | Reliance on Cookies without Validation and Integrity | V-15 |
926
+
927
+ ---
928
+
929
+ ## 10. Code Examples — Vulnerable vs. Secure Pairs
930
+
931
+ ### 10.1 Complete Express Session Setup
932
+
933
+ ```typescript
934
+ // === VULNERABLE SESSION CONFIGURATION ===
935
+ import express from 'express';
936
+ import session from 'express-session';
937
+
938
+ const app = express();
939
+ app.use(session({
940
+ secret: 'keyboard cat', // Weak, hardcoded secret
941
+ resave: true, // Unnecessary writes
942
+ saveUninitialized: true, // Creates sessions for anonymous users
943
+ cookie: {}, // No security attributes set
944
+ }));
945
+
946
+ // === SECURE SESSION CONFIGURATION ===
947
+ import express from 'express';
948
+ import session from 'express-session';
949
+ import { createClient } from 'redis';
950
+ import RedisStore from 'connect-redis';
951
+ import crypto from 'crypto';
952
+
953
+ const app = express();
954
+
955
+ const redisClient = createClient({
956
+ url: process.env.REDIS_URL,
957
+ socket: { tls: process.env.NODE_ENV === 'production' },
958
+ });
959
+ await redisClient.connect();
960
+
961
+ app.set('trust proxy', 1); // Trust first proxy (for Secure cookie behind LB)
962
+
963
+ app.use(session({
964
+ store: new RedisStore({ client: redisClient, prefix: 'sess:', ttl: 1800 }),
965
+ name: '__Host-sid',
966
+ secret: [
967
+ process.env.SESSION_SECRET_CURRENT!, // Current secret
968
+ process.env.SESSION_SECRET_PREVIOUS!, // Previous secret (for rotation)
969
+ ],
970
+ resave: false,
971
+ saveUninitialized: false,
972
+ rolling: true,
973
+ cookie: {
974
+ httpOnly: true,
975
+ secure: true,
976
+ sameSite: 'lax',
977
+ maxAge: 1800000,
978
+ path: '/',
979
+ },
980
+ }));
981
+ ```
982
+
983
+ ### 10.2 Session Timeout Middleware
984
+
985
+ ```typescript
986
+ // === VULNERABLE: No timeout enforcement ===
987
+ // (relying solely on cookie maxAge — client can modify)
988
+
989
+ // === SECURE: Server-side dual timeout enforcement ===
990
+ const IDLE_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes
991
+ const ABSOLUTE_TIMEOUT_MS = 8 * 60 * 60 * 1000; // 8 hours
992
+
993
+ function sessionTimeoutMiddleware(
994
+ req: express.Request,
995
+ res: express.Response,
996
+ next: express.NextFunction
997
+ ): void {
998
+ if (!req.session?.userId) {
999
+ return next(); // No authenticated session
1000
+ }
1001
+
1002
+ const now = Date.now();
1003
+
1004
+ // Check absolute timeout
1005
+ if (req.session.loginTime && now - req.session.loginTime > ABSOLUTE_TIMEOUT_MS) {
1006
+ return req.session.destroy(() => {
1007
+ res.clearCookie('__Host-sid', {
1008
+ httpOnly: true, secure: true, sameSite: 'lax', path: '/',
1009
+ });
1010
+ res.status(401).json({ error: 'Session expired', reason: 'absolute_timeout' });
1011
+ });
1012
+ }
1013
+
1014
+ // Check idle timeout
1015
+ if (req.session.lastActivity && now - req.session.lastActivity > IDLE_TIMEOUT_MS) {
1016
+ return req.session.destroy(() => {
1017
+ res.clearCookie('__Host-sid', {
1018
+ httpOnly: true, secure: true, sameSite: 'lax', path: '/',
1019
+ });
1020
+ res.status(401).json({ error: 'Session expired', reason: 'idle_timeout' });
1021
+ });
1022
+ }
1023
+
1024
+ // Update last activity timestamp
1025
+ req.session.lastActivity = now;
1026
+ next();
1027
+ }
1028
+
1029
+ app.use(sessionTimeoutMiddleware);
1030
+ ```
1031
+
1032
+ ### 10.3 Device/IP Binding for Session Integrity
1033
+
1034
+ ```typescript
1035
+ // SECURE: Bind session to device fingerprint for anomaly detection
1036
+ interface SessionMetadata {
1037
+ userId: string;
1038
+ ip: string;
1039
+ userAgent: string;
1040
+ loginTime: number;
1041
+ lastActivity: number;
1042
+ }
1043
+
1044
+ function sessionIntegrityCheck(
1045
+ req: express.Request,
1046
+ res: express.Response,
1047
+ next: express.NextFunction
1048
+ ): void {
1049
+ if (!req.session?.userId) return next();
1050
+
1051
+ const currentIp = req.ip;
1052
+ const currentUA = req.get('user-agent') || '';
1053
+
1054
+ // Strict: block if IP changes (may cause issues with mobile/VPN users)
1055
+ // Recommended: alert but allow, require re-auth for sensitive operations
1056
+ if (req.session.ip && req.session.ip !== currentIp) {
1057
+ logger.warn('Session IP change detected', {
1058
+ sessionId: req.sessionID,
1059
+ userId: req.session.userId,
1060
+ originalIp: req.session.ip,
1061
+ currentIp,
1062
+ });
1063
+ // For high-security: force re-authentication
1064
+ // For standard: log and continue
1065
+ }
1066
+
1067
+ if (req.session.userAgent && req.session.userAgent !== currentUA) {
1068
+ logger.warn('Session User-Agent change detected', {
1069
+ sessionId: req.sessionID,
1070
+ userId: req.session.userId,
1071
+ });
1072
+ // User-Agent change is a stronger signal of hijacking
1073
+ return req.session.destroy(() => {
1074
+ res.status(401).json({ error: 'Session invalidated', reason: 'integrity_check' });
1075
+ });
1076
+ }
1077
+
1078
+ next();
1079
+ }
1080
+ ```
1081
+
1082
+ ---
1083
+
1084
+ ## References
1085
+
1086
+ - [OWASP Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html)
1087
+ - [OWASP Top 10 A07:2021 — Identification and Authentication Failures](https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/)
1088
+ - [OWASP Testing Guide — Session Management Testing](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/)
1089
+ - [NIST SP 800-63B — Digital Identity Guidelines](https://pages.nist.gov/800-63-3/sp800-63b.html)
1090
+ - [PCI-DSS 4.0 Requirement 8.2.8 — Session Timeout](https://pcidssguide.com/pci-dss-session-timeout-requirements/)
1091
+ - [CWE-384: Session Fixation](https://cwe.mitre.org/data/definitions/384.html)
1092
+ - [PortSwigger — JWT Attacks](https://portswigger.net/web-security/jwt)
1093
+ - [PortSwigger — Burp Sequencer Documentation](https://portswigger.net/burp/documentation/desktop/tools/sequencer/getting-started)
1094
+ - [Auth0 — Refresh Token Rotation](https://auth0.com/blog/securing-single-page-applications-with-refresh-token-rotation/)
1095
+ - [Curity — SPA Best Practices](https://curity.io/resources/learn/spa-best-practices/)
1096
+ - [Redis — Session Management](https://redis.io/solutions/session-management/)
1097
+ - [Mozilla — Secure Cookie Configuration](https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/Cookies)
1098
+ - [SpyCloud — 2024 Cybercrime Report](https://spycloud.com/blog/2024-cybercrime-update-and-2025-predictions/)
1099
+ - [Push Security — 2024 Identity Breaches](https://pushsecurity.com/blog/2024-identity-breaches)
1100
+ - [The Hacker News — Session Hijacking 2.0](https://thehackernews.com/2024/09/session-hijacking-20-latest-way-that.html)
1101
+ - [Red Sentry — JWT Vulnerabilities 2026](https://redsentry.com/resources/blog/jwt-vulnerabilities-list-2026-security-risks-mitigation-guide)