ccjk 14.2.2 → 15.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 (528) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +58 -341
  3. package/dist/cli.js +59 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/detect.js +15 -0
  6. package/dist/commands/detect.js.map +1 -0
  7. package/dist/commands/doctor.js +68 -0
  8. package/dist/commands/doctor.js.map +1 -0
  9. package/dist/commands/git-install.js +50 -0
  10. package/dist/commands/git-install.js.map +1 -0
  11. package/dist/commands/init.js +102 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/commands/mcp.js +66 -0
  14. package/dist/commands/mcp.js.map +1 -0
  15. package/dist/commands/menu.js +33 -0
  16. package/dist/commands/menu.js.map +1 -0
  17. package/dist/core/detect.js +24 -0
  18. package/dist/core/detect.js.map +1 -0
  19. package/dist/core/lint.js +49 -0
  20. package/dist/core/lint.js.map +1 -0
  21. package/dist/core/mcp.js +41 -0
  22. package/dist/core/mcp.js.map +1 -0
  23. package/dist/core/paths.js +9 -0
  24. package/dist/core/paths.js.map +1 -0
  25. package/dist/core/providers.js +53 -0
  26. package/dist/core/providers.js.map +1 -0
  27. package/dist/core/settings.js +31 -0
  28. package/dist/core/settings.js.map +1 -0
  29. package/dist/core/slash-templates.js +56 -0
  30. package/dist/core/slash-templates.js.map +1 -0
  31. package/dist/core/tools.js +27 -0
  32. package/dist/core/tools.js.map +1 -0
  33. package/package.json +43 -164
  34. package/README.HONEST.md +0 -176
  35. package/README.en.md +0 -67
  36. package/README.ja.md +0 -67
  37. package/README.ko.md +0 -67
  38. package/README.zh-CN.md +0 -86
  39. package/bin/ccjk.mjs +0 -5
  40. package/bin/ccjk.ts +0 -222
  41. package/dist/chunks/agent-teams.mjs +0 -145
  42. package/dist/chunks/agent.mjs +0 -1439
  43. package/dist/chunks/agents.mjs +0 -3783
  44. package/dist/chunks/api-cli.mjs +0 -135
  45. package/dist/chunks/api-config-selector.mjs +0 -159
  46. package/dist/chunks/api-providers.mjs +0 -144
  47. package/dist/chunks/api.mjs +0 -115
  48. package/dist/chunks/auto-bootstrap.mjs +0 -358
  49. package/dist/chunks/auto-fixer.mjs +0 -95
  50. package/dist/chunks/auto-updater.mjs +0 -507
  51. package/dist/chunks/banner.mjs +0 -173
  52. package/dist/chunks/bash.mjs +0 -187
  53. package/dist/chunks/boost.mjs +0 -474
  54. package/dist/chunks/brain-config.mjs +0 -75
  55. package/dist/chunks/brain-status.mjs +0 -89
  56. package/dist/chunks/ccjk-agents.mjs +0 -416
  57. package/dist/chunks/ccjk-all.mjs +0 -1046
  58. package/dist/chunks/ccjk-config.mjs +0 -445
  59. package/dist/chunks/ccjk-hooks.mjs +0 -1074
  60. package/dist/chunks/ccjk-mcp.mjs +0 -763
  61. package/dist/chunks/ccjk-setup.mjs +0 -765
  62. package/dist/chunks/ccjk-skills.mjs +0 -518
  63. package/dist/chunks/ccr.mjs +0 -109
  64. package/dist/chunks/ccu.mjs +0 -40
  65. package/dist/chunks/check-updates.mjs +0 -117
  66. package/dist/chunks/claude-code-incremental-manager.mjs +0 -761
  67. package/dist/chunks/claude-config.mjs +0 -606
  68. package/dist/chunks/claude-config2.mjs +0 -62
  69. package/dist/chunks/claude-wrapper.mjs +0 -85
  70. package/dist/chunks/clavue-config.mjs +0 -1454
  71. package/dist/chunks/cleanup-migration.mjs +0 -20
  72. package/dist/chunks/cli-hook.mjs +0 -4096
  73. package/dist/chunks/cloud-sync.mjs +0 -29
  74. package/dist/chunks/code-type-resolver.mjs +0 -880
  75. package/dist/chunks/codex-config-switch.mjs +0 -452
  76. package/dist/chunks/codex-provider-manager.mjs +0 -238
  77. package/dist/chunks/codex-uninstaller.mjs +0 -404
  78. package/dist/chunks/codex.mjs +0 -2141
  79. package/dist/chunks/commands.mjs +0 -108
  80. package/dist/chunks/commands2.mjs +0 -421
  81. package/dist/chunks/commit.mjs +0 -140
  82. package/dist/chunks/completion.mjs +0 -517
  83. package/dist/chunks/config-consolidator.mjs +0 -172
  84. package/dist/chunks/config-switch.mjs +0 -334
  85. package/dist/chunks/config.mjs +0 -558
  86. package/dist/chunks/config2.mjs +0 -484
  87. package/dist/chunks/config3.mjs +0 -486
  88. package/dist/chunks/constants.mjs +0 -323
  89. package/dist/chunks/context-opt.mjs +0 -444
  90. package/dist/chunks/context.mjs +0 -974
  91. package/dist/chunks/dashboard.mjs +0 -481
  92. package/dist/chunks/doctor.mjs +0 -1301
  93. package/dist/chunks/eval.mjs +0 -502
  94. package/dist/chunks/evolution.mjs +0 -322
  95. package/dist/chunks/features.mjs +0 -715
  96. package/dist/chunks/fish.mjs +0 -181
  97. package/dist/chunks/fs-operations.mjs +0 -180
  98. package/dist/chunks/health-alerts.mjs +0 -830
  99. package/dist/chunks/help.mjs +0 -341
  100. package/dist/chunks/hook-installer.mjs +0 -48
  101. package/dist/chunks/impact.mjs +0 -651
  102. package/dist/chunks/index.mjs +0 -23
  103. package/dist/chunks/index10.mjs +0 -19
  104. package/dist/chunks/index11.mjs +0 -1171
  105. package/dist/chunks/index12.mjs +0 -218
  106. package/dist/chunks/index13.mjs +0 -679
  107. package/dist/chunks/index14.mjs +0 -1009
  108. package/dist/chunks/index15.mjs +0 -194
  109. package/dist/chunks/index2.mjs +0 -7637
  110. package/dist/chunks/index3.mjs +0 -171
  111. package/dist/chunks/index4.mjs +0 -26
  112. package/dist/chunks/index5.mjs +0 -19
  113. package/dist/chunks/index6.mjs +0 -19092
  114. package/dist/chunks/index7.mjs +0 -616
  115. package/dist/chunks/index8.mjs +0 -1602
  116. package/dist/chunks/index9.mjs +0 -5384
  117. package/dist/chunks/init.mjs +0 -1911
  118. package/dist/chunks/installer.mjs +0 -757
  119. package/dist/chunks/installer2.mjs +0 -103
  120. package/dist/chunks/interview.mjs +0 -2927
  121. package/dist/chunks/json-config.mjs +0 -60
  122. package/dist/chunks/linux.mjs +0 -3863
  123. package/dist/chunks/macos.mjs +0 -69
  124. package/dist/chunks/main.mjs +0 -635
  125. package/dist/chunks/manager.mjs +0 -1048
  126. package/dist/chunks/marketplace.mjs +0 -265
  127. package/dist/chunks/mcp-cli.mjs +0 -205
  128. package/dist/chunks/mcp-performance.mjs +0 -187
  129. package/dist/chunks/mcp.mjs +0 -667
  130. package/dist/chunks/memory-check.mjs +0 -2973
  131. package/dist/chunks/memory-paths.mjs +0 -259
  132. package/dist/chunks/memory-sync.mjs +0 -209
  133. package/dist/chunks/memory.mjs +0 -354
  134. package/dist/chunks/metrics-display.mjs +0 -153
  135. package/dist/chunks/monitor.mjs +0 -1856
  136. package/dist/chunks/notification.mjs +0 -1864
  137. package/dist/chunks/onboarding.mjs +0 -386
  138. package/dist/chunks/package.mjs +0 -3
  139. package/dist/chunks/paradigm.mjs +0 -74
  140. package/dist/chunks/permission-manager.mjs +0 -250
  141. package/dist/chunks/permissions.mjs +0 -265
  142. package/dist/chunks/persistence-manager.mjs +0 -801
  143. package/dist/chunks/persistence.mjs +0 -707
  144. package/dist/chunks/platform.mjs +0 -395
  145. package/dist/chunks/plugin.mjs +0 -1936
  146. package/dist/chunks/powershell.mjs +0 -213
  147. package/dist/chunks/prompts.mjs +0 -244
  148. package/dist/chunks/providers.mjs +0 -263
  149. package/dist/chunks/quick-actions.mjs +0 -335
  150. package/dist/chunks/quick-provider.mjs +0 -755
  151. package/dist/chunks/quick-setup.mjs +0 -421
  152. package/dist/chunks/remote.mjs +0 -497
  153. package/dist/chunks/research.mjs +0 -1904
  154. package/dist/chunks/rollback.mjs +0 -38
  155. package/dist/chunks/session-manager.mjs +0 -1371
  156. package/dist/chunks/session.mjs +0 -878
  157. package/dist/chunks/sessions.mjs +0 -106
  158. package/dist/chunks/silent-updater.mjs +0 -396
  159. package/dist/chunks/simple-config.mjs +0 -122
  160. package/dist/chunks/skill.mjs +0 -117
  161. package/dist/chunks/skill2.mjs +0 -9052
  162. package/dist/chunks/skills-sync.mjs +0 -1343
  163. package/dist/chunks/skills.mjs +0 -577
  164. package/dist/chunks/slash-commands.mjs +0 -208
  165. package/dist/chunks/smart-guide.mjs +0 -247
  166. package/dist/chunks/snapshot.mjs +0 -58
  167. package/dist/chunks/startup.mjs +0 -487
  168. package/dist/chunks/stats.mjs +0 -191
  169. package/dist/chunks/status.mjs +0 -471
  170. package/dist/chunks/team.mjs +0 -63
  171. package/dist/chunks/thinking.mjs +0 -626
  172. package/dist/chunks/trace.mjs +0 -57
  173. package/dist/chunks/uninstall.mjs +0 -852
  174. package/dist/chunks/update.mjs +0 -174
  175. package/dist/chunks/upgrade-manager.mjs +0 -204
  176. package/dist/chunks/upgrade.mjs +0 -133
  177. package/dist/chunks/version-checker.mjs +0 -891
  178. package/dist/chunks/vim.mjs +0 -903
  179. package/dist/chunks/windows.mjs +0 -14
  180. package/dist/chunks/workflows.mjs +0 -633
  181. package/dist/chunks/wsl.mjs +0 -129
  182. package/dist/chunks/zero-config.mjs +0 -871
  183. package/dist/chunks/zsh.mjs +0 -182
  184. package/dist/cli.d.mts +0 -1
  185. package/dist/cli.d.ts +0 -1
  186. package/dist/cli.mjs +0 -2684
  187. package/dist/i18n/locales/en/agent-teams.json +0 -18
  188. package/dist/i18n/locales/en/agentBrowser.json +0 -80
  189. package/dist/i18n/locales/en/agents.json +0 -135
  190. package/dist/i18n/locales/en/api.json +0 -63
  191. package/dist/i18n/locales/en/ccjk-agents.json +0 -33
  192. package/dist/i18n/locales/en/ccjk-all.json +0 -23
  193. package/dist/i18n/locales/en/ccjk-skills.json +0 -22
  194. package/dist/i18n/locales/en/ccjk.json +0 -276
  195. package/dist/i18n/locales/en/ccr.json +0 -65
  196. package/dist/i18n/locales/en/claude-md.json +0 -73
  197. package/dist/i18n/locales/en/cli.json +0 -148
  198. package/dist/i18n/locales/en/cloud-setup.json +0 -31
  199. package/dist/i18n/locales/en/cloud-sync.json +0 -147
  200. package/dist/i18n/locales/en/cloud.json +0 -40
  201. package/dist/i18n/locales/en/cloudPlugins.json +0 -118
  202. package/dist/i18n/locales/en/codex.json +0 -184
  203. package/dist/i18n/locales/en/cometix.json +0 -29
  204. package/dist/i18n/locales/en/common.json +0 -68
  205. package/dist/i18n/locales/en/config.json +0 -108
  206. package/dist/i18n/locales/en/configuration.json +0 -236
  207. package/dist/i18n/locales/en/context.json +0 -85
  208. package/dist/i18n/locales/en/dashboard.json +0 -78
  209. package/dist/i18n/locales/en/errors.json +0 -26
  210. package/dist/i18n/locales/en/evolution.json +0 -54
  211. package/dist/i18n/locales/en/hooks.json +0 -74
  212. package/dist/i18n/locales/en/hooksSync.json +0 -133
  213. package/dist/i18n/locales/en/installation.json +0 -83
  214. package/dist/i18n/locales/en/interview.json +0 -104
  215. package/dist/i18n/locales/en/language.json +0 -19
  216. package/dist/i18n/locales/en/lsp.json +0 -78
  217. package/dist/i18n/locales/en/marketplace.json +0 -116
  218. package/dist/i18n/locales/en/mcp.json +0 -180
  219. package/dist/i18n/locales/en/memory.json +0 -23
  220. package/dist/i18n/locales/en/menu.json +0 -299
  221. package/dist/i18n/locales/en/multi-config.json +0 -79
  222. package/dist/i18n/locales/en/notification.json +0 -307
  223. package/dist/i18n/locales/en/permissions.json +0 -95
  224. package/dist/i18n/locales/en/persistence.json +0 -127
  225. package/dist/i18n/locales/en/plugins.json +0 -146
  226. package/dist/i18n/locales/en/quick-actions.json +0 -78
  227. package/dist/i18n/locales/en/registry.json +0 -54
  228. package/dist/i18n/locales/en/remote.json +0 -93
  229. package/dist/i18n/locales/en/sandbox.json +0 -44
  230. package/dist/i18n/locales/en/setup.json +0 -44
  231. package/dist/i18n/locales/en/shencha.json +0 -14
  232. package/dist/i18n/locales/en/skills.json +0 -100
  233. package/dist/i18n/locales/en/skillsSync.json +0 -74
  234. package/dist/i18n/locales/en/smartGuide.json +0 -49
  235. package/dist/i18n/locales/en/stats.json +0 -20
  236. package/dist/i18n/locales/en/subagent.json +0 -69
  237. package/dist/i18n/locales/en/superpowers.json +0 -117
  238. package/dist/i18n/locales/en/team.json +0 -7
  239. package/dist/i18n/locales/en/thinking.json +0 -65
  240. package/dist/i18n/locales/en/tools.json +0 -42
  241. package/dist/i18n/locales/en/uninstall.json +0 -56
  242. package/dist/i18n/locales/en/updater.json +0 -29
  243. package/dist/i18n/locales/en/vim.json +0 -169
  244. package/dist/i18n/locales/en/workflow.json +0 -55
  245. package/dist/i18n/locales/en/workspace.json +0 -108
  246. package/dist/i18n/locales/zh-CN/agent-teams.json +0 -18
  247. package/dist/i18n/locales/zh-CN/agentBrowser.json +0 -80
  248. package/dist/i18n/locales/zh-CN/agents.json +0 -135
  249. package/dist/i18n/locales/zh-CN/api.json +0 -63
  250. package/dist/i18n/locales/zh-CN/ccjk-agents.json +0 -33
  251. package/dist/i18n/locales/zh-CN/ccjk-all.json +0 -23
  252. package/dist/i18n/locales/zh-CN/ccjk-skills.json +0 -22
  253. package/dist/i18n/locales/zh-CN/ccjk.json +0 -276
  254. package/dist/i18n/locales/zh-CN/ccr.json +0 -65
  255. package/dist/i18n/locales/zh-CN/claude-md.json +0 -73
  256. package/dist/i18n/locales/zh-CN/cli.json +0 -148
  257. package/dist/i18n/locales/zh-CN/cloud-setup.json +0 -31
  258. package/dist/i18n/locales/zh-CN/cloud-sync.json +0 -147
  259. package/dist/i18n/locales/zh-CN/cloud.json +0 -40
  260. package/dist/i18n/locales/zh-CN/cloudPlugins.json +0 -118
  261. package/dist/i18n/locales/zh-CN/codex.json +0 -184
  262. package/dist/i18n/locales/zh-CN/cometix.json +0 -29
  263. package/dist/i18n/locales/zh-CN/common.json +0 -68
  264. package/dist/i18n/locales/zh-CN/config.json +0 -108
  265. package/dist/i18n/locales/zh-CN/configuration.json +0 -234
  266. package/dist/i18n/locales/zh-CN/context.json +0 -85
  267. package/dist/i18n/locales/zh-CN/dashboard.json +0 -78
  268. package/dist/i18n/locales/zh-CN/errors.json +0 -26
  269. package/dist/i18n/locales/zh-CN/evolution.json +0 -54
  270. package/dist/i18n/locales/zh-CN/hooks.json +0 -74
  271. package/dist/i18n/locales/zh-CN/hooksSync.json +0 -133
  272. package/dist/i18n/locales/zh-CN/installation.json +0 -83
  273. package/dist/i18n/locales/zh-CN/interview.json +0 -104
  274. package/dist/i18n/locales/zh-CN/language.json +0 -19
  275. package/dist/i18n/locales/zh-CN/lsp.json +0 -78
  276. package/dist/i18n/locales/zh-CN/marketplace.json +0 -116
  277. package/dist/i18n/locales/zh-CN/mcp.json +0 -180
  278. package/dist/i18n/locales/zh-CN/memory.json +0 -23
  279. package/dist/i18n/locales/zh-CN/menu.json +0 -299
  280. package/dist/i18n/locales/zh-CN/multi-config.json +0 -79
  281. package/dist/i18n/locales/zh-CN/notification.json +0 -307
  282. package/dist/i18n/locales/zh-CN/permissions.json +0 -95
  283. package/dist/i18n/locales/zh-CN/persistence.json +0 -127
  284. package/dist/i18n/locales/zh-CN/plugins.json +0 -146
  285. package/dist/i18n/locales/zh-CN/quick-actions.json +0 -78
  286. package/dist/i18n/locales/zh-CN/registry.json +0 -54
  287. package/dist/i18n/locales/zh-CN/remote.json +0 -93
  288. package/dist/i18n/locales/zh-CN/sandbox.json +0 -44
  289. package/dist/i18n/locales/zh-CN/setup.json +0 -44
  290. package/dist/i18n/locales/zh-CN/shencha.json +0 -14
  291. package/dist/i18n/locales/zh-CN/skills.json +0 -100
  292. package/dist/i18n/locales/zh-CN/skillsSync.json +0 -74
  293. package/dist/i18n/locales/zh-CN/smartGuide.json +0 -49
  294. package/dist/i18n/locales/zh-CN/stats.json +0 -20
  295. package/dist/i18n/locales/zh-CN/subagent.json +0 -69
  296. package/dist/i18n/locales/zh-CN/superpowers.json +0 -117
  297. package/dist/i18n/locales/zh-CN/team.json +0 -7
  298. package/dist/i18n/locales/zh-CN/thinking.json +0 -65
  299. package/dist/i18n/locales/zh-CN/tools.json +0 -42
  300. package/dist/i18n/locales/zh-CN/uninstall.json +0 -56
  301. package/dist/i18n/locales/zh-CN/updater.json +0 -29
  302. package/dist/i18n/locales/zh-CN/vim.json +0 -169
  303. package/dist/i18n/locales/zh-CN/workflow.json +0 -55
  304. package/dist/i18n/locales/zh-CN/workspace.json +0 -108
  305. package/dist/index.d.mts +0 -5658
  306. package/dist/index.d.ts +0 -5658
  307. package/dist/index.mjs +0 -3732
  308. package/dist/shared/ccjk.5bEolFrk.mjs +0 -254
  309. package/dist/shared/ccjk.8oaxX4iR.mjs +0 -90
  310. package/dist/shared/ccjk.B2U7DsPy.mjs +0 -31
  311. package/dist/shared/ccjk.B2f-cwUP.mjs +0 -468
  312. package/dist/shared/ccjk.BAGoDD49.mjs +0 -36
  313. package/dist/shared/ccjk.BBtCGd_g.mjs +0 -899
  314. package/dist/shared/ccjk.BFQ7yr5S.mjs +0 -16
  315. package/dist/shared/ccjk.BLsIiTqO.mjs +0 -449
  316. package/dist/shared/ccjk.BXv8aYs1.mjs +0 -170
  317. package/dist/shared/ccjk.BnsY5WxD.mjs +0 -171
  318. package/dist/shared/ccjk.BoApaI4j.mjs +0 -28
  319. package/dist/shared/ccjk.Bq8TqZG_.mjs +0 -189
  320. package/dist/shared/ccjk.BtrioX1Z.mjs +0 -25
  321. package/dist/shared/ccjk.Bx_rmYfN.mjs +0 -69
  322. package/dist/shared/ccjk.BzPbSEP2.mjs +0 -115
  323. package/dist/shared/ccjk.C0WLUnFV.mjs +0 -293
  324. package/dist/shared/ccjk.C1hANZTu.mjs +0 -19
  325. package/dist/shared/ccjk.C2jHOZVP.mjs +0 -52
  326. package/dist/shared/ccjk.CNhnT6uQ.mjs +0 -636
  327. package/dist/shared/ccjk.COweQ1RR.mjs +0 -5
  328. package/dist/shared/ccjk.CfKKcvWy.mjs +0 -126
  329. package/dist/shared/ccjk.Cjgrln_h.mjs +0 -297
  330. package/dist/shared/ccjk.CoCHVXl3.mjs +0 -3951
  331. package/dist/shared/ccjk.CwGZSTAK.mjs +0 -319
  332. package/dist/shared/ccjk.CxpGa6MC.mjs +0 -2724
  333. package/dist/shared/ccjk.D-magaEx.mjs +0 -763
  334. package/dist/shared/ccjk.D0g2ABGg.mjs +0 -171
  335. package/dist/shared/ccjk.D6ycHbak.mjs +0 -270
  336. package/dist/shared/ccjk.D75wivnp.mjs +0 -142
  337. package/dist/shared/ccjk.DDL-4C-k.mjs +0 -100
  338. package/dist/shared/ccjk.DFRPtmK_.mjs +0 -75
  339. package/dist/shared/ccjk.DMV3x5Sd.mjs +0 -299
  340. package/dist/shared/ccjk.DZ2LLOa-.mjs +0 -2195
  341. package/dist/shared/ccjk.DbigonEQ.mjs +0 -698
  342. package/dist/shared/ccjk.DcMvE7lf.mjs +0 -618
  343. package/dist/shared/ccjk.DeWpAShp.mjs +0 -1828
  344. package/dist/shared/ccjk.DhJ1kyDR.mjs +0 -30
  345. package/dist/shared/ccjk.DlTXS9rP.mjs +0 -224
  346. package/dist/shared/ccjk.DopKzo3z.mjs +0 -305
  347. package/dist/shared/ccjk.DsZsc4LR.mjs +0 -1280
  348. package/dist/shared/ccjk.DuzJZlgj.mjs +0 -418
  349. package/dist/shared/ccjk.Dxgd2vjc.mjs +0 -444
  350. package/dist/shared/ccjk.J8YiPsOw.mjs +0 -259
  351. package/dist/shared/ccjk.KfSWcGlE.mjs +0 -38
  352. package/dist/shared/ccjk.L7yC58_i.mjs +0 -225
  353. package/dist/shared/ccjk.MwtjAULc.mjs +0 -1447
  354. package/dist/shared/ccjk.OJKHVSOb.mjs +0 -2005
  355. package/dist/shared/ccjk.OTnevPNE.mjs +0 -225
  356. package/dist/shared/ccjk.RyizuzOI.mjs +0 -21
  357. package/dist/shared/ccjk.T_cX87dY.mjs +0 -15
  358. package/dist/shared/ccjk.bQ7Dh1g4.mjs +0 -249
  359. package/dist/shared/ccjk.gDEDGD_t.mjs +0 -38
  360. package/dist/shared/ccjk.hoqrwWdN.mjs +0 -333
  361. package/dist/shared/ccjk.i_vn-9C3.mjs +0 -317
  362. package/dist/shared/ccjk.lG3ccFjm.mjs +0 -885
  363. package/dist/shared/ccjk.wLJHO0Af.mjs +0 -244
  364. package/dist/shared/ccjk.y-a_1vK4.mjs +0 -5127
  365. package/dist/templates/agents/README.md +0 -78
  366. package/dist/templates/agents/fullstack-developer.json +0 -70
  367. package/dist/templates/agents/go-expert.json +0 -69
  368. package/dist/templates/agents/index.json +0 -64
  369. package/dist/templates/agents/python-expert.json +0 -69
  370. package/dist/templates/agents/react-specialist.json +0 -69
  371. package/dist/templates/agents/testing-automation-expert.json +0 -70
  372. package/dist/templates/agents/typescript-architect.json +0 -69
  373. package/dist/templates/claude-code/common/settings.json +0 -109
  374. package/dist/templates/common/error-prevention.md +0 -267
  375. package/dist/templates/common/karpathy-baseline.md +0 -83
  376. package/dist/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
  377. package/dist/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
  378. package/dist/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
  379. package/dist/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
  380. package/dist/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
  381. package/dist/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
  382. package/dist/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
  383. package/dist/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
  384. package/dist/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
  385. package/dist/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
  386. package/dist/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
  387. package/dist/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
  388. package/dist/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
  389. package/dist/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
  390. package/dist/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
  391. package/dist/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
  392. package/dist/templates/common/workflow/essential/en/feat.md +0 -92
  393. package/dist/templates/common/workflow/essential/en/goal.md +0 -147
  394. package/dist/templates/common/workflow/essential/en/init-project.md +0 -53
  395. package/dist/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
  396. package/dist/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
  397. package/dist/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
  398. package/dist/templates/common/workflow/essential/zh-CN/feat.md +0 -315
  399. package/dist/templates/common/workflow/essential/zh-CN/goal.md +0 -146
  400. package/dist/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
  401. package/dist/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
  402. package/dist/templates/common/workflow/git/en/git-commit.md +0 -205
  403. package/dist/templates/common/workflow/git/en/git-rollback.md +0 -90
  404. package/dist/templates/common/workflow/git/en/git-worktree.md +0 -276
  405. package/dist/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
  406. package/dist/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
  407. package/dist/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
  408. package/dist/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
  409. package/dist/templates/common/workflow/interview/en/interview.md +0 -67
  410. package/dist/templates/common/workflow/interview/zh-CN/interview.md +0 -67
  411. package/dist/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
  412. package/dist/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
  413. package/dist/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
  414. package/dist/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
  415. package/dist/templates/common/workflow/sixStep/en/workflow.md +0 -83
  416. package/dist/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
  417. package/dist/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
  418. package/dist/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
  419. package/dist/templates/hooks/README.md +0 -212
  420. package/dist/templates/hooks/git-workflow-hooks.md +0 -551
  421. package/dist/templates/hooks/post-test/coverage.json +0 -21
  422. package/dist/templates/hooks/post-test/summary.json +0 -21
  423. package/dist/templates/hooks/post-test-coverage.md +0 -434
  424. package/dist/templates/hooks/pre-commit/eslint.json +0 -22
  425. package/dist/templates/hooks/pre-commit/prettier.json +0 -22
  426. package/dist/templates/hooks/pre-commit-black.md +0 -274
  427. package/dist/templates/hooks/pre-commit-eslint.md +0 -153
  428. package/dist/templates/hooks/pre-commit-gofmt.md +0 -284
  429. package/dist/templates/hooks/pre-commit-prettier.md +0 -212
  430. package/dist/templates/hooks/pre-commit-type-check.md +0 -377
  431. package/dist/templates/skills/ccjk-init.md +0 -154
  432. package/dist/templates/skills/ccjk-mcp-setup.md +0 -205
  433. package/dist/templates/skills/ccjk-troubleshoot.md +0 -228
  434. package/dist/templates/skills/django-patterns.md +0 -1016
  435. package/dist/templates/skills/git-workflow.md +0 -748
  436. package/dist/templates/skills/go-idioms.md +0 -963
  437. package/dist/templates/skills/index.json +0 -132
  438. package/dist/templates/skills/nextjs-optimization.md +0 -694
  439. package/dist/templates/skills/python-pep8.md +0 -852
  440. package/dist/templates/skills/react-patterns.md +0 -686
  441. package/dist/templates/skills/rust-patterns.md +0 -1057
  442. package/dist/templates/skills/security-best-practices.md +0 -1413
  443. package/dist/templates/skills/testing-best-practices.md +0 -1315
  444. package/dist/templates/skills/ts-best-practices.md +0 -354
  445. package/templates/agents/README.md +0 -78
  446. package/templates/agents/fullstack-developer.json +0 -70
  447. package/templates/agents/go-expert.json +0 -69
  448. package/templates/agents/index.json +0 -64
  449. package/templates/agents/python-expert.json +0 -69
  450. package/templates/agents/react-specialist.json +0 -69
  451. package/templates/agents/testing-automation-expert.json +0 -70
  452. package/templates/agents/typescript-architect.json +0 -69
  453. package/templates/claude-code/common/settings.json +0 -109
  454. package/templates/common/error-prevention.md +0 -267
  455. package/templates/common/karpathy-baseline.md +0 -83
  456. package/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
  457. package/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
  458. package/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
  459. package/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
  460. package/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
  461. package/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
  462. package/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
  463. package/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
  464. package/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
  465. package/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
  466. package/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
  467. package/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
  468. package/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
  469. package/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
  470. package/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
  471. package/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
  472. package/templates/common/workflow/essential/en/feat.md +0 -92
  473. package/templates/common/workflow/essential/en/goal.md +0 -147
  474. package/templates/common/workflow/essential/en/init-project.md +0 -53
  475. package/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
  476. package/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
  477. package/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
  478. package/templates/common/workflow/essential/zh-CN/feat.md +0 -315
  479. package/templates/common/workflow/essential/zh-CN/goal.md +0 -146
  480. package/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
  481. package/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
  482. package/templates/common/workflow/git/en/git-commit.md +0 -205
  483. package/templates/common/workflow/git/en/git-rollback.md +0 -90
  484. package/templates/common/workflow/git/en/git-worktree.md +0 -276
  485. package/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
  486. package/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
  487. package/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
  488. package/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
  489. package/templates/common/workflow/interview/en/interview.md +0 -67
  490. package/templates/common/workflow/interview/zh-CN/interview.md +0 -67
  491. package/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
  492. package/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
  493. package/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
  494. package/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
  495. package/templates/common/workflow/sixStep/en/workflow.md +0 -83
  496. package/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
  497. package/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
  498. package/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
  499. package/templates/hooks/README.md +0 -212
  500. package/templates/hooks/git-workflow-hooks.md +0 -551
  501. package/templates/hooks/post-test/coverage.json +0 -21
  502. package/templates/hooks/post-test/summary.json +0 -21
  503. package/templates/hooks/post-test-coverage.md +0 -434
  504. package/templates/hooks/pre-commit/eslint.json +0 -22
  505. package/templates/hooks/pre-commit/prettier.json +0 -22
  506. package/templates/hooks/pre-commit-black.md +0 -274
  507. package/templates/hooks/pre-commit-eslint.md +0 -153
  508. package/templates/hooks/pre-commit-gofmt.md +0 -284
  509. package/templates/hooks/pre-commit-prettier.md +0 -212
  510. package/templates/hooks/pre-commit-type-check.md +0 -377
  511. package/templates/skills/basic.hbs +0 -72
  512. package/templates/skills/ccjk-init.md +0 -154
  513. package/templates/skills/ccjk-mcp-setup.md +0 -205
  514. package/templates/skills/ccjk-troubleshoot.md +0 -228
  515. package/templates/skills/code-refactor.hbs +0 -133
  516. package/templates/skills/code-review.hbs +0 -141
  517. package/templates/skills/django-patterns.md +0 -1016
  518. package/templates/skills/git-workflow.md +0 -748
  519. package/templates/skills/go-idioms.md +0 -963
  520. package/templates/skills/index.json +0 -132
  521. package/templates/skills/nextjs-optimization.md +0 -694
  522. package/templates/skills/python-pep8.md +0 -852
  523. package/templates/skills/react-patterns.md +0 -686
  524. package/templates/skills/rust-patterns.md +0 -1057
  525. package/templates/skills/security-best-practices.md +0 -1413
  526. package/templates/skills/testing-best-practices.md +0 -1315
  527. package/templates/skills/ts-best-practices.md +0 -354
  528. package/templates/skills/type-fix.hbs +0 -132
