ccjk 14.2.2 → 15.1.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 (532) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +75 -338
  3. package/dist/cli.js +89 -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 +165 -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 +42 -0
  16. package/dist/commands/menu.js.map +1 -0
  17. package/dist/commands/profile.js +138 -0
  18. package/dist/commands/profile.js.map +1 -0
  19. package/dist/core/detect.js +24 -0
  20. package/dist/core/detect.js.map +1 -0
  21. package/dist/core/lint.js +49 -0
  22. package/dist/core/lint.js.map +1 -0
  23. package/dist/core/mcp.js +41 -0
  24. package/dist/core/mcp.js.map +1 -0
  25. package/dist/core/paths.js +9 -0
  26. package/dist/core/paths.js.map +1 -0
  27. package/dist/core/profiles.js +104 -0
  28. package/dist/core/profiles.js.map +1 -0
  29. package/dist/core/providers.js +53 -0
  30. package/dist/core/providers.js.map +1 -0
  31. package/dist/core/settings.js +31 -0
  32. package/dist/core/settings.js.map +1 -0
  33. package/dist/core/slash-templates.js +56 -0
  34. package/dist/core/slash-templates.js.map +1 -0
  35. package/dist/core/tools.js +27 -0
  36. package/dist/core/tools.js.map +1 -0
  37. package/package.json +43 -164
  38. package/README.HONEST.md +0 -176
  39. package/README.en.md +0 -67
  40. package/README.ja.md +0 -67
  41. package/README.ko.md +0 -67
  42. package/README.zh-CN.md +0 -86
  43. package/bin/ccjk.mjs +0 -5
  44. package/bin/ccjk.ts +0 -222
  45. package/dist/chunks/agent-teams.mjs +0 -145
  46. package/dist/chunks/agent.mjs +0 -1439
  47. package/dist/chunks/agents.mjs +0 -3783
  48. package/dist/chunks/api-cli.mjs +0 -135
  49. package/dist/chunks/api-config-selector.mjs +0 -159
  50. package/dist/chunks/api-providers.mjs +0 -144
  51. package/dist/chunks/api.mjs +0 -115
  52. package/dist/chunks/auto-bootstrap.mjs +0 -358
  53. package/dist/chunks/auto-fixer.mjs +0 -95
  54. package/dist/chunks/auto-updater.mjs +0 -507
  55. package/dist/chunks/banner.mjs +0 -173
  56. package/dist/chunks/bash.mjs +0 -187
  57. package/dist/chunks/boost.mjs +0 -474
  58. package/dist/chunks/brain-config.mjs +0 -75
  59. package/dist/chunks/brain-status.mjs +0 -89
  60. package/dist/chunks/ccjk-agents.mjs +0 -416
  61. package/dist/chunks/ccjk-all.mjs +0 -1046
  62. package/dist/chunks/ccjk-config.mjs +0 -445
  63. package/dist/chunks/ccjk-hooks.mjs +0 -1074
  64. package/dist/chunks/ccjk-mcp.mjs +0 -763
  65. package/dist/chunks/ccjk-setup.mjs +0 -765
  66. package/dist/chunks/ccjk-skills.mjs +0 -518
  67. package/dist/chunks/ccr.mjs +0 -109
  68. package/dist/chunks/ccu.mjs +0 -40
  69. package/dist/chunks/check-updates.mjs +0 -117
  70. package/dist/chunks/claude-code-incremental-manager.mjs +0 -761
  71. package/dist/chunks/claude-config.mjs +0 -606
  72. package/dist/chunks/claude-config2.mjs +0 -62
  73. package/dist/chunks/claude-wrapper.mjs +0 -85
  74. package/dist/chunks/clavue-config.mjs +0 -1454
  75. package/dist/chunks/cleanup-migration.mjs +0 -20
  76. package/dist/chunks/cli-hook.mjs +0 -4096
  77. package/dist/chunks/cloud-sync.mjs +0 -29
  78. package/dist/chunks/code-type-resolver.mjs +0 -880
  79. package/dist/chunks/codex-config-switch.mjs +0 -452
  80. package/dist/chunks/codex-provider-manager.mjs +0 -238
  81. package/dist/chunks/codex-uninstaller.mjs +0 -404
  82. package/dist/chunks/codex.mjs +0 -2141
  83. package/dist/chunks/commands.mjs +0 -108
  84. package/dist/chunks/commands2.mjs +0 -421
  85. package/dist/chunks/commit.mjs +0 -140
  86. package/dist/chunks/completion.mjs +0 -517
  87. package/dist/chunks/config-consolidator.mjs +0 -172
  88. package/dist/chunks/config-switch.mjs +0 -334
  89. package/dist/chunks/config.mjs +0 -558
  90. package/dist/chunks/config2.mjs +0 -484
  91. package/dist/chunks/config3.mjs +0 -486
  92. package/dist/chunks/constants.mjs +0 -323
  93. package/dist/chunks/context-opt.mjs +0 -444
  94. package/dist/chunks/context.mjs +0 -974
  95. package/dist/chunks/dashboard.mjs +0 -481
  96. package/dist/chunks/doctor.mjs +0 -1301
  97. package/dist/chunks/eval.mjs +0 -502
  98. package/dist/chunks/evolution.mjs +0 -322
  99. package/dist/chunks/features.mjs +0 -715
  100. package/dist/chunks/fish.mjs +0 -181
  101. package/dist/chunks/fs-operations.mjs +0 -180
  102. package/dist/chunks/health-alerts.mjs +0 -830
  103. package/dist/chunks/help.mjs +0 -341
  104. package/dist/chunks/hook-installer.mjs +0 -48
  105. package/dist/chunks/impact.mjs +0 -651
  106. package/dist/chunks/index.mjs +0 -23
  107. package/dist/chunks/index10.mjs +0 -19
  108. package/dist/chunks/index11.mjs +0 -1171
  109. package/dist/chunks/index12.mjs +0 -218
  110. package/dist/chunks/index13.mjs +0 -679
  111. package/dist/chunks/index14.mjs +0 -1009
  112. package/dist/chunks/index15.mjs +0 -194
  113. package/dist/chunks/index2.mjs +0 -7637
  114. package/dist/chunks/index3.mjs +0 -171
  115. package/dist/chunks/index4.mjs +0 -26
  116. package/dist/chunks/index5.mjs +0 -19
  117. package/dist/chunks/index6.mjs +0 -19092
  118. package/dist/chunks/index7.mjs +0 -616
  119. package/dist/chunks/index8.mjs +0 -1602
  120. package/dist/chunks/index9.mjs +0 -5384
  121. package/dist/chunks/init.mjs +0 -1911
  122. package/dist/chunks/installer.mjs +0 -757
  123. package/dist/chunks/installer2.mjs +0 -103
  124. package/dist/chunks/interview.mjs +0 -2927
  125. package/dist/chunks/json-config.mjs +0 -60
  126. package/dist/chunks/linux.mjs +0 -3863
  127. package/dist/chunks/macos.mjs +0 -69
  128. package/dist/chunks/main.mjs +0 -635
  129. package/dist/chunks/manager.mjs +0 -1048
  130. package/dist/chunks/marketplace.mjs +0 -265
  131. package/dist/chunks/mcp-cli.mjs +0 -205
  132. package/dist/chunks/mcp-performance.mjs +0 -187
  133. package/dist/chunks/mcp.mjs +0 -667
  134. package/dist/chunks/memory-check.mjs +0 -2973
  135. package/dist/chunks/memory-paths.mjs +0 -259
  136. package/dist/chunks/memory-sync.mjs +0 -209
  137. package/dist/chunks/memory.mjs +0 -354
  138. package/dist/chunks/metrics-display.mjs +0 -153
  139. package/dist/chunks/monitor.mjs +0 -1856
  140. package/dist/chunks/notification.mjs +0 -1864
  141. package/dist/chunks/onboarding.mjs +0 -386
  142. package/dist/chunks/package.mjs +0 -3
  143. package/dist/chunks/paradigm.mjs +0 -74
  144. package/dist/chunks/permission-manager.mjs +0 -250
  145. package/dist/chunks/permissions.mjs +0 -265
  146. package/dist/chunks/persistence-manager.mjs +0 -801
  147. package/dist/chunks/persistence.mjs +0 -707
  148. package/dist/chunks/platform.mjs +0 -395
  149. package/dist/chunks/plugin.mjs +0 -1936
  150. package/dist/chunks/powershell.mjs +0 -213
  151. package/dist/chunks/prompts.mjs +0 -244
  152. package/dist/chunks/providers.mjs +0 -263
  153. package/dist/chunks/quick-actions.mjs +0 -335
  154. package/dist/chunks/quick-provider.mjs +0 -755
  155. package/dist/chunks/quick-setup.mjs +0 -421
  156. package/dist/chunks/remote.mjs +0 -497
  157. package/dist/chunks/research.mjs +0 -1904
  158. package/dist/chunks/rollback.mjs +0 -38
  159. package/dist/chunks/session-manager.mjs +0 -1371
  160. package/dist/chunks/session.mjs +0 -878
  161. package/dist/chunks/sessions.mjs +0 -106
  162. package/dist/chunks/silent-updater.mjs +0 -396
  163. package/dist/chunks/simple-config.mjs +0 -122
  164. package/dist/chunks/skill.mjs +0 -117
  165. package/dist/chunks/skill2.mjs +0 -9052
  166. package/dist/chunks/skills-sync.mjs +0 -1343
  167. package/dist/chunks/skills.mjs +0 -577
  168. package/dist/chunks/slash-commands.mjs +0 -208
  169. package/dist/chunks/smart-guide.mjs +0 -247
  170. package/dist/chunks/snapshot.mjs +0 -58
  171. package/dist/chunks/startup.mjs +0 -487
  172. package/dist/chunks/stats.mjs +0 -191
  173. package/dist/chunks/status.mjs +0 -471
  174. package/dist/chunks/team.mjs +0 -63
  175. package/dist/chunks/thinking.mjs +0 -626
  176. package/dist/chunks/trace.mjs +0 -57
  177. package/dist/chunks/uninstall.mjs +0 -852
  178. package/dist/chunks/update.mjs +0 -174
  179. package/dist/chunks/upgrade-manager.mjs +0 -204
  180. package/dist/chunks/upgrade.mjs +0 -133
  181. package/dist/chunks/version-checker.mjs +0 -891
  182. package/dist/chunks/vim.mjs +0 -903
  183. package/dist/chunks/windows.mjs +0 -14
  184. package/dist/chunks/workflows.mjs +0 -633
  185. package/dist/chunks/wsl.mjs +0 -129
  186. package/dist/chunks/zero-config.mjs +0 -871
  187. package/dist/chunks/zsh.mjs +0 -182
  188. package/dist/cli.d.mts +0 -1
  189. package/dist/cli.d.ts +0 -1
  190. package/dist/cli.mjs +0 -2684
  191. package/dist/i18n/locales/en/agent-teams.json +0 -18
  192. package/dist/i18n/locales/en/agentBrowser.json +0 -80
  193. package/dist/i18n/locales/en/agents.json +0 -135
  194. package/dist/i18n/locales/en/api.json +0 -63
  195. package/dist/i18n/locales/en/ccjk-agents.json +0 -33
  196. package/dist/i18n/locales/en/ccjk-all.json +0 -23
  197. package/dist/i18n/locales/en/ccjk-skills.json +0 -22
  198. package/dist/i18n/locales/en/ccjk.json +0 -276
  199. package/dist/i18n/locales/en/ccr.json +0 -65
  200. package/dist/i18n/locales/en/claude-md.json +0 -73
  201. package/dist/i18n/locales/en/cli.json +0 -148
  202. package/dist/i18n/locales/en/cloud-setup.json +0 -31
  203. package/dist/i18n/locales/en/cloud-sync.json +0 -147
  204. package/dist/i18n/locales/en/cloud.json +0 -40
  205. package/dist/i18n/locales/en/cloudPlugins.json +0 -118
  206. package/dist/i18n/locales/en/codex.json +0 -184
  207. package/dist/i18n/locales/en/cometix.json +0 -29
  208. package/dist/i18n/locales/en/common.json +0 -68
  209. package/dist/i18n/locales/en/config.json +0 -108
  210. package/dist/i18n/locales/en/configuration.json +0 -236
  211. package/dist/i18n/locales/en/context.json +0 -85
  212. package/dist/i18n/locales/en/dashboard.json +0 -78
  213. package/dist/i18n/locales/en/errors.json +0 -26
  214. package/dist/i18n/locales/en/evolution.json +0 -54
  215. package/dist/i18n/locales/en/hooks.json +0 -74
  216. package/dist/i18n/locales/en/hooksSync.json +0 -133
  217. package/dist/i18n/locales/en/installation.json +0 -83
  218. package/dist/i18n/locales/en/interview.json +0 -104
  219. package/dist/i18n/locales/en/language.json +0 -19
  220. package/dist/i18n/locales/en/lsp.json +0 -78
  221. package/dist/i18n/locales/en/marketplace.json +0 -116
  222. package/dist/i18n/locales/en/mcp.json +0 -180
  223. package/dist/i18n/locales/en/memory.json +0 -23
  224. package/dist/i18n/locales/en/menu.json +0 -299
  225. package/dist/i18n/locales/en/multi-config.json +0 -79
  226. package/dist/i18n/locales/en/notification.json +0 -307
  227. package/dist/i18n/locales/en/permissions.json +0 -95
  228. package/dist/i18n/locales/en/persistence.json +0 -127
  229. package/dist/i18n/locales/en/plugins.json +0 -146
  230. package/dist/i18n/locales/en/quick-actions.json +0 -78
  231. package/dist/i18n/locales/en/registry.json +0 -54
  232. package/dist/i18n/locales/en/remote.json +0 -93
  233. package/dist/i18n/locales/en/sandbox.json +0 -44
  234. package/dist/i18n/locales/en/setup.json +0 -44
  235. package/dist/i18n/locales/en/shencha.json +0 -14
  236. package/dist/i18n/locales/en/skills.json +0 -100
  237. package/dist/i18n/locales/en/skillsSync.json +0 -74
  238. package/dist/i18n/locales/en/smartGuide.json +0 -49
  239. package/dist/i18n/locales/en/stats.json +0 -20
  240. package/dist/i18n/locales/en/subagent.json +0 -69
  241. package/dist/i18n/locales/en/superpowers.json +0 -117
  242. package/dist/i18n/locales/en/team.json +0 -7
  243. package/dist/i18n/locales/en/thinking.json +0 -65
  244. package/dist/i18n/locales/en/tools.json +0 -42
  245. package/dist/i18n/locales/en/uninstall.json +0 -56
  246. package/dist/i18n/locales/en/updater.json +0 -29
  247. package/dist/i18n/locales/en/vim.json +0 -169
  248. package/dist/i18n/locales/en/workflow.json +0 -55
  249. package/dist/i18n/locales/en/workspace.json +0 -108
  250. package/dist/i18n/locales/zh-CN/agent-teams.json +0 -18
  251. package/dist/i18n/locales/zh-CN/agentBrowser.json +0 -80
  252. package/dist/i18n/locales/zh-CN/agents.json +0 -135
  253. package/dist/i18n/locales/zh-CN/api.json +0 -63
  254. package/dist/i18n/locales/zh-CN/ccjk-agents.json +0 -33
  255. package/dist/i18n/locales/zh-CN/ccjk-all.json +0 -23
  256. package/dist/i18n/locales/zh-CN/ccjk-skills.json +0 -22
  257. package/dist/i18n/locales/zh-CN/ccjk.json +0 -276
  258. package/dist/i18n/locales/zh-CN/ccr.json +0 -65
  259. package/dist/i18n/locales/zh-CN/claude-md.json +0 -73
  260. package/dist/i18n/locales/zh-CN/cli.json +0 -148
  261. package/dist/i18n/locales/zh-CN/cloud-setup.json +0 -31
  262. package/dist/i18n/locales/zh-CN/cloud-sync.json +0 -147
  263. package/dist/i18n/locales/zh-CN/cloud.json +0 -40
  264. package/dist/i18n/locales/zh-CN/cloudPlugins.json +0 -118
  265. package/dist/i18n/locales/zh-CN/codex.json +0 -184
  266. package/dist/i18n/locales/zh-CN/cometix.json +0 -29
  267. package/dist/i18n/locales/zh-CN/common.json +0 -68
  268. package/dist/i18n/locales/zh-CN/config.json +0 -108
  269. package/dist/i18n/locales/zh-CN/configuration.json +0 -234
  270. package/dist/i18n/locales/zh-CN/context.json +0 -85
  271. package/dist/i18n/locales/zh-CN/dashboard.json +0 -78
  272. package/dist/i18n/locales/zh-CN/errors.json +0 -26
  273. package/dist/i18n/locales/zh-CN/evolution.json +0 -54
  274. package/dist/i18n/locales/zh-CN/hooks.json +0 -74
  275. package/dist/i18n/locales/zh-CN/hooksSync.json +0 -133
  276. package/dist/i18n/locales/zh-CN/installation.json +0 -83
  277. package/dist/i18n/locales/zh-CN/interview.json +0 -104
  278. package/dist/i18n/locales/zh-CN/language.json +0 -19
  279. package/dist/i18n/locales/zh-CN/lsp.json +0 -78
  280. package/dist/i18n/locales/zh-CN/marketplace.json +0 -116
  281. package/dist/i18n/locales/zh-CN/mcp.json +0 -180
  282. package/dist/i18n/locales/zh-CN/memory.json +0 -23
  283. package/dist/i18n/locales/zh-CN/menu.json +0 -299
  284. package/dist/i18n/locales/zh-CN/multi-config.json +0 -79
  285. package/dist/i18n/locales/zh-CN/notification.json +0 -307
  286. package/dist/i18n/locales/zh-CN/permissions.json +0 -95
  287. package/dist/i18n/locales/zh-CN/persistence.json +0 -127
  288. package/dist/i18n/locales/zh-CN/plugins.json +0 -146
  289. package/dist/i18n/locales/zh-CN/quick-actions.json +0 -78
  290. package/dist/i18n/locales/zh-CN/registry.json +0 -54
  291. package/dist/i18n/locales/zh-CN/remote.json +0 -93
  292. package/dist/i18n/locales/zh-CN/sandbox.json +0 -44
  293. package/dist/i18n/locales/zh-CN/setup.json +0 -44
  294. package/dist/i18n/locales/zh-CN/shencha.json +0 -14
  295. package/dist/i18n/locales/zh-CN/skills.json +0 -100
  296. package/dist/i18n/locales/zh-CN/skillsSync.json +0 -74
  297. package/dist/i18n/locales/zh-CN/smartGuide.json +0 -49
  298. package/dist/i18n/locales/zh-CN/stats.json +0 -20
  299. package/dist/i18n/locales/zh-CN/subagent.json +0 -69
  300. package/dist/i18n/locales/zh-CN/superpowers.json +0 -117
  301. package/dist/i18n/locales/zh-CN/team.json +0 -7
  302. package/dist/i18n/locales/zh-CN/thinking.json +0 -65
  303. package/dist/i18n/locales/zh-CN/tools.json +0 -42
  304. package/dist/i18n/locales/zh-CN/uninstall.json +0 -56
  305. package/dist/i18n/locales/zh-CN/updater.json +0 -29
  306. package/dist/i18n/locales/zh-CN/vim.json +0 -169
  307. package/dist/i18n/locales/zh-CN/workflow.json +0 -55
  308. package/dist/i18n/locales/zh-CN/workspace.json +0 -108
  309. package/dist/index.d.mts +0 -5658
  310. package/dist/index.d.ts +0 -5658
  311. package/dist/index.mjs +0 -3732
  312. package/dist/shared/ccjk.5bEolFrk.mjs +0 -254
  313. package/dist/shared/ccjk.8oaxX4iR.mjs +0 -90
  314. package/dist/shared/ccjk.B2U7DsPy.mjs +0 -31
  315. package/dist/shared/ccjk.B2f-cwUP.mjs +0 -468
  316. package/dist/shared/ccjk.BAGoDD49.mjs +0 -36
  317. package/dist/shared/ccjk.BBtCGd_g.mjs +0 -899
  318. package/dist/shared/ccjk.BFQ7yr5S.mjs +0 -16
  319. package/dist/shared/ccjk.BLsIiTqO.mjs +0 -449
  320. package/dist/shared/ccjk.BXv8aYs1.mjs +0 -170
  321. package/dist/shared/ccjk.BnsY5WxD.mjs +0 -171
  322. package/dist/shared/ccjk.BoApaI4j.mjs +0 -28
  323. package/dist/shared/ccjk.Bq8TqZG_.mjs +0 -189
  324. package/dist/shared/ccjk.BtrioX1Z.mjs +0 -25
  325. package/dist/shared/ccjk.Bx_rmYfN.mjs +0 -69
  326. package/dist/shared/ccjk.BzPbSEP2.mjs +0 -115
  327. package/dist/shared/ccjk.C0WLUnFV.mjs +0 -293
  328. package/dist/shared/ccjk.C1hANZTu.mjs +0 -19
  329. package/dist/shared/ccjk.C2jHOZVP.mjs +0 -52
  330. package/dist/shared/ccjk.CNhnT6uQ.mjs +0 -636
  331. package/dist/shared/ccjk.COweQ1RR.mjs +0 -5
  332. package/dist/shared/ccjk.CfKKcvWy.mjs +0 -126
  333. package/dist/shared/ccjk.Cjgrln_h.mjs +0 -297
  334. package/dist/shared/ccjk.CoCHVXl3.mjs +0 -3951
  335. package/dist/shared/ccjk.CwGZSTAK.mjs +0 -319
  336. package/dist/shared/ccjk.CxpGa6MC.mjs +0 -2724
  337. package/dist/shared/ccjk.D-magaEx.mjs +0 -763
  338. package/dist/shared/ccjk.D0g2ABGg.mjs +0 -171
  339. package/dist/shared/ccjk.D6ycHbak.mjs +0 -270
  340. package/dist/shared/ccjk.D75wivnp.mjs +0 -142
  341. package/dist/shared/ccjk.DDL-4C-k.mjs +0 -100
  342. package/dist/shared/ccjk.DFRPtmK_.mjs +0 -75
  343. package/dist/shared/ccjk.DMV3x5Sd.mjs +0 -299
  344. package/dist/shared/ccjk.DZ2LLOa-.mjs +0 -2195
  345. package/dist/shared/ccjk.DbigonEQ.mjs +0 -698
  346. package/dist/shared/ccjk.DcMvE7lf.mjs +0 -618
  347. package/dist/shared/ccjk.DeWpAShp.mjs +0 -1828
  348. package/dist/shared/ccjk.DhJ1kyDR.mjs +0 -30
  349. package/dist/shared/ccjk.DlTXS9rP.mjs +0 -224
  350. package/dist/shared/ccjk.DopKzo3z.mjs +0 -305
  351. package/dist/shared/ccjk.DsZsc4LR.mjs +0 -1280
  352. package/dist/shared/ccjk.DuzJZlgj.mjs +0 -418
  353. package/dist/shared/ccjk.Dxgd2vjc.mjs +0 -444
  354. package/dist/shared/ccjk.J8YiPsOw.mjs +0 -259
  355. package/dist/shared/ccjk.KfSWcGlE.mjs +0 -38
  356. package/dist/shared/ccjk.L7yC58_i.mjs +0 -225
  357. package/dist/shared/ccjk.MwtjAULc.mjs +0 -1447
  358. package/dist/shared/ccjk.OJKHVSOb.mjs +0 -2005
  359. package/dist/shared/ccjk.OTnevPNE.mjs +0 -225
  360. package/dist/shared/ccjk.RyizuzOI.mjs +0 -21
  361. package/dist/shared/ccjk.T_cX87dY.mjs +0 -15
  362. package/dist/shared/ccjk.bQ7Dh1g4.mjs +0 -249
  363. package/dist/shared/ccjk.gDEDGD_t.mjs +0 -38
  364. package/dist/shared/ccjk.hoqrwWdN.mjs +0 -333
  365. package/dist/shared/ccjk.i_vn-9C3.mjs +0 -317
  366. package/dist/shared/ccjk.lG3ccFjm.mjs +0 -885
  367. package/dist/shared/ccjk.wLJHO0Af.mjs +0 -244
  368. package/dist/shared/ccjk.y-a_1vK4.mjs +0 -5127
  369. package/dist/templates/agents/README.md +0 -78
  370. package/dist/templates/agents/fullstack-developer.json +0 -70
  371. package/dist/templates/agents/go-expert.json +0 -69
  372. package/dist/templates/agents/index.json +0 -64
  373. package/dist/templates/agents/python-expert.json +0 -69
  374. package/dist/templates/agents/react-specialist.json +0 -69
  375. package/dist/templates/agents/testing-automation-expert.json +0 -70
  376. package/dist/templates/agents/typescript-architect.json +0 -69
  377. package/dist/templates/claude-code/common/settings.json +0 -109
  378. package/dist/templates/common/error-prevention.md +0 -267
  379. package/dist/templates/common/karpathy-baseline.md +0 -83
  380. package/dist/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
  381. package/dist/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
  382. package/dist/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
  383. package/dist/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
  384. package/dist/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
  385. package/dist/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
  386. package/dist/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
  387. package/dist/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
  388. package/dist/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
  389. package/dist/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
  390. package/dist/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
  391. package/dist/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
  392. package/dist/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
  393. package/dist/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
  394. package/dist/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
  395. package/dist/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
  396. package/dist/templates/common/workflow/essential/en/feat.md +0 -92
  397. package/dist/templates/common/workflow/essential/en/goal.md +0 -147
  398. package/dist/templates/common/workflow/essential/en/init-project.md +0 -53
  399. package/dist/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
  400. package/dist/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
  401. package/dist/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
  402. package/dist/templates/common/workflow/essential/zh-CN/feat.md +0 -315
  403. package/dist/templates/common/workflow/essential/zh-CN/goal.md +0 -146
  404. package/dist/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
  405. package/dist/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
  406. package/dist/templates/common/workflow/git/en/git-commit.md +0 -205
  407. package/dist/templates/common/workflow/git/en/git-rollback.md +0 -90
  408. package/dist/templates/common/workflow/git/en/git-worktree.md +0 -276
  409. package/dist/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
  410. package/dist/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
  411. package/dist/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
  412. package/dist/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
  413. package/dist/templates/common/workflow/interview/en/interview.md +0 -67
  414. package/dist/templates/common/workflow/interview/zh-CN/interview.md +0 -67
  415. package/dist/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
  416. package/dist/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
  417. package/dist/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
  418. package/dist/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
  419. package/dist/templates/common/workflow/sixStep/en/workflow.md +0 -83
  420. package/dist/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
  421. package/dist/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
  422. package/dist/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
  423. package/dist/templates/hooks/README.md +0 -212
  424. package/dist/templates/hooks/git-workflow-hooks.md +0 -551
  425. package/dist/templates/hooks/post-test/coverage.json +0 -21
  426. package/dist/templates/hooks/post-test/summary.json +0 -21
  427. package/dist/templates/hooks/post-test-coverage.md +0 -434
  428. package/dist/templates/hooks/pre-commit/eslint.json +0 -22
  429. package/dist/templates/hooks/pre-commit/prettier.json +0 -22
  430. package/dist/templates/hooks/pre-commit-black.md +0 -274
  431. package/dist/templates/hooks/pre-commit-eslint.md +0 -153
  432. package/dist/templates/hooks/pre-commit-gofmt.md +0 -284
  433. package/dist/templates/hooks/pre-commit-prettier.md +0 -212
  434. package/dist/templates/hooks/pre-commit-type-check.md +0 -377
  435. package/dist/templates/skills/ccjk-init.md +0 -154
  436. package/dist/templates/skills/ccjk-mcp-setup.md +0 -205
  437. package/dist/templates/skills/ccjk-troubleshoot.md +0 -228
  438. package/dist/templates/skills/django-patterns.md +0 -1016
  439. package/dist/templates/skills/git-workflow.md +0 -748
  440. package/dist/templates/skills/go-idioms.md +0 -963
  441. package/dist/templates/skills/index.json +0 -132
  442. package/dist/templates/skills/nextjs-optimization.md +0 -694
  443. package/dist/templates/skills/python-pep8.md +0 -852
  444. package/dist/templates/skills/react-patterns.md +0 -686
  445. package/dist/templates/skills/rust-patterns.md +0 -1057
  446. package/dist/templates/skills/security-best-practices.md +0 -1413
  447. package/dist/templates/skills/testing-best-practices.md +0 -1315
  448. package/dist/templates/skills/ts-best-practices.md +0 -354
  449. package/templates/agents/README.md +0 -78
  450. package/templates/agents/fullstack-developer.json +0 -70
  451. package/templates/agents/go-expert.json +0 -69
  452. package/templates/agents/index.json +0 -64
  453. package/templates/agents/python-expert.json +0 -69
  454. package/templates/agents/react-specialist.json +0 -69
  455. package/templates/agents/testing-automation-expert.json +0 -70
  456. package/templates/agents/typescript-architect.json +0 -69
  457. package/templates/claude-code/common/settings.json +0 -109
  458. package/templates/common/error-prevention.md +0 -267
  459. package/templates/common/karpathy-baseline.md +0 -83
  460. package/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
  461. package/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
  462. package/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
  463. package/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
  464. package/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
  465. package/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
  466. package/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
  467. package/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
  468. package/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
  469. package/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
  470. package/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
  471. package/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
  472. package/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
  473. package/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
  474. package/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
  475. package/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
  476. package/templates/common/workflow/essential/en/feat.md +0 -92
  477. package/templates/common/workflow/essential/en/goal.md +0 -147
  478. package/templates/common/workflow/essential/en/init-project.md +0 -53
  479. package/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
  480. package/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
  481. package/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
  482. package/templates/common/workflow/essential/zh-CN/feat.md +0 -315
  483. package/templates/common/workflow/essential/zh-CN/goal.md +0 -146
  484. package/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
  485. package/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
  486. package/templates/common/workflow/git/en/git-commit.md +0 -205
  487. package/templates/common/workflow/git/en/git-rollback.md +0 -90
  488. package/templates/common/workflow/git/en/git-worktree.md +0 -276
  489. package/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
  490. package/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
  491. package/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
  492. package/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
  493. package/templates/common/workflow/interview/en/interview.md +0 -67
  494. package/templates/common/workflow/interview/zh-CN/interview.md +0 -67
  495. package/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
  496. package/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
  497. package/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
  498. package/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
  499. package/templates/common/workflow/sixStep/en/workflow.md +0 -83
  500. package/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
  501. package/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
  502. package/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
  503. package/templates/hooks/README.md +0 -212
  504. package/templates/hooks/git-workflow-hooks.md +0 -551
  505. package/templates/hooks/post-test/coverage.json +0 -21
  506. package/templates/hooks/post-test/summary.json +0 -21
  507. package/templates/hooks/post-test-coverage.md +0 -434
  508. package/templates/hooks/pre-commit/eslint.json +0 -22
  509. package/templates/hooks/pre-commit/prettier.json +0 -22
  510. package/templates/hooks/pre-commit-black.md +0 -274
  511. package/templates/hooks/pre-commit-eslint.md +0 -153
  512. package/templates/hooks/pre-commit-gofmt.md +0 -284
  513. package/templates/hooks/pre-commit-prettier.md +0 -212
  514. package/templates/hooks/pre-commit-type-check.md +0 -377
  515. package/templates/skills/basic.hbs +0 -72
  516. package/templates/skills/ccjk-init.md +0 -154
  517. package/templates/skills/ccjk-mcp-setup.md +0 -205
  518. package/templates/skills/ccjk-troubleshoot.md +0 -228
  519. package/templates/skills/code-refactor.hbs +0 -133
  520. package/templates/skills/code-review.hbs +0 -141
  521. package/templates/skills/django-patterns.md +0 -1016
  522. package/templates/skills/git-workflow.md +0 -748
  523. package/templates/skills/go-idioms.md +0 -963
  524. package/templates/skills/index.json +0 -132
  525. package/templates/skills/nextjs-optimization.md +0 -694
  526. package/templates/skills/python-pep8.md +0 -852
  527. package/templates/skills/react-patterns.md +0 -686
  528. package/templates/skills/rust-patterns.md +0 -1057
  529. package/templates/skills/security-best-practices.md +0 -1413
  530. package/templates/skills/testing-best-practices.md +0 -1315
  531. package/templates/skills/ts-best-practices.md +0 -354
  532. 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
- - [ ] 文件上传经过适当验证和沙箱化