@@ -1,1413 +0,0 @@
1
- ---
2
- name: security-best-practices
3
- description: Common vulnerabilities, input validation, authentication patterns, and security scanning
4
- description_zh: 常见漏洞、输入验证、身份验证模式和安全扫描
5
- version: 1.0.0
6
- category: security
7
- triggers: ['/security-best-practices', '/security', '/vulnerabilities', '/auth-security']
8
- use_when:
9
- - Implementing secure coding practices
10
- - Conducting security reviews and audits
11
- - Setting up authentication and authorization
12
- - Preventing common security vulnerabilities
13
- use_when_zh:
14
- - 实现安全编码实践
15
- - 进行安全审查和审计
16
- - 设置身份验证和授权
17
- - 防止常见安全漏洞
18
- auto_activate: true
19
- priority: 9
20
- agents: [security-expert, backend-architect]
21
- tags: [security, vulnerabilities, authentication, validation, encryption]
22
- ---
23
-
24
- # Security Best Practices | 安全最佳实践
25
-
26
- ## Context | 上下文
27
-
28
- Use this skill when implementing secure applications, conducting security reviews, and protecting against common vulnerabilities. Essential for building trustworthy and resilient software systems.
29
-
30
- 在实现安全应用程序、进行安全审查和防范常见漏洞时使用此技能。对于构建可信赖和有弹性的软件系统至关重要。
31
-
32
- ## OWASP Top 10 Vulnerabilities | OWASP 十大漏洞
33
-
34
- ### 1. Injection Attacks | 注入攻击
35
-
36
- ```javascript
37
- // ✅ Good: SQL Injection Prevention
38
- const mysql = require('mysql2/promise');
39
-
40
- // Use parameterized queries
41
- async function getUserById(userId) {
42
- const connection = await mysql.createConnection(dbConfig);
43
-
44
- // Safe: Parameters are properly escaped
45
- const [rows] = await connection.execute(
46
- 'SELECT * FROM users WHERE id = ?',
47
- [userId]
48
- );
49
-
50
- await connection.end();
51
- return rows[0];
52
- }
53
-
54
- async function searchUsers(searchTerm) {
55
- const connection = await mysql.createConnection(dbConfig);
56
-
57
- // Safe: Using LIKE with parameterized query
58
- const [rows] = await connection.execute(
59
- 'SELECT id, name, email FROM users WHERE name LIKE ? OR email LIKE ?',
60
- [`%${searchTerm}%`, `%${searchTerm}%`]
61
- );
62
-
63
- await connection.end();
64
- return rows;
65
- }
66
-
67
- // ✅ Good: NoSQL Injection Prevention (MongoDB)
68
- const { MongoClient, ObjectId } = require('mongodb');
69
-
70
- async function getUserByIdMongo(userId) {
71
- const client = new MongoClient(mongoUrl);
72
- await client.connect();
73
-
74
- const db = client.db('myapp');
75
- const users = db.collection('users');
76
-
77
- // Safe: Validate and sanitize input
78
- if (!ObjectId.isValid(userId)) {
79
- throw new Error('Invalid user ID format');
80
- }
81
-
82
- const user = await users.findOne({ _id: new ObjectId(userId) });
83
-
84
- await client.close();
85
- return user;
86
- }
87
-
88
- async function searchUsersMongo(searchCriteria) {
89
- const client = new MongoClient(mongoUrl);
90
- await client.connect();
91
-
92
- const db = client.db('myapp');
93
- const users = db.collection('users');
94
-
95
- // Safe: Validate search criteria structure
96
- const allowedFields = ['name', 'email', 'department'];
97
- const sanitizedCriteria = {};
98
-
99
- for (const [key, value] of Object.entries(searchCriteria)) {
100
- if (allowedFields.includes(key) && typeof value === 'string') {
101
- sanitizedCriteria[key] = { $regex: value, $options: 'i' };
102
- }
103
- }
104
-
105
- const users_result = await users.find(sanitizedCriteria).toArray();
106
-
107
- await client.close();
108
- return users_result;
109
- }
110
-
111
- // ❌ Bad: Vulnerable to SQL injection
112
- async function vulnerableGetUser(userId) {
113
- const connection = await mysql.createConnection(dbConfig);
114
-
115
- // Dangerous: Direct string concatenation
116
- const query = `SELECT * FROM users WHERE id = ${userId}`;
117
- const [rows] = await connection.execute(query);
118
-
119
- return rows[0];
120
- }
121
-
122
- // ❌ Bad: Vulnerable to NoSQL injection
123
- async function vulnerableSearchMongo(userInput) {
124
- const client = new MongoClient(mongoUrl);
125
- await client.connect();
126
-
127
- const db = client.db('myapp');
128
- const users = db.collection('users');
129
-
130
- // Dangerous: Direct use of user input
131
- const result = await users.find(userInput).toArray();
132
-
133
- return result;
134
- }
135
- ```
136
-
137
- ### 2. Cross-Site Scripting (XSS) | 跨站脚本攻击
138
-
139
- ```javascript
140
- // ✅ Good: XSS Prevention
141
- const DOMPurify = require('dompurify');
142
- const { JSDOM } = require('jsdom');
143
-
144
- const window = new JSDOM('').window;
145
- const purify = DOMPurify(window);
146
-
147
- // Input sanitization
148
- function sanitizeHtml(dirty) {
149
- return purify.sanitize(dirty, {
150
- ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p', 'br'],
151
- ALLOWED_ATTR: []
152
- });
153
- }
154
-
155
- // Output encoding for different contexts
156
- function escapeHtml(unsafe) {
157
- return unsafe
158
- .replace(/&/g, "&")
159
- .replace(/</g, "&lt;")
160
- .replace(/>/g, "&gt;")
161
- .replace(/"/g, "&quot;")
162
- .replace(/'/g, "&#039;");
163
- }
164
-
165
- function escapeJavaScript(unsafe) {
166
- return unsafe
167
- .replace(/\\/g, "\\\\")
168
- .replace(/'/g, "\\'")
169
- .replace(/"/g, '\\"')
170
- .replace(/\n/g, "\\n")
171
- .replace(/\r/g, "\\r")
172
- .replace(/\t/g, "\\t");
173
- }
174
-
175
- // React component with proper escaping
176
- import React from 'react';
177
-
178
- function UserProfile({ user }) {
179
- return (
180
- <div>
181
- {/* Safe: React automatically escapes */}
182
- <h1>{user.name}</h1>
183
- <p>{user.bio}</p>
184
-
185
- {/* Safe: Sanitized HTML */}
186
- <div dangerouslySetInnerHTML={{
187
- __html: sanitizeHtml(user.description)
188
- }} />
189
-
190
- {/* Safe: URL validation */}
191
- {isValidUrl(user.website) && (
192
- <a href={user.website} target="_blank" rel="noopener noreferrer">
193
- {user.website}
194
- </a>
195
- )}
196
- </div>
197
- );
198
- }
199
-
200
- function isValidUrl(string) {
201
- try {
202
- const url = new URL(string);
203
- return url.protocol === 'http:' || url.protocol === 'https:';
204
- } catch (_) {
205
- return false;
206
- }
207
- }
208
-
209
- // ✅ Good: Content Security Policy
210
- app.use((req, res, next) => {
211
- res.setHeader(
212
- 'Content-Security-Policy',
213
- "default-src 'self'; " +
214
- "script-src 'self' 'unsafe-inline' https://trusted-cdn.com; " +
215
- "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " +
216
- "img-src 'self' data: https:; " +
217
- "font-src 'self' https://fonts.gstatic.com; " +
218
- "connect-src 'self' https://api.example.com; " +
219
- "frame-ancestors 'none';"
220
- );
221
- next();
222
- });
223
-
224
- // ❌ Bad: Vulnerable to XSS
225
- function vulnerableRender(userInput) {
226
- // Dangerous: Direct HTML insertion
227
- document.getElementById('content').innerHTML = userInput;
228
-
229
- // Dangerous: Unescaped output in template
230
- return `<div>${userInput}</div>`;
231
- }
232
-
233
- // ❌ Bad: Dangerous use of eval
234
- function vulnerableExecute(userCode) {
235
- // Extremely dangerous: Never use eval with user input
236
- eval(userCode);
237
- }
238
- ```
239
-
240
- ### 3. Authentication and Session Management | 身份验证和会话管理
241
-
242
- ```javascript
243
- // ✅ Good: Secure Authentication Implementation
244
- const bcrypt = require('bcrypt');
245
- const jwt = require('jsonwebtoken');
246
- const crypto = require('crypto');
247
- const rateLimit = require('express-rate-limit');
248
-
249
- // Password hashing
250
- async function hashPassword(password) {
251
- const saltRounds = 12; // Adjust based on security requirements
252
- return await bcrypt.hash(password, saltRounds);
253
- }
254
-
255
- async function verifyPassword(password, hashedPassword) {
256
- return await bcrypt.compare(password, hashedPassword);
257
- }
258
-
259
- // Secure password requirements
260
- function validatePassword(password) {
261
- const minLength = 8;
262
- const hasUpperCase = /[A-Z]/.test(password);
263
- const hasLowerCase = /[a-z]/.test(password);
264
- const hasNumbers = /\d/.test(password);
265
- const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password);
266
-
267
- const errors = [];
268
-
269
- if (password.length < minLength) {
270
- errors.push(`Password must be at least ${minLength} characters long`);
271
- }
272
-
273
- if (!hasUpperCase) {
274
- errors.push('Password must contain at least one uppercase letter');
275
- }
276
-
277
- if (!hasLowerCase) {
278
- errors.push('Password must contain at least one lowercase letter');
279
- }
280
-
281
- if (!hasNumbers) {
282
- errors.push('Password must contain at least one number');
283
- }
284
-
285
- if (!hasSpecialChar) {
286
- errors.push('Password must contain at least one special character');
287
- }
288
-
289
- return {
290
- isValid: errors.length === 0,
291
- errors
292
- };
293
- }
294
-
295
- // JWT token management
296
- const JWT_SECRET = process.env.JWT_SECRET || crypto.randomBytes(64).toString('hex');
297
- const JWT_REFRESH_SECRET = process.env.JWT_REFRESH_SECRET || crypto.randomBytes(64).toString('hex');
298
-
299
- function generateTokens(userId) {
300
- const accessToken = jwt.sign(
301
- { userId, type: 'access' },
302
- JWT_SECRET,
303
- { expiresIn: '15m' }
304
- );
305
-
306
- const refreshToken = jwt.sign(
307
- { userId, type: 'refresh' },
308
- JWT_REFRESH_SECRET,
309
- { expiresIn: '7d' }
310
- );
311
-
312
- return { accessToken, refreshToken };
313
- }
314
-
315
- function verifyAccessToken(token) {
316
- try {
317
- const decoded = jwt.verify(token, JWT_SECRET);
318
- if (decoded.type !== 'access') {
319
- throw new Error('Invalid token type');
320
- }
321
- return decoded;
322
- } catch (error) {
323
- throw new Error('Invalid or expired token');
324
- }
325
- }
326
-
327
- // Rate limiting for authentication
328
- const loginLimiter = rateLimit({
329
- windowMs: 15 * 60 * 1000, // 15 minutes
330
- max: 5, // Limit each IP to 5 requests per windowMs
331
- message: 'Too many login attempts, please try again later',
332
- standardHeaders: true,
333
- legacyHeaders: false,
334
- });
335
-
336
- // Secure login endpoint
337
- app.post('/login', loginLimiter, async (req, res) => {
338
- try {
339
- const { email, password } = req.body;
340
-
341
- // Input validation
342
- if (!email || !password) {
343
- return res.status(400).json({ error: 'Email and password are required' });
344
- }
345
-
346
- // Find user
347
- const user = await User.findOne({ email: email.toLowerCase() });
348
- if (!user) {
349
- // Don't reveal whether user exists
350
- return res.status(401).json({ error: 'Invalid credentials' });
351
- }
352
-
353
- // Check if account is locked
354
- if (user.lockUntil && user.lockUntil > Date.now()) {
355
- return res.status(423).json({ error: 'Account temporarily locked' });
356
- }
357
-
358
- // Verify password
359
- const isValidPassword = await verifyPassword(password, user.passwordHash);
360
-
361
- if (!isValidPassword) {
362
- // Increment failed attempts
363
- await user.incFailedAttempts();
364
- return res.status(401).json({ error: 'Invalid credentials' });
365
- }
366
-
367
- // Reset failed attempts on successful login
368
- await user.resetFailedAttempts();
369
-
370
- // Generate tokens
371
- const { accessToken, refreshToken } = generateTokens(user._id);
372
-
373
- // Store refresh token securely
374
- await user.updateRefreshToken(refreshToken);
375
-
376
- // Set secure cookie
377
- res.cookie('refreshToken', refreshToken, {
378
- httpOnly: true,
379
- secure: process.env.NODE_ENV === 'production',
380
- sameSite: 'strict',
381
- maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
382
- });
383
-
384
- res.json({
385
- accessToken,
386
- user: {
387
- id: user._id,
388
- email: user.email,
389
- name: user.name
390
- }
391
- });
392
-
393
- } catch (error) {
394
- console.error('Login error:', error);
395
- res.status(500).json({ error: 'Internal server error' });
396
- }
397
- });
398
-
399
- // Multi-factor authentication
400
- const speakeasy = require('speakeasy');
401
- const QRCode = require('qrcode');
402
-
403
- async function setupTwoFactor(userId) {
404
- const secret = speakeasy.generateSecret({
405
- name: `MyApp (${userId})`,
406
- issuer: 'MyApp'
407
- });
408
-
409
- // Store secret temporarily (user must verify before enabling)
410
- await User.findByIdAndUpdate(userId, {
411
- tempTwoFactorSecret: secret.base32
412
- });
413
-
414
- // Generate QR code
415
- const qrCodeUrl = await QRCode.toDataURL(secret.otpauth_url);
416
-
417
- return {
418
- secret: secret.base32,
419
- qrCode: qrCodeUrl
420
- };
421
- }
422
-
423
- function verifyTwoFactor(token, secret) {
424
- return speakeasy.totp.verify({
425
- secret,
426
- encoding: 'base32',
427
- token,
428
- window: 2 // Allow some time drift
429
- });
430
- }
431
-
432
- // ❌ Bad: Insecure authentication
433
- async function insecureLogin(email, password) {
434
- // Bad: Plain text password storage
435
- const user = await User.findOne({ email, password });
436
-
437
- // Bad: Weak JWT secret
438
- const token = jwt.sign({ userId: user.id }, 'secret123');
439
-
440
- // Bad: No rate limiting, no input validation
441
- return { token };
442
- }
443
- ```
444
-
445
- ### 4. Access Control and Authorization | 访问控制和授权
446
-
447
- ```javascript
448
- // ✅ Good: Role-Based Access Control (RBAC)
449
- const permissions = {
450
- 'user:read': ['admin', 'manager', 'user'],
451
- 'user:write': ['admin', 'manager'],
452
- 'user:delete': ['admin'],
453
- 'report:read': ['admin', 'manager'],
454
- 'report:write': ['admin', 'manager'],
455
- 'system:admin': ['admin']
456
- };
457
-
458
- function hasPermission(userRole, permission) {
459
- return permissions[permission]?.includes(userRole) || false;
460
- }
461
-
462
- // Middleware for permission checking
463
- function requirePermission(permission) {
464
- return (req, res, next) => {
465
- const user = req.user; // Set by authentication middleware
466
-
467
- if (!user) {
468
- return res.status(401).json({ error: 'Authentication required' });
469
- }
470
-
471
- if (!hasPermission(user.role, permission)) {
472
- return res.status(403).json({ error: 'Insufficient permissions' });
473
- }
474
-
475
- next();
476
- };
477
- }
478
-
479
- // Resource-based authorization
480
- async function canAccessResource(userId, resourceId, action) {
481
- const resource = await Resource.findById(resourceId);
482
-
483
- if (!resource) {
484
- return false;
485
- }
486
-
487
- // Owner can do anything
488
- if (resource.ownerId.toString() === userId.toString()) {
489
- return true;
490
- }
491
-
492
- // Check shared permissions
493
- const permission = await Permission.findOne({
494
- resourceId,
495
- userId,
496
- action: { $in: [action, 'all'] }
497
- });
498
-
499
- return !!permission;
500
- }
501
-
502
- // API endpoint with proper authorization
503
- app.get('/api/users/:id',
504
- authenticateToken,
505
- requirePermission('user:read'),
506
- async (req, res) => {
507
- try {
508
- const requestedUserId = req.params.id;
509
- const currentUserId = req.user.id;
510
-
511
- // Users can only access their own data unless they have admin role
512
- if (requestedUserId !== currentUserId && req.user.role !== 'admin') {
513
- return res.status(403).json({ error: 'Access denied' });
514
- }
515
-
516
- const user = await User.findById(requestedUserId);
517
- if (!user) {
518
- return res.status(404).json({ error: 'User not found' });
519
- }
520
-
521
- // Filter sensitive data based on permissions
522
- const userData = filterUserData(user, req.user.role);
523
-
524
- res.json(userData);
525
- } catch (error) {
526
- console.error('Error fetching user:', error);
527
- res.status(500).json({ error: 'Internal server error' });
528
- }
529
- }
530
- );
531
-
532
- function filterUserData(user, viewerRole) {
533
- const baseData = {
534
- id: user._id,
535
- name: user.name,
536
- email: user.email
537
- };
538
-
539
- // Admin can see everything
540
- if (viewerRole === 'admin') {
541
- return {
542
- ...baseData,
543
- role: user.role,
544
- createdAt: user.createdAt,
545
- lastLogin: user.lastLogin,
546
- isActive: user.isActive
547
- };
548
- }
549
-
550
- // Regular users see limited data
551
- return baseData;
552
- }
553
-
554
- // ✅ Good: Attribute-Based Access Control (ABAC)
555
- class AccessControlEngine {
556
- constructor() {
557
- this.policies = [];
558
- }
559
-
560
- addPolicy(policy) {
561
- this.policies.push(policy);
562
- }
563
-
564
- async evaluate(subject, action, resource, context = {}) {
565
- for (const policy of this.policies) {
566
- const result = await policy.evaluate(subject, action, resource, context);
567
- if (result === 'deny') {
568
- return false;
569
- }
570
- if (result === 'allow') {
571
- return true;
572
- }
573
- }
574
-
575
- // Default deny
576
- return false;
577
- }
578
- }
579
-
580
- class Policy {
581
- constructor(name, condition, effect) {
582
- this.name = name;
583
- this.condition = condition;
584
- this.effect = effect; // 'allow' or 'deny'
585
- }
586
-
587
- async evaluate(subject, action, resource, context) {
588
- if (await this.condition(subject, action, resource, context)) {
589
- return this.effect;
590
- }
591
- return 'not_applicable';
592
- }
593
- }
594
-
595
- // Example policies
596
- const ownerPolicy = new Policy(
597
- 'owner-access',
598
- async (subject, action, resource) => {
599
- return resource.ownerId === subject.id;
600
- },
601
- 'allow'
602
- );
603
-
604
- const businessHoursPolicy = new Policy(
605
- 'business-hours-only',
606
- async (subject, action, resource, context) => {
607
- const hour = new Date().getHours();
608
- return hour >= 9 && hour <= 17; // 9 AM to 5 PM
609
- },
610
- 'allow'
611
- );
612
-
613
- const acEngine = new AccessControlEngine();
614
- acEngine.addPolicy(ownerPolicy);
615
- acEngine.addPolicy(businessHoursPolicy);
616
- ```
617
-
618
- ## Input Validation and Sanitization | 输入验证和清理
619
-
620
- ### 1. Comprehensive Input Validation | 全面输入验证
621
-
622
- ```javascript
623
- // ✅ Good: Input validation with Joi
624
- const Joi = require('joi');
625
-
626
- // User registration schema
627
- const userRegistrationSchema = Joi.object({
628
- name: Joi.string()
629
- .min(2)
630
- .max(50)
631
- .pattern(/^[a-zA-Z\s]+$/)
632
- .required()
633
- .messages({
634
- 'string.pattern.base': 'Name can only contain letters and spaces'
635
- }),
636
-
637
- email: Joi.string()
638
- .email({ minDomainSegments: 2 })
639
- .required()
640
- .lowercase(),
641
-
642
- password: Joi.string()
643
- .min(8)
644
- .max(128)
645
- .pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/)
646
- .required()
647
- .messages({
648
- 'string.pattern.base': 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character'
649
- }),
650
-
651
- age: Joi.number()
652
- .integer()
653
- .min(13)
654
- .max(120)
655
- .required(),
656
-
657
- phone: Joi.string()
658
- .pattern(/^\+?[\d\s\-\(\)]+$/)
659
- .optional(),
660
-
661
- website: Joi.string()
662
- .uri({ scheme: ['http', 'https'] })
663
- .optional()
664
- });
665
-
666
- // Validation middleware
667
- function validateInput(schema) {
668
- return (req, res, next) => {
669
- const { error, value } = schema.validate(req.body, {
670
- abortEarly: false,
671
- stripUnknown: true
672
- });
673
-
674
- if (error) {
675
- const errors = error.details.map(detail => ({
676
- field: detail.path.join('.'),
677
- message: detail.message
678
- }));
679
-
680
- return res.status(400).json({
681
- error: 'Validation failed',
682
- details: errors
683
- });
684
- }
685
-
686
- req.validatedData = value;
687
- next();
688
- };
689
- }
690
-
691
- // File upload validation
692
- const multer = require('multer');
693
- const path = require('path');
694
-
695
- const fileFilter = (req, file, cb) => {
696
- // Allowed file types
697
- const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
698
-
699
- if (allowedTypes.includes(file.mimetype)) {
700
- cb(null, true);
701
- } else {
702
- cb(new Error('Invalid file type. Only JPEG, PNG, GIF, and PDF files are allowed.'), false);
703
- }
704
- };
705
-
706
- const upload = multer({
707
- dest: 'uploads/',
708
- limits: {
709
- fileSize: 5 * 1024 * 1024, // 5MB limit
710
- files: 5 // Maximum 5 files
711
- },
712
- fileFilter
713
- });
714
-
715
- // API endpoint with validation
716
- app.post('/api/users',
717
- validateInput(userRegistrationSchema),
718
- async (req, res) => {
719
- try {
720
- const userData = req.validatedData;
721
-
722
- // Additional business logic validation
723
- const existingUser = await User.findOne({ email: userData.email });
724
- if (existingUser) {
725
- return res.status(409).json({ error: 'Email already registered' });
726
- }
727
-
728
- // Hash password
729
- userData.passwordHash = await hashPassword(userData.password);
730
- delete userData.password;
731
-
732
- const user = new User(userData);
733
- await user.save();
734
-
735
- res.status(201).json({
736
- message: 'User created successfully',
737
- user: {
738
- id: user._id,
739
- name: user.name,
740
- email: user.email
741
- }
742
- });
743
-
744
- } catch (error) {
745
- console.error('User creation error:', error);
746
- res.status(500).json({ error: 'Internal server error' });
747
- }
748
- }
749
- );
750
-
751
- // ✅ Good: SQL injection prevention with parameterized queries
752
- async function searchProducts(filters) {
753
- const { category, minPrice, maxPrice, searchTerm } = filters;
754
-
755
- let query = 'SELECT * FROM products WHERE 1=1';
756
- const params = [];
757
-
758
- if (category) {
759
- query += ' AND category = ?';
760
- params.push(category);
761
- }
762
-
763
- if (minPrice !== undefined) {
764
- query += ' AND price >= ?';
765
- params.push(minPrice);
766
- }
767
-
768
- if (maxPrice !== undefined) {
769
- query += ' AND price <= ?';
770
- params.push(maxPrice);
771
- }
772
-
773
- if (searchTerm) {
774
- query += ' AND (name LIKE ? OR description LIKE ?)';
775
- params.push(`%${searchTerm}%`, `%${searchTerm}%`);
776
- }
777
-
778
- const [rows] = await connection.execute(query, params);
779
- return rows;
780
- }
781
-
782
- // ❌ Bad: No input validation
783
- app.post('/api/users', async (req, res) => {
784
- // Dangerous: No validation of input data
785
- const user = new User(req.body);
786
- await user.save();
787
- res.json(user);
788
- });
789
- ```
790
-
791
- ## Cryptography and Data Protection | 密码学和数据保护
792
-
793
- ### 1. Encryption and Hashing | 加密和哈希
794
-
795
- ```javascript
796
- // ✅ Good: Proper encryption implementation
797
- const crypto = require('crypto');
798
-
799
- class EncryptionService {
800
- constructor() {
801
- this.algorithm = 'aes-256-gcm';
802
- this.keyLength = 32; // 256 bits
803
- this.ivLength = 16; // 128 bits
804
- this.tagLength = 16; // 128 bits
805
- }
806
-
807
- // Generate a random encryption key
808
- generateKey() {
809
- return crypto.randomBytes(this.keyLength);
810
- }
811
-
812
- // Encrypt data
813
- encrypt(plaintext, key) {
814
- const iv = crypto.randomBytes(this.ivLength);
815
- const cipher = crypto.createCipher(this.algorithm, key, iv);
816
-
817
- let encrypted = cipher.update(plaintext, 'utf8', 'hex');
818
- encrypted += cipher.final('hex');
819
-
820
- const tag = cipher.getAuthTag();
821
-
822
- // Return IV + tag + encrypted data
823
- return {
824
- iv: iv.toString('hex'),
825
- tag: tag.toString('hex'),
826
- encrypted: encrypted
827
- };
828
- }
829
-
830
- // Decrypt data
831
- decrypt(encryptedData, key) {
832
- const { iv, tag, encrypted } = encryptedData;
833
-
834
- const decipher = crypto.createDecipher(
835
- this.algorithm,
836
- key,
837
- Buffer.from(iv, 'hex')
838
- );
839
-
840
- decipher.setAuthTag(Buffer.from(tag, 'hex'));
841
-
842
- let decrypted = decipher.update(encrypted, 'hex', 'utf8');
843
- decrypted += decipher.final('utf8');
844
-
845
- return decrypted;
846
- }
847
-
848
- // Hash data with salt
849
- hashWithSalt(data, salt = null) {
850
- if (!salt) {
851
- salt = crypto.randomBytes(32);
852
- }
853
-
854
- const hash = crypto.pbkdf2Sync(data, salt, 100000, 64, 'sha512');
855
-
856
- return {
857
- hash: hash.toString('hex'),
858
- salt: salt.toString('hex')
859
- };
860
- }
861
-
862
- // Verify hash
863
- verifyHash(data, hash, salt) {
864
- const { hash: computedHash } = this.hashWithSalt(
865
- data,
866
- Buffer.from(salt, 'hex')
867
- );
868
-
869
- return crypto.timingSafeEqual(
870
- Buffer.from(hash, 'hex'),
871
- Buffer.from(computedHash, 'hex')
872
- );
873
- }
874
- }
875
-
876
- // ✅ Good: Secure random token generation
877
- function generateSecureToken(length = 32) {
878
- return crypto.randomBytes(length).toString('hex');
879
- }
880
-
881
- function generateApiKey() {
882
- const prefix = 'ak_';
883
- const randomPart = crypto.randomBytes(24).toString('base64url');
884
- return prefix + randomPart;
885
- }
886
-
887
- // ✅ Good: Digital signatures
888
- class SignatureService {
889
- constructor() {
890
- this.algorithm = 'sha256';
891
- }
892
-
893
- // Generate key pair
894
- generateKeyPair() {
895
- return crypto.generateKeyPairSync('rsa', {
896
- modulusLength: 2048,
897
- publicKeyEncoding: {
898
- type: 'spki',
899
- format: 'pem'
900
- },
901
- privateKeyEncoding: {
902
- type: 'pkcs8',
903
- format: 'pem'
904
- }
905
- });
906
- }
907
-
908
- // Sign data
909
- sign(data, privateKey) {
910
- const sign = crypto.createSign(this.algorithm);
911
- sign.update(data);
912
- return sign.sign(privateKey, 'hex');
913
- }
914
-
915
- // Verify signature
916
- verify(data, signature, publicKey) {
917
- const verify = crypto.createVerify(this.algorithm);
918
- verify.update(data);
919
- return verify.verify(publicKey, signature, 'hex');
920
- }
921
- }
922
-
923
- // ✅ Good: Secure session management
924
- const session = require('express-session');
925
- const MongoStore = require('connect-mongo');
926
-
927
- app.use(session({
928
- secret: process.env.SESSION_SECRET || crypto.randomBytes(64).toString('hex'),
929
- name: 'sessionId', // Don't use default name
930
- resave: false,
931
- saveUninitialized: false,
932
- store: MongoStore.create({
933
- mongoUrl: process.env.MONGODB_URI,
934
- touchAfter: 24 * 3600 // Lazy session update
935
- }),
936
- cookie: {
937
- secure: process.env.NODE_ENV === 'production', // HTTPS only in production
938
- httpOnly: true, // Prevent XSS
939
- maxAge: 1000 * 60 * 60 * 24, // 24 hours
940
- sameSite: 'strict' // CSRF protection
941
- }
942
- }));
943
-
944
- // ❌ Bad: Weak encryption
945
- function weakEncryption(data) {
946
- // Bad: Using deprecated algorithm
947
- const cipher = crypto.createCipher('des', 'weak-key');
948
- return cipher.update(data, 'utf8', 'hex') + cipher.final('hex');
949
- }
950
-
951
- // ❌ Bad: Predictable tokens
952
- function weakToken() {
953
- // Bad: Predictable timestamp-based token
954
- return Date.now().toString() + Math.random().toString();
955
- }
956
- ```
957
-
958
- ### 2. Secure Communication | 安全通信
959
-
960
- ```javascript
961
- // ✅ Good: HTTPS configuration
962
- const https = require('https');
963
- const fs = require('fs');
964
-
965
- // SSL/TLS configuration
966
- const httpsOptions = {
967
- key: fs.readFileSync('path/to/private-key.pem'),
968
- cert: fs.readFileSync('path/to/certificate.pem'),
969
- // Additional security options
970
- secureProtocol: 'TLSv1_2_method',
971
- ciphers: [
972
- 'ECDHE-RSA-AES128-GCM-SHA256',
973
- 'ECDHE-RSA-AES256-GCM-SHA384',
974
- 'ECDHE-RSA-AES128-SHA256',
975
- 'ECDHE-RSA-AES256-SHA384'
976
- ].join(':'),
977
- honorCipherOrder: true
978
- };
979
-
980
- const server = https.createServer(httpsOptions, app);
981
-
982
- // ✅ Good: Security headers middleware
983
- const helmet = require('helmet');
984
-
985
- app.use(helmet({
986
- contentSecurityPolicy: {
987
- directives: {
988
- defaultSrc: ["'self'"],
989
- styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
990
- fontSrc: ["'self'", "https://fonts.gstatic.com"],
991
- imgSrc: ["'self'", "data:", "https:"],
992
- scriptSrc: ["'self'"],
993
- connectSrc: ["'self'", "https://api.example.com"]
994
- }
995
- },
996
- hsts: {
997
- maxAge: 31536000,
998
- includeSubDomains: true,
999
- preload: true
1000
- }
1001
- }));
1002
-
1003
- // ✅ Good: API rate limiting
1004
- const rateLimit = require('express-rate-limit');
1005
-
1006
- const apiLimiter = rateLimit({
1007
- windowMs: 15 * 60 * 1000, // 15 minutes
1008
- max: 100, // Limit each IP to 100 requests per windowMs
1009
- message: 'Too many requests from this IP, please try again later.',
1010
- standardHeaders: true,
1011
- legacyHeaders: false,
1012
- });
1013
-
1014
- const strictLimiter = rateLimit({
1015
- windowMs: 15 * 60 * 1000,
1016
- max: 5, // Stricter limit for sensitive endpoints
1017
- skipSuccessfulRequests: true
1018
- });
1019
-
1020
- app.use('/api/', apiLimiter);
1021
- app.use('/api/auth/', strictLimiter);
1022
-
1023
- // ✅ Good: Request validation and sanitization
1024
- const validator = require('validator');
1025
-
1026
- function sanitizeInput(req, res, next) {
1027
- // Sanitize string inputs
1028
- for (const key in req.body) {
1029
- if (typeof req.body[key] === 'string') {
1030
- req.body[key] = validator.escape(req.body[key]);
1031
- }
1032
- }
1033
-
1034
- // Validate and sanitize specific fields
1035
- if (req.body.email) {
1036
- req.body.email = validator.normalizeEmail(req.body.email);
1037
- if (!validator.isEmail(req.body.email)) {
1038
- return res.status(400).json({ error: 'Invalid email format' });
1039
- }
1040
- }
1041
-
1042
- if (req.body.url) {
1043
- if (!validator.isURL(req.body.url, { protocols: ['http', 'https'] })) {
1044
- return res.status(400).json({ error: 'Invalid URL format' });
1045
- }
1046
- }
1047
-
1048
- next();
1049
- }
1050
-
1051
- app.use(sanitizeInput);
1052
- ```
1053
-
1054
- ## Security Testing and Monitoring | 安全测试和监控
1055
-
1056
- ### 1. Security Testing | 安全测试
1057
-
1058
- ```javascript
1059
- // ✅ Good: Security-focused unit tests
1060
- describe('Authentication Security', () => {
1061
- describe('Password validation', () => {
1062
- it('should reject weak passwords', () => {
1063
- const weakPasswords = [
1064
- 'password',
1065
- '123456',
1066
- 'qwerty',
1067
- 'abc123',
1068
- 'password123'
1069
- ];
1070
-
1071
- weakPasswords.forEach(password => {
1072
- const result = validatePassword(password);
1073
- expect(result.isValid).toBe(false);
1074
- });
1075
- });
1076
-
1077
- it('should accept strong passwords', () => {
1078
- const strongPasswords = [
1079
- 'MyStr0ng!Pass',
1080
- 'C0mplex@Password123',
1081
- 'Secure#Pass2023!'
1082
- ];
1083
-
1084
- strongPasswords.forEach(password => {
1085
- const result = validatePassword(password);
1086
- expect(result.isValid).toBe(true);
1087
- });
1088
- });
1089
- });
1090
-
1091
- describe('SQL injection prevention', () => {
1092
- it('should handle malicious input safely', async () => {
1093
- const maliciousInputs = [
1094
- "'; DROP TABLE users; --",
1095
- "1' OR '1'='1",
1096
- "admin'/*",
1097
- "1; DELETE FROM users WHERE 1=1; --"
1098
- ];
1099
-
1100
- for (const input of maliciousInputs) {
1101
- const result = await getUserById(input);
1102
- expect(result).toBeNull(); // Should not return any data
1103
- }
1104
- });
1105
- });
1106
-
1107
- describe('XSS prevention', () => {
1108
- it('should sanitize HTML input', () => {
1109
- const maliciousInputs = [
1110
- '<script>alert("XSS")</script>',
1111
- '<img src="x" onerror="alert(1)">',
1112
- 'javascript:alert("XSS")',
1113
- '<svg onload="alert(1)">'
1114
- ];
1115
-
1116
- maliciousInputs.forEach(input => {
1117
- const sanitized = sanitizeHtml(input);
1118
- expect(sanitized).not.toContain('<script>');
1119
- expect(sanitized).not.toContain('javascript:');
1120
- expect(sanitized).not.toContain('onerror');
1121
- expect(sanitized).not.toContain('onload');
1122
- });
1123
- });
1124
- });
1125
- });
1126
-
1127
- // ✅ Good: Penetration testing helpers
1128
- class SecurityTester {
1129
- constructor(baseUrl) {
1130
- this.baseUrl = baseUrl;
1131
- }
1132
-
1133
- async testSqlInjection(endpoint, params) {
1134
- const sqlPayloads = [
1135
- "' OR '1'='1",
1136
- "'; DROP TABLE users; --",
1137
- "1' UNION SELECT * FROM users --",
1138
- "admin'/*"
1139
- ];
1140
-
1141
- const results = [];
1142
-
1143
- for (const payload of sqlPayloads) {
1144
- try {
1145
- const testParams = { ...params };
1146
- // Inject payload into each parameter
1147
- for (const key in testParams) {
1148
- testParams[key] = payload;
1149
-
1150
- const response = await fetch(`${this.baseUrl}${endpoint}`, {
1151
- method: 'POST',
1152
- headers: { 'Content-Type': 'application/json' },
1153
- body: JSON.stringify(testParams)
1154
- });
1155
-
1156
- results.push({
1157
- payload,
1158
- parameter: key,
1159
- status: response.status,
1160
- vulnerable: response.status === 200 && response.headers.get('content-length') > 1000
1161
- });
1162
- }
1163
- } catch (error) {
1164
- results.push({
1165
- payload,
1166
- error: error.message
1167
- });
1168
- }
1169
- }
1170
-
1171
- return results;
1172
- }
1173
-
1174
- async testXss(endpoint, params) {
1175
- const xssPayloads = [
1176
- '<script>alert("XSS")</script>',
1177
- '<img src="x" onerror="alert(1)">',
1178
- 'javascript:alert("XSS")',
1179
- '<svg onload="alert(1)">'
1180
- ];
1181
-
1182
- const results = [];
1183
-
1184
- for (const payload of xssPayloads) {
1185
- const testParams = { ...params };
1186
-
1187
- for (const key in testParams) {
1188
- testParams[key] = payload;
1189
-
1190
- const response = await fetch(`${this.baseUrl}${endpoint}`, {
1191
- method: 'POST',
1192
- headers: { 'Content-Type': 'application/json' },
1193
- body: JSON.stringify(testParams)
1194
- });
1195
-
1196
- const responseText = await response.text();
1197
-
1198
- results.push({
1199
- payload,
1200
- parameter: key,
1201
- vulnerable: responseText.includes(payload) && !responseText.includes('&lt;script&gt;')
1202
- });
1203
- }
1204
- }
1205
-
1206
- return results;
1207
- }
1208
- }
1209
- ```
1210
-
1211
- ### 2. Security Monitoring | 安全监控
1212
-
1213
- ```javascript
1214
- // ✅ Good: Security event logging
1215
- const winston = require('winston');
1216
-
1217
- const securityLogger = winston.createLogger({
1218
- level: 'info',
1219
- format: winston.format.combine(
1220
- winston.format.timestamp(),
1221
- winston.format.errors({ stack: true }),
1222
- winston.format.json()
1223
- ),
1224
- transports: [
1225
- new winston.transports.File({ filename: 'logs/security.log' }),
1226
- new winston.transports.Console()
1227
- ]
1228
- });
1229
-
1230
- // Security event types
1231
- const SecurityEvents = {
1232
- LOGIN_SUCCESS: 'login_success',
1233
- LOGIN_FAILURE: 'login_failure',
1234
- LOGIN_BLOCKED: 'login_blocked',
1235
- PASSWORD_CHANGE: 'password_change',
1236
- PERMISSION_DENIED: 'permission_denied',
1237
- SUSPICIOUS_ACTIVITY: 'suspicious_activity',
1238
- DATA_ACCESS: 'data_access',
1239
- ADMIN_ACTION: 'admin_action'
1240
- };
1241
-
1242
- function logSecurityEvent(eventType, details) {
1243
- securityLogger.info({
1244
- event: eventType,
1245
- timestamp: new Date().toISOString(),
1246
- ...details
1247
- });
1248
- }
1249
-
1250
- // Middleware for security logging
1251
- function securityLoggingMiddleware(req, res, next) {
1252
- const originalSend = res.send;
1253
-
1254
- res.send = function(data) {
1255
- // Log failed authentication attempts
1256
- if (res.statusCode === 401) {
1257
- logSecurityEvent(SecurityEvents.LOGIN_FAILURE, {
1258
- ip: req.ip,
1259
- userAgent: req.get('User-Agent'),
1260
- endpoint: req.path,
1261
- method: req.method
1262
- });
1263
- }
1264
-
1265
- // Log permission denied
1266
- if (res.statusCode === 403) {
1267
- logSecurityEvent(SecurityEvents.PERMISSION_DENIED, {
1268
- ip: req.ip,
1269
- userId: req.user?.id,
1270
- endpoint: req.path,
1271
- method: req.method
1272
- });
1273
- }
1274
-
1275
- originalSend.call(this, data);
1276
- };
1277
-
1278
- next();
1279
- }
1280
-
1281
- // ✅ Good: Intrusion detection
1282
- class IntrusionDetector {
1283
- constructor() {
1284
- this.suspiciousPatterns = [
1285
- /(\bor\b|\band\b).*=.*=/i, // SQL injection patterns
1286
- /<script[^>]*>.*?<\/script>/i, // XSS patterns
1287
- /javascript:/i,
1288
- /vbscript:/i,
1289
- /onload|onerror|onclick/i,
1290
- /\.\.\//g, // Path traversal
1291
- /\/etc\/passwd/i,
1292
- /cmd\.exe|powershell/i
1293
- ];
1294
-
1295
- this.rateLimits = new Map();
1296
- }
1297
-
1298
- analyzeRequest(req) {
1299
- const threats = [];
1300
-
1301
- // Check for suspicious patterns in all input
1302
- const inputs = [
1303
- ...Object.values(req.query || {}),
1304
- ...Object.values(req.body || {}),
1305
- req.get('User-Agent') || '',
1306
- req.get('Referer') || ''
1307
- ];
1308
-
1309
- for (const input of inputs) {
1310
- if (typeof input === 'string') {
1311
- for (const pattern of this.suspiciousPatterns) {
1312
- if (pattern.test(input)) {
1313
- threats.push({
1314
- type: 'suspicious_pattern',
1315
- pattern: pattern.toString(),
1316
- input: input.substring(0, 100) // Truncate for logging
1317
- });
1318
- }
1319
- }
1320
- }
1321
- }
1322
-
1323
- // Rate limiting check
1324
- const clientId = req.ip;
1325
- const now = Date.now();
1326
- const windowMs = 60000; // 1 minute
1327
- const maxRequests = 100;
1328
-
1329
- if (!this.rateLimits.has(clientId)) {
1330
- this.rateLimits.set(clientId, []);
1331
- }
1332
-
1333
- const requests = this.rateLimits.get(clientId);
1334
- const recentRequests = requests.filter(time => now - time < windowMs);
1335
-
1336
- if (recentRequests.length >= maxRequests) {
1337
- threats.push({
1338
- type: 'rate_limit_exceeded',
1339
- requestCount: recentRequests.length,
1340
- windowMs
1341
- });
1342
- }
1343
-
1344
- recentRequests.push(now);
1345
- this.rateLimits.set(clientId, recentRequests);
1346
-
1347
- return threats;
1348
- }
1349
- }
1350
-
1351
- const intrusionDetector = new IntrusionDetector();
1352
-
1353
- app.use((req, res, next) => {
1354
- const threats = intrusionDetector.analyzeRequest(req);
1355
-
1356
- if (threats.length > 0) {
1357
- logSecurityEvent(SecurityEvents.SUSPICIOUS_ACTIVITY, {
1358
- ip: req.ip,
1359
- userAgent: req.get('User-Agent'),
1360
- endpoint: req.path,
1361
- method: req.method,
1362
- threats
1363
- });
1364
-
1365
- // Block request if high-risk threats detected
1366
- const highRiskThreats = threats.filter(t =>
1367
- t.type === 'suspicious_pattern' || t.type === 'rate_limit_exceeded'
1368
- );
1369
-
1370
- if (highRiskThreats.length > 0) {
1371
- return res.status(429).json({ error: 'Request blocked due to suspicious activity' });
1372
- }
1373
- }
1374
-
1375
- next();
1376
- });
1377
- ```
1378
-
1379
- ## Security Checklist | 安全检查清单
1380
-
1381
- - [ ] Input validation is implemented for all user inputs
1382
- - [ ] SQL injection prevention with parameterized queries
1383
- - [ ] XSS prevention with proper output encoding
1384
- - [ ] Authentication uses strong password requirements
1385
- - [ ] Multi-factor authentication is available for sensitive accounts
1386
- - [ ] Authorization checks are implemented at all levels
1387
- - [ ] Sensitive data is encrypted at rest and in transit
1388
- - [ ] Security headers are properly configured
1389
- - [ ] Rate limiting is implemented for API endpoints
1390
- - [ ] Security logging and monitoring are in place
1391
- - [ ] Regular security testing and code reviews
1392
- - [ ] Dependencies are regularly updated and scanned for vulnerabilities
1393
- - [ ] Error messages don't reveal sensitive information
1394
- - [ ] Session management is secure
1395
- - [ ] File uploads are properly validated and sandboxed
1396
-
1397
- ## 安全检查清单
1398
-
1399
- - [ ] 对所有用户输入实施输入验证
1400
- - [ ] 使用参数化查询防止 SQL 注入
1401
- - [ ] 通过适当的输出编码防止 XSS
1402
- - [ ] 身份验证使用强密码要求
1403
- - [ ] 敏感账户可使用多因素身份验证
1404
- - [ ] 在所有级别实施授权检查
1405
- - [ ] 敏感数据在静态和传输中加密
1406
- - [ ] 正确配置安全标头
1407
- - [ ] 为 API 端点实施速率限制
1408
- - [ ] 建立安全日志记录和监控
1409
- - [ ] 定期进行安全测试和代码审查
1410
- - [ ] 定期更新依赖项并扫描漏洞
1411
- - [ ] 错误消息不泄露敏感信息
1412
- - [ ] 会话管理安全
1413
- - [ ] 文件上传经过适当验证和沙箱化