@sun-asterisk/sunlint 1.3.39 → 1.3.41

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 (488) hide show
  1. package/config/rules/rules-registry-generated.json +134 -108
  2. package/core/rule-selection-service.js +11 -0
  3. package/docs/GENERATED_FILES_QUICK_REFERENCE.md +96 -0
  4. package/docs/GENERATED_FILE_HANDLING_SUMMARY.md +152 -0
  5. package/docs/skills/CREATE_NEW_DART_RULE.md +161 -14
  6. package/origin-rules/dart-en.md +151 -163
  7. package/package.json +2 -1
  8. package/rules/dart/D002_dispose_resources/config.json +25 -0
  9. package/rules/dart/D003_prefer_widgets_over_methods/config.json +14 -0
  10. package/rules/dart/D004_avoid_shrinkwrap_listview/config.json +13 -0
  11. package/rules/dart/D005_limit_widget_nesting/config.json +13 -0
  12. package/rules/dart/D006_prefer_extracting_large_callbacks/config.json +25 -0
  13. package/rules/dart/D007_prefer_init_first_dispose_last/config.json +10 -0
  14. package/rules/dart/D008_avoid_long_functions/config.json +12 -0
  15. package/rules/dart/D009_limit_function_parameters/config.json +13 -0
  16. package/rules/dart/D010_limit_cyclomatic_complexity/config.json +12 -0
  17. package/rules/dart/D011_prefer_named_parameters/config.json +12 -0
  18. package/rules/dart/D012_prefer_named_boolean_parameters/config.json +9 -0
  19. package/rules/dart/D013_single_public_class/config.json +10 -0
  20. package/rules/dart/D014_unsafe_collection_access/config.json +10 -0
  21. package/rules/dart/D015_copywith_all_parameters/config.json +9 -0
  22. package/rules/dart/D016_project_should_have_tests/config.json +24 -0
  23. package/rules/dart/D017_pubspec_dependencies_review/config.json +23 -0
  24. package/rules/dart/D018_remove_commented_code/config.json +13 -0
  25. package/rules/dart/D019_avoid_single_child_multi_child_widget/config.json +21 -0
  26. package/rules/dart/D020_limit_if_else_branches/config.json +12 -0
  27. package/rules/dart/D021_avoid_negated_boolean_checks/config.json +14 -0
  28. package/rules/dart/D022_use_setstate_correctly/config.json +14 -0
  29. package/rules/dart/D023_avoid_unnecessary_method_overrides/config.json +13 -0
  30. package/rules/dart/D024_avoid_unnecessary_stateful_widget/config.json +9 -0
  31. package/rules/dart/D025_avoid_nested_conditional_expressions/config.json +9 -0
  32. package/skill-assets/sunlint-code-quality/AGENTS.md +80 -0
  33. package/skill-assets/sunlint-code-quality/SKILL.md +176 -0
  34. package/skill-assets/sunlint-code-quality/rules/csharp/C006-verb-noun-functions.md +36 -0
  35. package/skill-assets/sunlint-code-quality/rules/csharp/C013-no-dead-code.md +38 -0
  36. package/skill-assets/sunlint-code-quality/rules/csharp/C014-dependency-injection.md +45 -0
  37. package/skill-assets/sunlint-code-quality/rules/csharp/C017-no-constructor-logic.md +46 -0
  38. package/skill-assets/sunlint-code-quality/rules/csharp/C018-generic-errors.md +38 -0
  39. package/skill-assets/sunlint-code-quality/rules/csharp/C019-error-log-level.md +29 -0
  40. package/skill-assets/sunlint-code-quality/rules/csharp/C020-no-unused-imports.md +30 -0
  41. package/skill-assets/sunlint-code-quality/rules/csharp/C022-no-unused-variables.md +33 -0
  42. package/skill-assets/sunlint-code-quality/rules/csharp/C023-no-duplicate-names.md +36 -0
  43. package/skill-assets/sunlint-code-quality/rules/csharp/C024-centralize-constants.md +33 -0
  44. package/skill-assets/sunlint-code-quality/rules/csharp/C029-catch-log-root-cause.md +40 -0
  45. package/skill-assets/sunlint-code-quality/rules/csharp/C030-custom-error-classes.md +38 -0
  46. package/skill-assets/sunlint-code-quality/rules/csharp/C033-separate-data-access.md +53 -0
  47. package/skill-assets/sunlint-code-quality/rules/csharp/C035-error-context-logging.md +31 -0
  48. package/skill-assets/sunlint-code-quality/rules/csharp/C041-no-hardcoded-secrets.md +25 -0
  49. package/skill-assets/sunlint-code-quality/rules/csharp/C042-boolean-naming.md +27 -0
  50. package/skill-assets/sunlint-code-quality/rules/csharp/C052-controller-parsing.md +41 -0
  51. package/skill-assets/sunlint-code-quality/rules/csharp/C060-superclass-logic.md +33 -0
  52. package/skill-assets/sunlint-code-quality/rules/csharp/C067-no-hardcoded-config.md +24 -0
  53. package/skill-assets/sunlint-code-quality/rules/csharp/S003-open-redirect.md +47 -0
  54. package/skill-assets/sunlint-code-quality/rules/csharp/S004-no-log-credentials.md +28 -0
  55. package/skill-assets/sunlint-code-quality/rules/csharp/S005-server-authorization.md +51 -0
  56. package/skill-assets/sunlint-code-quality/rules/csharp/S006-default-credentials.md +42 -0
  57. package/skill-assets/sunlint-code-quality/rules/csharp/S007-output-encoding.md +36 -0
  58. package/skill-assets/sunlint-code-quality/rules/csharp/S009-approved-crypto.md +37 -0
  59. package/skill-assets/sunlint-code-quality/rules/csharp/S010-csprng.md +32 -0
  60. package/skill-assets/sunlint-code-quality/rules/csharp/S011-encrypted-client-hello.md +36 -0
  61. package/skill-assets/sunlint-code-quality/rules/csharp/S012-secrets-management.md +35 -0
  62. package/skill-assets/sunlint-code-quality/rules/csharp/S013-tls-connections.md +36 -0
  63. package/skill-assets/sunlint-code-quality/rules/csharp/S016-no-sensitive-query-string.md +39 -0
  64. package/skill-assets/sunlint-code-quality/rules/csharp/S017-parameterized-queries.md +47 -0
  65. package/skill-assets/sunlint-code-quality/rules/csharp/S019-email-input-sanitization.md +35 -0
  66. package/skill-assets/sunlint-code-quality/rules/csharp/S020-eval-code-execution.md +56 -0
  67. package/skill-assets/sunlint-code-quality/rules/csharp/S022-context-escaping.md +50 -0
  68. package/skill-assets/sunlint-code-quality/rules/csharp/S023-dynamic-js-encoding.md +34 -0
  69. package/skill-assets/sunlint-code-quality/rules/csharp/S025-server-validation.md +56 -0
  70. package/skill-assets/sunlint-code-quality/rules/csharp/S026-tls-encryption.md +28 -0
  71. package/skill-assets/sunlint-code-quality/rules/csharp/S027-mtls-validation.md +40 -0
  72. package/skill-assets/sunlint-code-quality/rules/csharp/S028-upload-limits.md +50 -0
  73. package/skill-assets/sunlint-code-quality/rules/csharp/S029-csrf-protection.md +42 -0
  74. package/skill-assets/sunlint-code-quality/rules/csharp/S030-directory-browsing.md +26 -0
  75. package/skill-assets/sunlint-code-quality/rules/csharp/S031-secure-cookie-flag.md +35 -0
  76. package/skill-assets/sunlint-code-quality/rules/csharp/S032-httponly-cookie.md +31 -0
  77. package/skill-assets/sunlint-code-quality/rules/csharp/S033-samesite-cookie.md +36 -0
  78. package/skill-assets/sunlint-code-quality/rules/csharp/S034-host-prefix-cookie.md +31 -0
  79. package/skill-assets/sunlint-code-quality/rules/csharp/S035-app-hostnames.md +26 -0
  80. package/skill-assets/sunlint-code-quality/rules/csharp/S036-internal-file-paths.md +36 -0
  81. package/skill-assets/sunlint-code-quality/rules/csharp/S037-anti-cache-headers.md +33 -0
  82. package/skill-assets/sunlint-code-quality/rules/csharp/S039-tls-certificate-validation.md +41 -0
  83. package/skill-assets/sunlint-code-quality/rules/csharp/S041-logout-invalidation.md +36 -0
  84. package/skill-assets/sunlint-code-quality/rules/csharp/S042-long-lived-sessions.md +47 -0
  85. package/skill-assets/sunlint-code-quality/rules/csharp/S044-critical-changes-reauth.md +45 -0
  86. package/skill-assets/sunlint-code-quality/rules/csharp/S045-brute-force-protection.md +48 -0
  87. package/skill-assets/sunlint-code-quality/rules/csharp/S047-oauth-csrf-protection.md +53 -0
  88. package/skill-assets/sunlint-code-quality/rules/csharp/S048-oauth-redirect-validation.md +37 -0
  89. package/skill-assets/sunlint-code-quality/rules/csharp/S049-auth-code-expiry.md +33 -0
  90. package/skill-assets/sunlint-code-quality/rules/csharp/S050-token-entropy.md +33 -0
  91. package/skill-assets/sunlint-code-quality/rules/csharp/S051-password-length.md +35 -0
  92. package/skill-assets/sunlint-code-quality/rules/csharp/S052-otp-entropy.md +26 -0
  93. package/skill-assets/sunlint-code-quality/rules/csharp/S053-generic-error-messages.md +32 -0
  94. package/skill-assets/sunlint-code-quality/rules/csharp/S054-no-default-admin.md +31 -0
  95. package/skill-assets/sunlint-code-quality/rules/csharp/S055-content-type-validation.md +44 -0
  96. package/skill-assets/sunlint-code-quality/rules/csharp/S056-log-injection.md +33 -0
  97. package/skill-assets/sunlint-code-quality/rules/csharp/S057-synchronized-time.md +27 -0
  98. package/skill-assets/sunlint-code-quality/rules/csharp/S058-ssrf-protection.md +54 -0
  99. package/skill-assets/sunlint-code-quality/rules/go/C006-verb-noun-functions.md +45 -0
  100. package/skill-assets/sunlint-code-quality/rules/go/C013-no-dead-code.md +48 -0
  101. package/skill-assets/sunlint-code-quality/rules/go/C014-dependency-injection.md +85 -0
  102. package/skill-assets/sunlint-code-quality/rules/go/C017-no-constructor-logic.md +67 -0
  103. package/skill-assets/sunlint-code-quality/rules/go/C018-generic-errors.md +63 -0
  104. package/skill-assets/sunlint-code-quality/rules/go/C019-error-log-level.md +50 -0
  105. package/skill-assets/sunlint-code-quality/rules/go/C020-no-unused-imports.md +45 -0
  106. package/skill-assets/sunlint-code-quality/rules/go/C022-no-unused-variables.md +34 -0
  107. package/skill-assets/sunlint-code-quality/rules/go/C023-no-duplicate-names.md +41 -0
  108. package/skill-assets/sunlint-code-quality/rules/go/C024-centralize-constants.md +55 -0
  109. package/skill-assets/sunlint-code-quality/rules/go/C029-catch-log-root-cause.md +56 -0
  110. package/skill-assets/sunlint-code-quality/rules/go/C030-custom-error-classes.md +69 -0
  111. package/skill-assets/sunlint-code-quality/rules/go/C033-separate-data-access.md +68 -0
  112. package/skill-assets/sunlint-code-quality/rules/go/C035-error-context-logging.md +48 -0
  113. package/skill-assets/sunlint-code-quality/rules/go/C041-no-hardcoded-secrets.md +45 -0
  114. package/skill-assets/sunlint-code-quality/rules/go/C042-boolean-naming.md +42 -0
  115. package/skill-assets/sunlint-code-quality/rules/go/C052-controller-parsing.md +62 -0
  116. package/skill-assets/sunlint-code-quality/rules/go/C060-superclass-logic.md +60 -0
  117. package/skill-assets/sunlint-code-quality/rules/go/C067-no-hardcoded-config.md +51 -0
  118. package/skill-assets/sunlint-code-quality/rules/go/S003-open-redirect.md +80 -0
  119. package/skill-assets/sunlint-code-quality/rules/go/S004-no-log-credentials.md +66 -0
  120. package/skill-assets/sunlint-code-quality/rules/go/S005-server-authorization.md +55 -0
  121. package/skill-assets/sunlint-code-quality/rules/go/S006-default-credentials.md +47 -0
  122. package/skill-assets/sunlint-code-quality/rules/go/S007-output-encoding.md +50 -0
  123. package/skill-assets/sunlint-code-quality/rules/go/S009-approved-crypto.md +63 -0
  124. package/skill-assets/sunlint-code-quality/rules/go/S010-csprng.md +53 -0
  125. package/skill-assets/sunlint-code-quality/rules/go/S011-encrypted-client-hello.md +34 -0
  126. package/skill-assets/sunlint-code-quality/rules/go/S012-secrets-management.md +49 -0
  127. package/skill-assets/sunlint-code-quality/rules/go/S013-tls-connections.md +61 -0
  128. package/skill-assets/sunlint-code-quality/rules/go/S016-no-sensitive-query-string.md +42 -0
  129. package/skill-assets/sunlint-code-quality/rules/go/S017-parameterized-queries.md +36 -0
  130. package/skill-assets/sunlint-code-quality/rules/go/S019-email-input-sanitization.md +44 -0
  131. package/skill-assets/sunlint-code-quality/rules/go/S020-eval-code-execution.md +47 -0
  132. package/skill-assets/sunlint-code-quality/rules/go/S022-context-escaping.md +49 -0
  133. package/skill-assets/sunlint-code-quality/rules/go/S023-dynamic-js-encoding.md +51 -0
  134. package/skill-assets/sunlint-code-quality/rules/go/S025-server-validation.md +57 -0
  135. package/skill-assets/sunlint-code-quality/rules/go/S026-tls-encryption.md +46 -0
  136. package/skill-assets/sunlint-code-quality/rules/go/S027-mtls-validation.md +52 -0
  137. package/skill-assets/sunlint-code-quality/rules/go/S028-upload-limits.md +58 -0
  138. package/skill-assets/sunlint-code-quality/rules/go/S029-csrf-protection.md +53 -0
  139. package/skill-assets/sunlint-code-quality/rules/go/S030-directory-browsing.md +53 -0
  140. package/skill-assets/sunlint-code-quality/rules/go/S031-secure-cookie-flag.md +48 -0
  141. package/skill-assets/sunlint-code-quality/rules/go/S032-httponly-cookie.md +42 -0
  142. package/skill-assets/sunlint-code-quality/rules/go/S033-samesite-cookie.md +49 -0
  143. package/skill-assets/sunlint-code-quality/rules/go/S034-host-prefix-cookie.md +44 -0
  144. package/skill-assets/sunlint-code-quality/rules/go/S035-app-hostnames.md +50 -0
  145. package/skill-assets/sunlint-code-quality/rules/go/S036-internal-file-paths.md +56 -0
  146. package/skill-assets/sunlint-code-quality/rules/go/S037-anti-cache-headers.md +43 -0
  147. package/skill-assets/sunlint-code-quality/rules/go/S039-tls-certificate-validation.md +41 -0
  148. package/skill-assets/sunlint-code-quality/rules/go/S041-logout-invalidation.md +46 -0
  149. package/skill-assets/sunlint-code-quality/rules/go/S042-long-lived-sessions.md +58 -0
  150. package/skill-assets/sunlint-code-quality/rules/go/S044-critical-changes-reauth.md +53 -0
  151. package/skill-assets/sunlint-code-quality/rules/go/S045-brute-force-protection.md +55 -0
  152. package/skill-assets/sunlint-code-quality/rules/go/S047-oauth-csrf-protection.md +51 -0
  153. package/skill-assets/sunlint-code-quality/rules/go/S048-oauth-redirect-validation.md +58 -0
  154. package/skill-assets/sunlint-code-quality/rules/go/S049-auth-code-expiry.md +52 -0
  155. package/skill-assets/sunlint-code-quality/rules/go/S050-token-entropy.md +53 -0
  156. package/skill-assets/sunlint-code-quality/rules/go/S051-password-length.md +49 -0
  157. package/skill-assets/sunlint-code-quality/rules/go/S052-otp-entropy.md +48 -0
  158. package/skill-assets/sunlint-code-quality/rules/go/S053-generic-error-messages.md +51 -0
  159. package/skill-assets/sunlint-code-quality/rules/go/S054-no-default-admin.md +43 -0
  160. package/skill-assets/sunlint-code-quality/rules/go/S055-content-type-validation.md +52 -0
  161. package/skill-assets/sunlint-code-quality/rules/go/S056-log-injection.md +40 -0
  162. package/skill-assets/sunlint-code-quality/rules/go/S057-synchronized-time.md +40 -0
  163. package/skill-assets/sunlint-code-quality/rules/go/S058-ssrf-protection.md +70 -0
  164. package/skill-assets/sunlint-code-quality/rules/java/C006-verb-noun-functions.md +36 -0
  165. package/skill-assets/sunlint-code-quality/rules/java/C013-no-dead-code.md +175 -0
  166. package/skill-assets/sunlint-code-quality/rules/java/C014-dependency-injection.md +42 -0
  167. package/skill-assets/sunlint-code-quality/rules/java/C017-no-constructor-logic.md +39 -0
  168. package/skill-assets/sunlint-code-quality/rules/java/C018-generic-errors.md +28 -0
  169. package/skill-assets/sunlint-code-quality/rules/java/C019-error-log-level.md +34 -0
  170. package/skill-assets/sunlint-code-quality/rules/java/C020-no-unused-imports.md +34 -0
  171. package/skill-assets/sunlint-code-quality/rules/java/C022-no-unused-variables.md +31 -0
  172. package/skill-assets/sunlint-code-quality/rules/java/C023-no-duplicate-names.md +37 -0
  173. package/skill-assets/sunlint-code-quality/rules/java/C024-centralize-constants.md +36 -0
  174. package/skill-assets/sunlint-code-quality/rules/java/C029-catch-log-root-cause.md +42 -0
  175. package/skill-assets/sunlint-code-quality/rules/java/C030-custom-error-classes.md +50 -0
  176. package/skill-assets/sunlint-code-quality/rules/java/C033-separate-data-access.md +46 -0
  177. package/skill-assets/sunlint-code-quality/rules/java/C035-error-context-logging.md +38 -0
  178. package/skill-assets/sunlint-code-quality/rules/java/C041-no-hardcoded-secrets.md +34 -0
  179. package/skill-assets/sunlint-code-quality/rules/java/C042-boolean-naming.md +27 -0
  180. package/skill-assets/sunlint-code-quality/rules/java/C052-controller-parsing.md +39 -0
  181. package/skill-assets/sunlint-code-quality/rules/java/C060-superclass-logic.md +32 -0
  182. package/skill-assets/sunlint-code-quality/rules/java/C067-no-hardcoded-config.md +31 -0
  183. package/skill-assets/sunlint-code-quality/rules/java/S003-open-redirect.md +38 -0
  184. package/skill-assets/sunlint-code-quality/rules/java/S004-no-log-credentials.md +36 -0
  185. package/skill-assets/sunlint-code-quality/rules/java/S005-server-authorization.md +53 -0
  186. package/skill-assets/sunlint-code-quality/rules/java/S006-default-credentials.md +39 -0
  187. package/skill-assets/sunlint-code-quality/rules/java/S007-output-encoding.md +49 -0
  188. package/skill-assets/sunlint-code-quality/rules/java/S009-approved-crypto.md +40 -0
  189. package/skill-assets/sunlint-code-quality/rules/java/S010-csprng.md +36 -0
  190. package/skill-assets/sunlint-code-quality/rules/java/S011-encrypted-client-hello.md +27 -0
  191. package/skill-assets/sunlint-code-quality/rules/java/S012-secrets-management.md +34 -0
  192. package/skill-assets/sunlint-code-quality/rules/java/S013-tls-connections.md +40 -0
  193. package/skill-assets/sunlint-code-quality/rules/java/S016-no-sensitive-query-string.md +36 -0
  194. package/skill-assets/sunlint-code-quality/rules/java/S017-parameterized-queries.md +47 -0
  195. package/skill-assets/sunlint-code-quality/rules/java/S019-email-input-sanitization.md +32 -0
  196. package/skill-assets/sunlint-code-quality/rules/java/S020-eval-code-execution.md +45 -0
  197. package/skill-assets/sunlint-code-quality/rules/java/S022-context-escaping.md +28 -0
  198. package/skill-assets/sunlint-code-quality/rules/java/S023-dynamic-js-encoding.md +28 -0
  199. package/skill-assets/sunlint-code-quality/rules/java/S025-server-validation.md +58 -0
  200. package/skill-assets/sunlint-code-quality/rules/java/S026-tls-encryption.md +57 -0
  201. package/skill-assets/sunlint-code-quality/rules/java/S027-mtls-validation.md +26 -0
  202. package/skill-assets/sunlint-code-quality/rules/java/S028-upload-limits.md +35 -0
  203. package/skill-assets/sunlint-code-quality/rules/java/S029-csrf-protection.md +35 -0
  204. package/skill-assets/sunlint-code-quality/rules/java/S030-directory-browsing.md +38 -0
  205. package/skill-assets/sunlint-code-quality/rules/java/S031-secure-cookie-flag.md +38 -0
  206. package/skill-assets/sunlint-code-quality/rules/java/S032-httponly-cookie.md +31 -0
  207. package/skill-assets/sunlint-code-quality/rules/java/S033-samesite-cookie.md +42 -0
  208. package/skill-assets/sunlint-code-quality/rules/java/S034-host-prefix-cookie.md +35 -0
  209. package/skill-assets/sunlint-code-quality/rules/java/S035-app-hostnames.md +23 -0
  210. package/skill-assets/sunlint-code-quality/rules/java/S036-internal-file-paths.md +39 -0
  211. package/skill-assets/sunlint-code-quality/rules/java/S037-anti-cache-headers.md +37 -0
  212. package/skill-assets/sunlint-code-quality/rules/java/S039-tls-certificate-validation.md +43 -0
  213. package/skill-assets/sunlint-code-quality/rules/java/S041-logout-invalidation.md +53 -0
  214. package/skill-assets/sunlint-code-quality/rules/java/S042-long-lived-sessions.md +36 -0
  215. package/skill-assets/sunlint-code-quality/rules/java/S044-critical-changes-reauth.md +28 -0
  216. package/skill-assets/sunlint-code-quality/rules/java/S045-brute-force-protection.md +38 -0
  217. package/skill-assets/sunlint-code-quality/rules/java/S047-oauth-csrf-protection.md +33 -0
  218. package/skill-assets/sunlint-code-quality/rules/java/S048-oauth-redirect-validation.md +25 -0
  219. package/skill-assets/sunlint-code-quality/rules/java/S049-auth-code-expiry.md +23 -0
  220. package/skill-assets/sunlint-code-quality/rules/java/S050-token-entropy.md +20 -0
  221. package/skill-assets/sunlint-code-quality/rules/java/S051-password-length.md +20 -0
  222. package/skill-assets/sunlint-code-quality/rules/java/S052-otp-entropy.md +23 -0
  223. package/skill-assets/sunlint-code-quality/rules/java/S053-generic-error-messages.md +21 -0
  224. package/skill-assets/sunlint-code-quality/rules/java/S054-no-default-admin.md +16 -0
  225. package/skill-assets/sunlint-code-quality/rules/java/S055-content-type-validation.md +36 -0
  226. package/skill-assets/sunlint-code-quality/rules/java/S056-log-injection.md +38 -0
  227. package/skill-assets/sunlint-code-quality/rules/java/S057-synchronized-time.md +35 -0
  228. package/skill-assets/sunlint-code-quality/rules/java/S058-ssrf-protection.md +56 -0
  229. package/skill-assets/sunlint-code-quality/rules/kotlin/C006-verb-noun-functions.md +45 -0
  230. package/skill-assets/sunlint-code-quality/rules/kotlin/C013-no-dead-code.md +49 -0
  231. package/skill-assets/sunlint-code-quality/rules/kotlin/C014-dependency-injection.md +64 -0
  232. package/skill-assets/sunlint-code-quality/rules/kotlin/C017-no-constructor-logic.md +68 -0
  233. package/skill-assets/sunlint-code-quality/rules/kotlin/C018-generic-errors.md +46 -0
  234. package/skill-assets/sunlint-code-quality/rules/kotlin/C019-error-log-level.md +50 -0
  235. package/skill-assets/sunlint-code-quality/rules/kotlin/C020-no-unused-imports.md +44 -0
  236. package/skill-assets/sunlint-code-quality/rules/kotlin/C022-no-unused-variables.md +39 -0
  237. package/skill-assets/sunlint-code-quality/rules/kotlin/C023-no-duplicate-names.md +47 -0
  238. package/skill-assets/sunlint-code-quality/rules/kotlin/C024-centralize-constants.md +58 -0
  239. package/skill-assets/sunlint-code-quality/rules/kotlin/C029-catch-log-root-cause.md +50 -0
  240. package/skill-assets/sunlint-code-quality/rules/kotlin/C030-custom-error-classes.md +72 -0
  241. package/skill-assets/sunlint-code-quality/rules/kotlin/C033-separate-data-access.md +69 -0
  242. package/skill-assets/sunlint-code-quality/rules/kotlin/C035-error-context-logging.md +47 -0
  243. package/skill-assets/sunlint-code-quality/rules/kotlin/C041-no-hardcoded-secrets.md +47 -0
  244. package/skill-assets/sunlint-code-quality/rules/kotlin/C042-boolean-naming.md +42 -0
  245. package/skill-assets/sunlint-code-quality/rules/kotlin/C052-controller-parsing.md +71 -0
  246. package/skill-assets/sunlint-code-quality/rules/kotlin/C060-superclass-logic.md +60 -0
  247. package/skill-assets/sunlint-code-quality/rules/kotlin/C067-no-hardcoded-config.md +51 -0
  248. package/skill-assets/sunlint-code-quality/rules/kotlin/S003-open-redirect.md +66 -0
  249. package/skill-assets/sunlint-code-quality/rules/kotlin/S004-no-log-credentials.md +59 -0
  250. package/skill-assets/sunlint-code-quality/rules/kotlin/S005-server-authorization.md +75 -0
  251. package/skill-assets/sunlint-code-quality/rules/kotlin/S006-default-credentials.md +49 -0
  252. package/skill-assets/sunlint-code-quality/rules/kotlin/S007-output-encoding.md +62 -0
  253. package/skill-assets/sunlint-code-quality/rules/kotlin/S009-approved-crypto.md +51 -0
  254. package/skill-assets/sunlint-code-quality/rules/kotlin/S010-csprng.md +61 -0
  255. package/skill-assets/sunlint-code-quality/rules/kotlin/S011-encrypted-client-hello.md +48 -0
  256. package/skill-assets/sunlint-code-quality/rules/kotlin/S012-secrets-management.md +53 -0
  257. package/skill-assets/sunlint-code-quality/rules/kotlin/S013-tls-connections.md +61 -0
  258. package/skill-assets/sunlint-code-quality/rules/kotlin/S016-no-sensitive-query-string.md +51 -0
  259. package/skill-assets/sunlint-code-quality/rules/kotlin/S017-parameterized-queries.md +41 -0
  260. package/skill-assets/sunlint-code-quality/rules/kotlin/S019-email-input-sanitization.md +50 -0
  261. package/skill-assets/sunlint-code-quality/rules/kotlin/S020-eval-code-execution.md +57 -0
  262. package/skill-assets/sunlint-code-quality/rules/kotlin/S022-context-escaping.md +58 -0
  263. package/skill-assets/sunlint-code-quality/rules/kotlin/S023-dynamic-js-encoding.md +57 -0
  264. package/skill-assets/sunlint-code-quality/rules/kotlin/S025-server-validation.md +59 -0
  265. package/skill-assets/sunlint-code-quality/rules/kotlin/S026-tls-encryption.md +50 -0
  266. package/skill-assets/sunlint-code-quality/rules/kotlin/S027-mtls-validation.md +60 -0
  267. package/skill-assets/sunlint-code-quality/rules/kotlin/S028-upload-limits.md +67 -0
  268. package/skill-assets/sunlint-code-quality/rules/kotlin/S029-csrf-protection.md +57 -0
  269. package/skill-assets/sunlint-code-quality/rules/kotlin/S030-directory-browsing.md +50 -0
  270. package/skill-assets/sunlint-code-quality/rules/kotlin/S031-secure-cookie-flag.md +51 -0
  271. package/skill-assets/sunlint-code-quality/rules/kotlin/S032-httponly-cookie.md +49 -0
  272. package/skill-assets/sunlint-code-quality/rules/kotlin/S033-samesite-cookie.md +54 -0
  273. package/skill-assets/sunlint-code-quality/rules/kotlin/S034-host-prefix-cookie.md +50 -0
  274. package/skill-assets/sunlint-code-quality/rules/kotlin/S035-app-hostnames.md +59 -0
  275. package/skill-assets/sunlint-code-quality/rules/kotlin/S036-internal-file-paths.md +61 -0
  276. package/skill-assets/sunlint-code-quality/rules/kotlin/S037-anti-cache-headers.md +58 -0
  277. package/skill-assets/sunlint-code-quality/rules/kotlin/S039-tls-certificate-validation.md +62 -0
  278. package/skill-assets/sunlint-code-quality/rules/kotlin/S041-logout-invalidation.md +71 -0
  279. package/skill-assets/sunlint-code-quality/rules/kotlin/S042-long-lived-sessions.md +57 -0
  280. package/skill-assets/sunlint-code-quality/rules/kotlin/S044-critical-changes-reauth.md +64 -0
  281. package/skill-assets/sunlint-code-quality/rules/kotlin/S045-brute-force-protection.md +64 -0
  282. package/skill-assets/sunlint-code-quality/rules/kotlin/S047-oauth-csrf-protection.md +74 -0
  283. package/skill-assets/sunlint-code-quality/rules/kotlin/S048-oauth-redirect-validation.md +61 -0
  284. package/skill-assets/sunlint-code-quality/rules/kotlin/S049-auth-code-expiry.md +70 -0
  285. package/skill-assets/sunlint-code-quality/rules/kotlin/S050-token-entropy.md +65 -0
  286. package/skill-assets/sunlint-code-quality/rules/kotlin/S051-password-length.md +52 -0
  287. package/skill-assets/sunlint-code-quality/rules/kotlin/S052-otp-entropy.md +55 -0
  288. package/skill-assets/sunlint-code-quality/rules/kotlin/S053-generic-error-messages.md +66 -0
  289. package/skill-assets/sunlint-code-quality/rules/kotlin/S054-no-default-admin.md +57 -0
  290. package/skill-assets/sunlint-code-quality/rules/kotlin/S055-content-type-validation.md +58 -0
  291. package/skill-assets/sunlint-code-quality/rules/kotlin/S056-log-injection.md +47 -0
  292. package/skill-assets/sunlint-code-quality/rules/kotlin/S057-synchronized-time.md +49 -0
  293. package/skill-assets/sunlint-code-quality/rules/kotlin/S058-ssrf-protection.md +69 -0
  294. package/skill-assets/sunlint-code-quality/rules/php/C006-verb-noun-functions.md +46 -0
  295. package/skill-assets/sunlint-code-quality/rules/php/C013-no-dead-code.md +53 -0
  296. package/skill-assets/sunlint-code-quality/rules/php/C014-dependency-injection.md +71 -0
  297. package/skill-assets/sunlint-code-quality/rules/php/C017-no-constructor-logic.md +68 -0
  298. package/skill-assets/sunlint-code-quality/rules/php/C018-generic-errors.md +50 -0
  299. package/skill-assets/sunlint-code-quality/rules/php/C019-error-log-level.md +54 -0
  300. package/skill-assets/sunlint-code-quality/rules/php/C020-no-unused-imports.md +55 -0
  301. package/skill-assets/sunlint-code-quality/rules/php/C022-no-unused-variables.md +51 -0
  302. package/skill-assets/sunlint-code-quality/rules/php/C023-no-duplicate-names.md +61 -0
  303. package/skill-assets/sunlint-code-quality/rules/php/C024-centralize-constants.md +60 -0
  304. package/skill-assets/sunlint-code-quality/rules/php/C029-catch-log-root-cause.md +57 -0
  305. package/skill-assets/sunlint-code-quality/rules/php/C030-custom-error-classes.md +62 -0
  306. package/skill-assets/sunlint-code-quality/rules/php/C033-separate-data-access.md +79 -0
  307. package/skill-assets/sunlint-code-quality/rules/php/C035-error-context-logging.md +54 -0
  308. package/skill-assets/sunlint-code-quality/rules/php/C041-no-hardcoded-secrets.md +59 -0
  309. package/skill-assets/sunlint-code-quality/rules/php/C042-boolean-naming.md +52 -0
  310. package/skill-assets/sunlint-code-quality/rules/php/C052-controller-parsing.md +66 -0
  311. package/skill-assets/sunlint-code-quality/rules/php/C060-superclass-logic.md +54 -0
  312. package/skill-assets/sunlint-code-quality/rules/php/C067-no-hardcoded-config.md +55 -0
  313. package/skill-assets/sunlint-code-quality/rules/php/S003-open-redirect.md +60 -0
  314. package/skill-assets/sunlint-code-quality/rules/php/S004-no-log-credentials.md +67 -0
  315. package/skill-assets/sunlint-code-quality/rules/php/S005-server-authorization.md +57 -0
  316. package/skill-assets/sunlint-code-quality/rules/php/S006-default-credentials.md +61 -0
  317. package/skill-assets/sunlint-code-quality/rules/php/S007-output-encoding.md +61 -0
  318. package/skill-assets/sunlint-code-quality/rules/php/S009-approved-crypto.md +53 -0
  319. package/skill-assets/sunlint-code-quality/rules/php/S010-csprng.md +47 -0
  320. package/skill-assets/sunlint-code-quality/rules/php/S011-encrypted-client-hello.md +41 -0
  321. package/skill-assets/sunlint-code-quality/rules/php/S012-secrets-management.md +60 -0
  322. package/skill-assets/sunlint-code-quality/rules/php/S013-tls-connections.md +67 -0
  323. package/skill-assets/sunlint-code-quality/rules/php/S016-no-sensitive-query-string.md +61 -0
  324. package/skill-assets/sunlint-code-quality/rules/php/S017-parameterized-queries.md +44 -0
  325. package/skill-assets/sunlint-code-quality/rules/php/S019-email-input-sanitization.md +54 -0
  326. package/skill-assets/sunlint-code-quality/rules/php/S020-eval-code-execution.md +57 -0
  327. package/skill-assets/sunlint-code-quality/rules/php/S022-context-escaping.md +58 -0
  328. package/skill-assets/sunlint-code-quality/rules/php/S023-dynamic-js-encoding.md +62 -0
  329. package/skill-assets/sunlint-code-quality/rules/php/S025-server-validation.md +63 -0
  330. package/skill-assets/sunlint-code-quality/rules/php/S026-tls-encryption.md +48 -0
  331. package/skill-assets/sunlint-code-quality/rules/php/S027-mtls-validation.md +62 -0
  332. package/skill-assets/sunlint-code-quality/rules/php/S028-upload-limits.md +60 -0
  333. package/skill-assets/sunlint-code-quality/rules/php/S029-csrf-protection.md +65 -0
  334. package/skill-assets/sunlint-code-quality/rules/php/S030-directory-browsing.md +40 -0
  335. package/skill-assets/sunlint-code-quality/rules/php/S031-secure-cookie-flag.md +55 -0
  336. package/skill-assets/sunlint-code-quality/rules/php/S032-httponly-cookie.md +54 -0
  337. package/skill-assets/sunlint-code-quality/rules/php/S033-samesite-cookie.md +52 -0
  338. package/skill-assets/sunlint-code-quality/rules/php/S034-host-prefix-cookie.md +49 -0
  339. package/skill-assets/sunlint-code-quality/rules/php/S035-app-hostnames.md +49 -0
  340. package/skill-assets/sunlint-code-quality/rules/php/S036-internal-file-paths.md +56 -0
  341. package/skill-assets/sunlint-code-quality/rules/php/S037-anti-cache-headers.md +56 -0
  342. package/skill-assets/sunlint-code-quality/rules/php/S039-tls-certificate-validation.md +54 -0
  343. package/skill-assets/sunlint-code-quality/rules/php/S041-logout-invalidation.md +63 -0
  344. package/skill-assets/sunlint-code-quality/rules/php/S042-long-lived-sessions.md +57 -0
  345. package/skill-assets/sunlint-code-quality/rules/php/S044-critical-changes-reauth.md +71 -0
  346. package/skill-assets/sunlint-code-quality/rules/php/S045-brute-force-protection.md +67 -0
  347. package/skill-assets/sunlint-code-quality/rules/php/S047-oauth-csrf-protection.md +72 -0
  348. package/skill-assets/sunlint-code-quality/rules/php/S048-oauth-redirect-validation.md +54 -0
  349. package/skill-assets/sunlint-code-quality/rules/php/S049-auth-code-expiry.md +71 -0
  350. package/skill-assets/sunlint-code-quality/rules/php/S050-token-entropy.md +58 -0
  351. package/skill-assets/sunlint-code-quality/rules/php/S051-password-length.md +59 -0
  352. package/skill-assets/sunlint-code-quality/rules/php/S052-otp-entropy.md +45 -0
  353. package/skill-assets/sunlint-code-quality/rules/php/S053-generic-error-messages.md +59 -0
  354. package/skill-assets/sunlint-code-quality/rules/php/S054-no-default-admin.md +62 -0
  355. package/skill-assets/sunlint-code-quality/rules/php/S055-content-type-validation.md +58 -0
  356. package/skill-assets/sunlint-code-quality/rules/php/S056-log-injection.md +48 -0
  357. package/skill-assets/sunlint-code-quality/rules/php/S057-synchronized-time.md +52 -0
  358. package/skill-assets/sunlint-code-quality/rules/php/S058-ssrf-protection.md +65 -0
  359. package/skill-assets/sunlint-code-quality/rules/python/C006-verb-noun-functions.md +30 -0
  360. package/skill-assets/sunlint-code-quality/rules/python/C013-no-dead-code.md +24 -0
  361. package/skill-assets/sunlint-code-quality/rules/python/C014-dependency-injection.md +68 -0
  362. package/skill-assets/sunlint-code-quality/rules/python/C017-no-constructor-logic.md +30 -0
  363. package/skill-assets/sunlint-code-quality/rules/python/C018-generic-errors.md +25 -0
  364. package/skill-assets/sunlint-code-quality/rules/python/C019-error-log-level.md +26 -0
  365. package/skill-assets/sunlint-code-quality/rules/python/C020-no-unused-imports.md +28 -0
  366. package/skill-assets/sunlint-code-quality/rules/python/C022-no-unused-variables.md +24 -0
  367. package/skill-assets/sunlint-code-quality/rules/python/C023-no-duplicate-names.md +27 -0
  368. package/skill-assets/sunlint-code-quality/rules/python/C024-centralize-constants.md +27 -0
  369. package/skill-assets/sunlint-code-quality/rules/python/C029-catch-log-root-cause.md +61 -0
  370. package/skill-assets/sunlint-code-quality/rules/python/C030-custom-error-classes.md +28 -0
  371. package/skill-assets/sunlint-code-quality/rules/python/C033-separate-data-access.md +53 -0
  372. package/skill-assets/sunlint-code-quality/rules/python/C035-error-context-logging.md +26 -0
  373. package/skill-assets/sunlint-code-quality/rules/python/C041-no-hardcoded-secrets.md +23 -0
  374. package/skill-assets/sunlint-code-quality/rules/python/C042-boolean-naming.md +24 -0
  375. package/skill-assets/sunlint-code-quality/rules/python/C052-controller-parsing.md +34 -0
  376. package/skill-assets/sunlint-code-quality/rules/python/C060-superclass-logic.md +26 -0
  377. package/skill-assets/sunlint-code-quality/rules/python/C067-no-hardcoded-config.md +22 -0
  378. package/skill-assets/sunlint-code-quality/rules/python/S003-open-redirect.md +16 -0
  379. package/skill-assets/sunlint-code-quality/rules/python/S004-no-log-credentials.md +16 -0
  380. package/skill-assets/sunlint-code-quality/rules/python/S005-server-authorization.md +16 -0
  381. package/skill-assets/sunlint-code-quality/rules/python/S006-default-credentials.md +16 -0
  382. package/skill-assets/sunlint-code-quality/rules/python/S007-output-encoding.md +16 -0
  383. package/skill-assets/sunlint-code-quality/rules/python/S009-approved-crypto.md +16 -0
  384. package/skill-assets/sunlint-code-quality/rules/python/S010-csprng.md +16 -0
  385. package/skill-assets/sunlint-code-quality/rules/python/S011-encrypted-client-hello.md +16 -0
  386. package/skill-assets/sunlint-code-quality/rules/python/S012-secrets-management.md +16 -0
  387. package/skill-assets/sunlint-code-quality/rules/python/S013-tls-connections.md +16 -0
  388. package/skill-assets/sunlint-code-quality/rules/python/S016-no-sensitive-query-string.md +16 -0
  389. package/skill-assets/sunlint-code-quality/rules/python/S017-parameterized-queries.md +51 -0
  390. package/skill-assets/sunlint-code-quality/rules/python/S019-email-input-sanitization.md +16 -0
  391. package/skill-assets/sunlint-code-quality/rules/python/S020-eval-code-execution.md +51 -0
  392. package/skill-assets/sunlint-code-quality/rules/python/S022-context-escaping.md +16 -0
  393. package/skill-assets/sunlint-code-quality/rules/python/S023-dynamic-js-encoding.md +16 -0
  394. package/skill-assets/sunlint-code-quality/rules/python/S025-server-validation.md +16 -0
  395. package/skill-assets/sunlint-code-quality/rules/python/S026-tls-encryption.md +16 -0
  396. package/skill-assets/sunlint-code-quality/rules/python/S027-mtls-validation.md +16 -0
  397. package/skill-assets/sunlint-code-quality/rules/python/S028-upload-limits.md +16 -0
  398. package/skill-assets/sunlint-code-quality/rules/python/S029-csrf-protection.md +16 -0
  399. package/skill-assets/sunlint-code-quality/rules/python/S030-directory-browsing.md +16 -0
  400. package/skill-assets/sunlint-code-quality/rules/python/S031-secure-cookie-flag.md +16 -0
  401. package/skill-assets/sunlint-code-quality/rules/python/S032-httponly-cookie.md +16 -0
  402. package/skill-assets/sunlint-code-quality/rules/python/S033-samesite-cookie.md +16 -0
  403. package/skill-assets/sunlint-code-quality/rules/python/S034-host-prefix-cookie.md +16 -0
  404. package/skill-assets/sunlint-code-quality/rules/python/S035-app-hostnames.md +16 -0
  405. package/skill-assets/sunlint-code-quality/rules/python/S036-internal-file-paths.md +50 -0
  406. package/skill-assets/sunlint-code-quality/rules/python/S037-anti-cache-headers.md +16 -0
  407. package/skill-assets/sunlint-code-quality/rules/python/S039-tls-certificate-validation.md +16 -0
  408. package/skill-assets/sunlint-code-quality/rules/python/S041-logout-invalidation.md +16 -0
  409. package/skill-assets/sunlint-code-quality/rules/python/S042-long-lived-sessions.md +16 -0
  410. package/skill-assets/sunlint-code-quality/rules/python/S044-critical-changes-reauth.md +16 -0
  411. package/skill-assets/sunlint-code-quality/rules/python/S045-brute-force-protection.md +16 -0
  412. package/skill-assets/sunlint-code-quality/rules/python/S047-oauth-csrf-protection.md +16 -0
  413. package/skill-assets/sunlint-code-quality/rules/python/S048-oauth-redirect-validation.md +16 -0
  414. package/skill-assets/sunlint-code-quality/rules/python/S049-auth-code-expiry.md +16 -0
  415. package/skill-assets/sunlint-code-quality/rules/python/S050-token-entropy.md +16 -0
  416. package/skill-assets/sunlint-code-quality/rules/python/S051-password-length.md +16 -0
  417. package/skill-assets/sunlint-code-quality/rules/python/S052-otp-entropy.md +16 -0
  418. package/skill-assets/sunlint-code-quality/rules/python/S053-generic-error-messages.md +16 -0
  419. package/skill-assets/sunlint-code-quality/rules/python/S054-no-default-admin.md +16 -0
  420. package/skill-assets/sunlint-code-quality/rules/python/S055-content-type-validation.md +16 -0
  421. package/skill-assets/sunlint-code-quality/rules/python/S056-log-injection.md +16 -0
  422. package/skill-assets/sunlint-code-quality/rules/python/S057-synchronized-time.md +16 -0
  423. package/skill-assets/sunlint-code-quality/rules/python/S058-ssrf-protection.md +57 -0
  424. package/skill-assets/sunlint-code-quality/rules/typescript/C006-verb-noun-functions.md +45 -0
  425. package/skill-assets/sunlint-code-quality/rules/typescript/C013-no-dead-code.md +51 -0
  426. package/skill-assets/sunlint-code-quality/rules/typescript/C014-dependency-injection.md +69 -0
  427. package/skill-assets/sunlint-code-quality/rules/typescript/C017-no-constructor-logic.md +60 -0
  428. package/skill-assets/sunlint-code-quality/rules/typescript/C018-generic-errors.md +47 -0
  429. package/skill-assets/sunlint-code-quality/rules/typescript/C019-error-log-level.md +50 -0
  430. package/skill-assets/sunlint-code-quality/rules/typescript/C020-no-unused-imports.md +55 -0
  431. package/skill-assets/sunlint-code-quality/rules/typescript/C022-no-unused-variables.md +59 -0
  432. package/skill-assets/sunlint-code-quality/rules/typescript/C023-no-duplicate-names.md +58 -0
  433. package/skill-assets/sunlint-code-quality/rules/typescript/C024-centralize-constants.md +56 -0
  434. package/skill-assets/sunlint-code-quality/rules/typescript/C029-catch-log-root-cause.md +53 -0
  435. package/skill-assets/sunlint-code-quality/rules/typescript/C030-custom-error-classes.md +60 -0
  436. package/skill-assets/sunlint-code-quality/rules/typescript/C033-separate-data-access.md +69 -0
  437. package/skill-assets/sunlint-code-quality/rules/typescript/C035-error-context-logging.md +50 -0
  438. package/skill-assets/sunlint-code-quality/rules/typescript/C041-no-hardcoded-secrets.md +47 -0
  439. package/skill-assets/sunlint-code-quality/rules/typescript/C042-boolean-naming.md +42 -0
  440. package/skill-assets/sunlint-code-quality/rules/typescript/C052-controller-parsing.md +64 -0
  441. package/skill-assets/sunlint-code-quality/rules/typescript/C060-superclass-logic.md +67 -0
  442. package/skill-assets/sunlint-code-quality/rules/typescript/C067-no-hardcoded-config.md +52 -0
  443. package/skill-assets/sunlint-code-quality/rules/typescript/S003-open-redirect.md +76 -0
  444. package/skill-assets/sunlint-code-quality/rules/typescript/S004-no-log-credentials.md +71 -0
  445. package/skill-assets/sunlint-code-quality/rules/typescript/S005-server-authorization.md +68 -0
  446. package/skill-assets/sunlint-code-quality/rules/typescript/S006-default-credentials.md +69 -0
  447. package/skill-assets/sunlint-code-quality/rules/typescript/S007-output-encoding.md +60 -0
  448. package/skill-assets/sunlint-code-quality/rules/typescript/S009-approved-crypto.md +53 -0
  449. package/skill-assets/sunlint-code-quality/rules/typescript/S010-csprng.md +53 -0
  450. package/skill-assets/sunlint-code-quality/rules/typescript/S011-encrypted-client-hello.md +45 -0
  451. package/skill-assets/sunlint-code-quality/rules/typescript/S012-secrets-management.md +47 -0
  452. package/skill-assets/sunlint-code-quality/rules/typescript/S013-tls-connections.md +70 -0
  453. package/skill-assets/sunlint-code-quality/rules/typescript/S016-no-sensitive-query-string.md +53 -0
  454. package/skill-assets/sunlint-code-quality/rules/typescript/S017-parameterized-queries.md +55 -0
  455. package/skill-assets/sunlint-code-quality/rules/typescript/S019-email-input-sanitization.md +56 -0
  456. package/skill-assets/sunlint-code-quality/rules/typescript/S020-eval-code-execution.md +58 -0
  457. package/skill-assets/sunlint-code-quality/rules/typescript/S022-context-escaping.md +48 -0
  458. package/skill-assets/sunlint-code-quality/rules/typescript/S023-dynamic-js-encoding.md +52 -0
  459. package/skill-assets/sunlint-code-quality/rules/typescript/S025-server-validation.md +62 -0
  460. package/skill-assets/sunlint-code-quality/rules/typescript/S026-tls-encryption.md +47 -0
  461. package/skill-assets/sunlint-code-quality/rules/typescript/S027-mtls-validation.md +50 -0
  462. package/skill-assets/sunlint-code-quality/rules/typescript/S028-upload-limits.md +65 -0
  463. package/skill-assets/sunlint-code-quality/rules/typescript/S029-csrf-protection.md +62 -0
  464. package/skill-assets/sunlint-code-quality/rules/typescript/S030-directory-browsing.md +52 -0
  465. package/skill-assets/sunlint-code-quality/rules/typescript/S031-secure-cookie-flag.md +48 -0
  466. package/skill-assets/sunlint-code-quality/rules/typescript/S032-httponly-cookie.md +36 -0
  467. package/skill-assets/sunlint-code-quality/rules/typescript/S033-samesite-cookie.md +46 -0
  468. package/skill-assets/sunlint-code-quality/rules/typescript/S034-host-prefix-cookie.md +50 -0
  469. package/skill-assets/sunlint-code-quality/rules/typescript/S035-app-hostnames.md +49 -0
  470. package/skill-assets/sunlint-code-quality/rules/typescript/S036-internal-file-paths.md +53 -0
  471. package/skill-assets/sunlint-code-quality/rules/typescript/S037-anti-cache-headers.md +52 -0
  472. package/skill-assets/sunlint-code-quality/rules/typescript/S039-tls-certificate-validation.md +51 -0
  473. package/skill-assets/sunlint-code-quality/rules/typescript/S041-logout-invalidation.md +58 -0
  474. package/skill-assets/sunlint-code-quality/rules/typescript/S042-long-lived-sessions.md +55 -0
  475. package/skill-assets/sunlint-code-quality/rules/typescript/S044-critical-changes-reauth.md +69 -0
  476. package/skill-assets/sunlint-code-quality/rules/typescript/S045-brute-force-protection.md +59 -0
  477. package/skill-assets/sunlint-code-quality/rules/typescript/S047-oauth-csrf-protection.md +60 -0
  478. package/skill-assets/sunlint-code-quality/rules/typescript/S048-oauth-redirect-validation.md +59 -0
  479. package/skill-assets/sunlint-code-quality/rules/typescript/S049-auth-code-expiry.md +73 -0
  480. package/skill-assets/sunlint-code-quality/rules/typescript/S050-token-entropy.md +48 -0
  481. package/skill-assets/sunlint-code-quality/rules/typescript/S051-password-length.md +60 -0
  482. package/skill-assets/sunlint-code-quality/rules/typescript/S052-otp-entropy.md +49 -0
  483. package/skill-assets/sunlint-code-quality/rules/typescript/S053-generic-error-messages.md +61 -0
  484. package/skill-assets/sunlint-code-quality/rules/typescript/S054-no-default-admin.md +64 -0
  485. package/skill-assets/sunlint-code-quality/rules/typescript/S055-content-type-validation.md +64 -0
  486. package/skill-assets/sunlint-code-quality/rules/typescript/S056-log-injection.md +48 -0
  487. package/skill-assets/sunlint-code-quality/rules/typescript/S057-synchronized-time.md +57 -0
  488. package/skill-assets/sunlint-code-quality/rules/typescript/S058-ssrf-protection.md +63 -0
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: Use __Host- Prefix For Cookies
3
+ impact: MEDIUM
4
+ impactDescription: locks the cookie to the specific domain and path, preventing subdomain cookie tossing attacks
5
+ tags: cookies, prefix, domain, security, kotlin
6
+ ---
7
+
8
+ ## Use __Host- Prefix For Cookies
9
+
10
+ The `__Host-` prefix is a browser-enforced security mechanism. When a cookie name starts with `__Host-`, the browser will only accept it if it meets strict criteria, making it much harder for an attacker on a subdomain (e.g., `attacker.example.com`) to overwrite or spoof cookies for the main domain (`example.com`).
11
+
12
+ **Incorrect (standard session cookie):**
13
+
14
+ ```kotlin
15
+ // VULNERABLE to subdomain shadowing/tossing
16
+ val cookie = Cookie("session_id", token).apply {
17
+ isHttpOnly = true
18
+ isSecure = true
19
+ path = "/"
20
+ }
21
+ ```
22
+
23
+ **Correct (__Host- prefixed cookie):**
24
+
25
+ ```kotlin
26
+ // STRONGLY SECURE
27
+ val cookie = Cookie("__Host-session_id", token).apply {
28
+ isHttpOnly = true
29
+ isSecure = true // REQ: Must be secure
30
+ path = "/" // REQ: Must be /
31
+ // REQ: Must NOT call setDomain().
32
+ // This locks it to the EXACT host that sent it.
33
+ }
34
+ response.addCookie(cookie)
35
+
36
+ // Ktor:
37
+ call.sessions.set("__Host-session", MySession(token))
38
+ // Ensure the session cookie configuration has path = "/" and secure = true
39
+ ```
40
+
41
+ **__Host- Prefix Requirements:**
42
+ 1. Must have the `Secure` flag.
43
+ 2. Must be sent from a secure origin (HTTPS).
44
+ 3. Must have `Path=/`.
45
+ 4. Must **NOT** have a `Domain` attribute (this ensures it's only sent to the host that set it, not subdomains).
46
+
47
+ **Why use it?**
48
+ It prevents "Cookie Tossing" attacks where an attacker controlling a subdomain (like `blog.company.com`) sets a cookie for the parent domain (`company.com`), potentially hijacking its sessions or triggering CSRF.
49
+
50
+ **Tools:** OWASP ZAP, Browser DevTools, Snyk, Manual Review
@@ -0,0 +1,59 @@
1
+ ---
2
+ title: Host Apps On Different Hostnames
3
+ impact: MEDIUM
4
+ impactDescription: enforces origin isolation to prevent cross-app data and session leakage
5
+ tags: hostname, isolation, same-origin, security, kotlin
6
+ ---
7
+
8
+ ## Host Apps On Different Hostnames
9
+
10
+ Hosting multiple separate applications (e.g., a customer portal and an admin dashboard) on the same hostname but different paths (e.g., `/app` and `/admin`) is risky. Because they share the same origin, they also share cookies, `localStorage`, `sessionStorage`, and `IndexedDB`.
11
+
12
+ **Incorrect (Shared Hostname):**
13
+ ```text
14
+ https://company.com/portal <-- Shared cookies/storage
15
+ https://company.com/admin <-- Shared cookies/storage
16
+ https://company.com/blog <-- A vulnerability in the blog can steal admin cookies!
17
+ ```
18
+
19
+ **Correct (Separate Hostnames):**
20
+ ```text
21
+ https://portal.company.com <-- Isolated
22
+ https://admin.company.com <-- Isolated
23
+ https://blog.company.com <-- Isolated
24
+ ```
25
+
26
+ **Implementation in Kotlin (CORS):**
27
+ When applications are on different hostnames, you must configure Cross-Origin Resource Sharing (CORS) to allow them to communicate safely.
28
+
29
+ ```kotlin
30
+ // Ktor CORS configuration for separate origins
31
+ install(CORS) {
32
+ allowHost("portal.company.com", schemas = listOf("https"))
33
+ allowHost("admin.company.com", schemas = listOf("https"))
34
+ allowCredentials = true
35
+ allowHeader(HttpHeaders.Authorization)
36
+ allowMethod(HttpMethod.Options)
37
+ allowMethod(HttpMethod.Post)
38
+ }
39
+
40
+ // Spring Security
41
+ @Bean
42
+ fun corsConfigurationSource(): CorsConfigurationSource {
43
+ val configuration = CorsConfiguration()
44
+ configuration.allowedOrigins = listOf("https://portal.company.com")
45
+ configuration.allowedMethods = listOf("GET", "POST", "PUT", "DELETE")
46
+ configuration.allowCredentials = true
47
+ val source = UrlBasedCorsConfigurationSource()
48
+ source.registerCorsConfiguration("/**", configuration)
49
+ return source
50
+ }
51
+ ```
52
+
53
+ **Benefits of Isolation:**
54
+ - **Cookie Security:** Admin session cookies cannot be read or overwritten by logic in the user portal.
55
+ - **Storage Security:** Sensitive data in `localStorage` is scoped only to the specific application.
56
+ - **CSRF Mitigation:** Attacking one app from another becomes much harder as they are seen as different origins.
57
+ - **Blast Radius:** A XSS vulnerability in a less-secure part of the site (like a blog or forum) cannot easily pivot to the highly-sensitive admin panel.
58
+
59
+ **Tools:** DNS Configuration, Load Balancer (NGINX/Cloudfront), Browser DevTools
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: Use Internal Data For File Paths
3
+ impact: CRITICAL
4
+ impactDescription: prevents Path Traversal (LFI) attacks that allow reading sensitive system files
5
+ tags: file-path, path-traversal, lfi, input-validation, security, kotlin
6
+ ---
7
+
8
+ ## Use Internal Data For File Paths
9
+
10
+ User-provided input should never be used to construct file paths directly. An attacker can use sequences like `../` to escape the intended directory and access sensitive files on the server (e.g., `/etc/passwd`, database credentials, or source code).
11
+
12
+ **Incorrect (user-controlled path construction):**
13
+
14
+ ```kotlin
15
+ // VULNERABLE: Direct use of filename from query
16
+ @GetMapping("/download")
17
+ fun download(@RequestParam filename: String, response: HttpServletResponse) {
18
+ val file = File("/opt/app/uploads/$filename")
19
+ // Attacker: ?filename=../../../../etc/passwd
20
+ file.inputStream().use { it.copyTo(response.outputStream) }
21
+ }
22
+ ```
23
+
24
+ **Correct (validation and sanitization):**
25
+
26
+ ```kotlin
27
+ import java.nio.file.Paths
28
+ import kotlin.io.path.name
29
+
30
+ @GetMapping("/download")
31
+ fun safeDownload(@RequestParam filename: String): ResponseEntity<Resource> {
32
+ // 1. Sanitize: Extract ONLY the filename, ignore any path components
33
+ val safeName = Paths.get(filename).fileName.toString()
34
+
35
+ // 2. Ideally: Map the filename to an internal ID or record in the DB
36
+ val fileRecord = fileRepository.findByOriginalNameAndUserId(safeName, currentUserId)
37
+ ?: throw NotFoundException("File not found")
38
+
39
+ // 3. Use a static base directory and the SANITIZED name
40
+ val baseDir = Paths.get("/opt/app/uploads").toAbsolutePath()
41
+ val filePath = baseDir.resolve(safeName).normalize()
42
+
43
+ // 4. Verify the resulting path is still inside the base directory
44
+ if (!filePath.startsWith(baseDir)) {
45
+ throw SecurityException("Invalid file path attempt")
46
+ }
47
+
48
+ val resource = FileUrlResource(filePath.toUri().toURL())
49
+ return ResponseEntity.ok()
50
+ .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"$safeName\"")
51
+ .body(resource)
52
+ }
53
+ ```
54
+
55
+ **Security Principles:**
56
+ - **Whitelisting:** Store files with generated IDs (UUIDs) and look them up in a database.
57
+ - **Sanitization:** Use `Paths.get(name).fileName` to strip directory components.
58
+ - **Normalization:** Always call `.normalize()` and `.toAbsolutePath()` before checking if a path starts with your root directory.
59
+ - **Isolation:** Run the application with a dedicated user that has minimal filesystem permissions.
60
+
61
+ **Tools:** SonarQube (S2083), Semgrep, OWASP Path Traversal Cheat Sheet, Manual Review
@@ -0,0 +1,58 @@
1
+ ---
2
+ title: Set Anti-cache Headers
3
+ impact: MEDIUM
4
+ impactDescription: prevents sensitive data from being cached in shared proxies or local browser caches
5
+ tags: headers, cache, sensitive-data, security, kotlin
6
+ ---
7
+
8
+ ## Set Anti-cache Headers
9
+
10
+ Sensitive information (like banking details, health records, or private profile info) cached in a browser or by a proxy can be retrieved by an attacker with access to the same machine or network. You must tell the browser strictly not to store this data.
11
+
12
+ **Incorrect (no cache control for sensitive data):**
13
+
14
+ ```kotlin
15
+ // Data returned without instructions to the browser
16
+ @GetMapping("/api/bank-details")
17
+ fun getDetails(): List<Transaction> {
18
+ return transactionService.findAll() // Might be cached by browser or CDN
19
+ }
20
+ ```
21
+
22
+ **Correct (explicit anti-cache headers):**
23
+
24
+ ```kotlin
25
+ // Spring Boot (Manual in Controller)
26
+ @GetMapping("/api/bank-details")
27
+ fun getDetails(response: HttpServletResponse): List<Transaction> {
28
+ response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, private")
29
+ response.setHeader("Pragma", "no-cache")
30
+ response.setHeader("Expires", "0")
31
+ return transactionService.findAll()
32
+ }
33
+
34
+ // Ktor: Using CachingHeaders plugin
35
+ install(CachingHeaders) {
36
+ options { _, outgoingContent ->
37
+ if (outgoingContent.contentType?.withoutParameters() == ContentType.Application.Json) {
38
+ CachingOptions(CacheControl.NoStore(CacheControl.Visibility.Private))
39
+ } else null
40
+ }
41
+ }
42
+
43
+ // Global Spring Security configuration (Applied by default)
44
+ // http.headers().cacheControl().disable() // DO NOT DO THIS!
45
+ ```
46
+
47
+ **Recommended Headers:**
48
+ - `Cache-Control: no-store, no-cache, must-revalidate, private`
49
+ - `Pragma: no-cache` (For compatibility with old HTTP/1.0 clients)
50
+ - `Expires: 0` (Marking the content as immediately expired)
51
+
52
+ **Critical areas to protect:**
53
+ - User account and profile pages.
54
+ - Authentication tokens or state.
55
+ - Personalized dashboards or reports.
56
+ - Administrative consoles.
57
+
58
+ **Tools:** OWASP ZAP, Browser DevTools (Network tab), Qualys SSL Labs
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: TLS Clients Must Validate Server Certificates
3
+ impact: CRITICAL
4
+ impactDescription: prevents Man-in-the-Middle (MitM) attacks by ensuring the server identity is authentic
5
+ tags: tls, certificates, validation, mitm, security, kotlin
6
+ ---
7
+
8
+ ## TLS Clients Must Validate Server Certificates
9
+
10
+ Disabling TLS certificate validation or trusting all certificates allows an attacker to intercept, read, and modify your traffic by presenting a self-signed or forged certificate. This completely bypasses the security provided by TLS.
11
+
12
+ **Incorrect (disabled validation / trust-all):**
13
+
14
+ ```kotlin
15
+ // DANGEROUS: Trusting all certificates in OkHttp
16
+ val trustAllCerts = arrayOf<X509TrustManager>(object : X509TrustManager {
17
+ override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}
18
+ override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}
19
+ override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
20
+ })
21
+
22
+ // DANGEROUS: Trust-all SSL context
23
+ val sslContext = SSLContext.getInstance("SSL").apply {
24
+ init(null, trustAllCerts, SecureRandom())
25
+ }
26
+
27
+ // DANGEROUS: Ignoring Hostname verification
28
+ val hostnameVerifier = HostnameVerifier { _, _ -> true }
29
+ ```
30
+
31
+ **Correct (proper validation):**
32
+
33
+ ```kotlin
34
+ // 1. Default Behavior (Uses System Trust Store) - Safe
35
+ val client = OkHttpClient() // Validates against trusted root CAs
36
+
37
+ // 2. Custom CA for internal/private services
38
+ val caInputStream: InputStream = File("internal-ca.pem").inputStream()
39
+ val certificateFactory = CertificateFactory.getInstance("X.509")
40
+ val ca = certificateFactory.generateCertificate(caInputStream)
41
+
42
+ val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply {
43
+ load(null, null)
44
+ setCertificateEntry("ca", ca)
45
+ }
46
+
47
+ val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
48
+ init(keyStore)
49
+ }
50
+
51
+ val client = OkHttpClient.Builder()
52
+ .sslSocketFactory(sslContext.socketFactory, trustManagerFactory.trustManagers[0] as X509TrustManager)
53
+ .build()
54
+ ```
55
+
56
+ **Security Checklist:**
57
+ - Never use code that explicitly bypasses `checkServerTrusted`.
58
+ - Do not return `true` from a custom `HostnameVerifier` without validation.
59
+ - In production, ensure no "trust-all" SSL factories are instantiated.
60
+ - For mobile apps, consider **Certificate Pinning** for high-security endpoints.
61
+
62
+ **Tools:** SSLyze, Qualys SSL Labs, OWASP ZAP, Manual Review
@@ -0,0 +1,71 @@
1
+ ---
2
+ title: Invalidate Session On Logout
3
+ impact: MEDIUM
4
+ impactDescription: ensures logout actually terminates access and prevents session reuse
5
+ tags: session, logout, invalidation, security, kotlin
6
+ ---
7
+
8
+ ## Invalidate Session On Logout
9
+
10
+ If the server does not explicitly invalidate the session on logout, the session token remains valid. An attacker who has stolen the session token (e.g., via XSS or physical access) can continue using it even after the user thinks they have logged out.
11
+
12
+ **Incorrect (client-only logout):**
13
+
14
+ ```kotlin
15
+ // Frontend-only logout (token still valid on server!)
16
+ fun logout() {
17
+ localStorage.removeItem("token")
18
+ navigateToLogin()
19
+ }
20
+
21
+ // Server doesn't invalidate session
22
+ @PostMapping("/logout")
23
+ fun logout(): ResponseEntity<Any> {
24
+ return ResponseEntity.ok("Success") // Session still active in Redis/DB!
25
+ }
26
+ ```
27
+
28
+ **Correct (server-side invalidation):**
29
+
30
+ ```kotlin
31
+ // Spring Security (Handles most of this automatically)
32
+ // http.logout().logoutUrl("/logout").invalidateHttpSession(true).deleteCookies("JSESSIONID")
33
+
34
+ @PostMapping("/api/logout")
35
+ fun logout(request: HttpServletRequest, response: HttpServletResponse): ResponseEntity<Any> {
36
+ // 1. Invalidate Session
37
+ request.session?.invalidate()
38
+
39
+ // 2. If using JWT - add to a blacklist (Redis) until expiry
40
+ val token = extractToken(request)
41
+ tokenBlacklist.add(token)
42
+
43
+ // 3. Clear cookies explicitly
44
+ val cookie = Cookie("session", null).apply {
45
+ maxAge = 0
46
+ path = "/"
47
+ isHttpOnly = true
48
+ isSecure = true
49
+ }
50
+ response.addCookie(cookie)
51
+
52
+ // 4. Prevent Caching of sensitive data
53
+ response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate")
54
+
55
+ return ResponseEntity.ok("Logged out")
56
+ }
57
+
58
+ // Ktor
59
+ post("/logout") {
60
+ call.sessions.clear<UserSession>()
61
+ call.respond(HttpStatusCode.OK)
62
+ }
63
+ ```
64
+
65
+ **Best Practices:**
66
+ - Always invalidate the session on the server side.
67
+ - Clear authentication cookies with appropriate flags (`HttpOnly`, `Secure`).
68
+ - If using stateless JWTs, maintain a short-lived blacklist for logged-out tokens.
69
+ - Clear all sensitive data from client-side storage (`localStorage`, `sessionStorage`).
70
+
71
+ **Tools:** Spring Security Logout, Ktor Sessions, Manual Audit
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: Re-authenticate For Long-lived Sessions
3
+ impact: MEDIUM
4
+ impactDescription: ensures continuous user identity verification and reduces the window for session hijacking
5
+ tags: session, authentication, timeout, reauthentication, security, kotlin
6
+ ---
7
+
8
+ ## Re-authenticate For Long-lived Sessions
9
+
10
+ Long-lived sessions (e.g., "Remember Me" for 30 days) are convenient but increase the risk that a stolen session token remains useful to an attacker for a long time. Periodic re-authentication for the entire session or specific sensitive actions ensures the original user is still in control.
11
+
12
+ **Incorrect (sessions never expire or are too long without checks):**
13
+
14
+ ```kotlin
15
+ // Infinite session age
16
+ sessionConfig.cookie.maxAge = -1
17
+
18
+ // No re-authentication for critical tasks
19
+ @PostMapping("/user/change-password")
20
+ fun changePassword(@RequestBody req: NewPasswordReq) {
21
+ // Only checks if session is valid, doesn't ask for old password again
22
+ userService.updatePassword(currentUserId, req.newPassword)
23
+ }
24
+ ```
25
+
26
+ **Correct (periodic re-authentication and step-up auth):**
27
+
28
+ ```kotlin
29
+ val SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1000L // 1 day
30
+ val REAUTH_INTERVAL_MS = 4 * 60 * 60 * 1000L // 4 hours
31
+
32
+ // Middleware/Interceptor for checking last auth time
33
+ fun checkReauthNeeded(session: UserSession): Boolean {
34
+ val lastAuth = session.lastAuthenticatedAt ?: 0L
35
+ val now = System.currentTimeMillis()
36
+
37
+ return (now - lastAuth) > REAUTH_INTERVAL_MS
38
+ }
39
+
40
+ // For sensitive operations (Step-up Authentication)
41
+ @PostMapping("/user/delete-account")
42
+ fun deleteAccount(@RequestBody request: DeleteAccountRequest) {
43
+ // REQUIRE the current password again, even if the session is valid
44
+ if (!authService.verifyPassword(currentUserId, request.currentPassword)) {
45
+ throw AccessDeniedException("Recent password verification required")
46
+ }
47
+
48
+ userService.delete(currentUserId)
49
+ }
50
+ ```
51
+
52
+ **Best Practices:**
53
+ - **Inactivity Timeout:** Invalidate sessions after an idle period (e.g., 30 minutes).
54
+ - **Absolute Timeout:** Force a full logout after a fixed period (e.g., 12 or 24 hours), regardless of activity.
55
+ - **Step-up Auth:** Require re-authentication (Password, OTP, or Biometric) for highly sensitive actions like changing security settings, financial transfers, or accessing personal info.
56
+
57
+ **Tools:** Spring Security (ConcurrentSessionFilter, RememberMe), Ktor Sessions, Manual Audit
@@ -0,0 +1,64 @@
1
+ ---
2
+ title: Re-authenticate Before Critical Changes
3
+ impact: HIGH
4
+ impactDescription: prevents unauthorized sensitive operations if a session is left unattended or hijacked
5
+ tags: authentication, critical, reauthentication, security, kotlin
6
+ ---
7
+
8
+ ## Re-authenticate Before Critical Changes
9
+
10
+ Even if a user has an active session, critical identity or financial changes must require "fresh" authentication (typically the current password, an OTP, or a biometric check). This prevents an attacker who has hijacked a session or gained physical access to an unlocked device from taking full control of the account.
11
+
12
+ **Incorrect (no confirmation for critical actions):**
13
+
14
+ ```kotlin
15
+ // DANGEROUS: Deleting an account without confirming credentials
16
+ @PostMapping("/account/delete")
17
+ fun delete() {
18
+ userService.delete(currentUserId)
19
+ }
20
+
21
+ // DANGEROUS: Changing email without verification
22
+ @PostMapping("/account/change-email")
23
+ fun changeEmail(@RequestBody req: EmailChangeRequest) {
24
+ userService.updateEmail(currentUserId, req.newEmail)
25
+ }
26
+ ```
27
+
28
+ **Correct (require current password or 2FA):**
29
+
30
+ ```kotlin
31
+ @PostMapping("/account/delete")
32
+ fun delete(@RequestBody req: ConfirmationRequest) {
33
+ // 1. Confirm current password
34
+ val isValid = authService.verifyPassword(currentUserId, req.currentPassword)
35
+ if (!isValid) {
36
+ throw BadCredentialsException("Invalid password for confirmation")
37
+ }
38
+
39
+ // 2. Log exactly who and when initiated this
40
+ logger.security("Account deletion initiated", "userId" to currentUserId)
41
+
42
+ userService.delete(currentUserId)
43
+ }
44
+
45
+ // For systems with 2FA
46
+ @PostMapping("/account/change-email")
47
+ fun changeEmail(@RequestBody req: EmailChangeRequest) {
48
+ // Require TOTP/SMS code for sensitive changes
49
+ if (!mfaService.verifyCode(currentUserId, req.totpCode)) {
50
+ throw AccessDeniedException("Valid multi-factor authentication code required")
51
+ }
52
+
53
+ userService.updateEmail(currentUserId, req.newEmail)
54
+ }
55
+ ```
56
+
57
+ **Actions requiring re-authentication:**
58
+ - Changing passwords or security questions.
59
+ - Updating email addresses or MFA settings.
60
+ - Account deletion or deactivation.
61
+ - Modifying linked bank accounts or credit cards.
62
+ - Transferring large sums of money.
63
+
64
+ **Tools:** Spring Security (Step-up Auth), Ktor Auth, Manual Review, OWASP ASVS
@@ -0,0 +1,64 @@
1
+ ---
2
+ title: Implement Brute-force Protection
3
+ impact: HIGH
4
+ impactDescription: prevents automated password guessing and account harvesting attacks
5
+ tags: brute-force, rate-limiting, authentication, security, kotlin
6
+ ---
7
+
8
+ ## Implement Brute-force Protection
9
+
10
+ Authentication endpoints without rate limiting or lockout mechanisms are vulnerable to brute-force attacks, where attackers try thousands of common passwords or perform "credential stuffing" attacks using stolen credentials.
11
+
12
+ **Incorrect (no protection):**
13
+
14
+ ```kotlin
15
+ @PostMapping("/login")
16
+ fun login(@RequestBody data: LoginRequest): ResponseEntity<Any> {
17
+ val result = authService.authenticate(data.username, data.password)
18
+ // No limit on attempts. Attacker can call this 10,000 times a minute.
19
+ return ResponseEntity.ok(result)
20
+ }
21
+ ```
22
+
23
+ **Correct (rate limiting and account lockout):**
24
+
25
+ ```kotlin
26
+ // Using Ktor RateLimiting
27
+ install(RateLimit) {
28
+ register(RateLimitName("login")) {
29
+ rateLimiter(limit = 5, refillPeriod = 15.minutes)
30
+ }
31
+ }
32
+
33
+ // In-code tracking and exponential backoff
34
+ class LoginService(private val redisTemplate: RedisTemplate<String, Int>) {
35
+ fun handleLogin(username: String) {
36
+ val attempts = redisTemplate.get("login_attempts:$username") ?: 0
37
+
38
+ if (attempts >= 5) {
39
+ val lockoutMinutes = Math.pow(2.0, (attempts - 5).toDouble()).toLong()
40
+ throw LockedException("Account locked for $lockoutMinutes minutes")
41
+ }
42
+
43
+ try {
44
+ authenticate(username)
45
+ redisTemplate.delete("login_attempts:$username")
46
+ } catch (e: Exception) {
47
+ redisTemplate.increment("login_attempts:$username")
48
+ throw e
49
+ }
50
+ }
51
+ }
52
+
53
+ // Spring Security Configuration
54
+ // Use standard LoginFailureHandler to increment counters.
55
+ ```
56
+
57
+ **Brute-Force Protection Strategies:**
58
+ - **Rate Limiting:** Limit requests by IP and by username.
59
+ - **Account Lockout:** Temporarily disable accounts after X failed attempts.
60
+ - **Exponential Backoff:** Increase the wait time between successive login attempts.
61
+ - **CAPTCHA:** Use CAPTCHA challenges after a few failed attempts.
62
+ - **WAF:** Use a Web Application Firewall to block high-frequency attacks.
63
+
64
+ **Tools:** Spring Security (LoginFailureHandler), Redis, Ktor RateLimit, Cloudflare WAF, reCAPTCHA
@@ -0,0 +1,74 @@
1
+ ---
2
+ title: Protect OAuth Code Flow Vs CSRF
3
+ impact: HIGH
4
+ impactDescription: prevents attackers from stealing authorization codes or linking victim accounts to attacker credentials
5
+ tags: oauth, csrf, state, authorization, security, kotlin
6
+ ---
7
+
8
+ ## Protect OAuth Code Flow Vs CSRF
9
+
10
+ During an OAuth 2.0 Authorization Code flow, an attacker can perform a CSRF attack to force a user to link their session with the attacker's account, or to intercept the victim's authorization code. Using a `state` parameter is the standard defense.
11
+
12
+ **Incorrect (no state parameter):**
13
+
14
+ ```kotlin
15
+ // VULNERABLE: Initiating OAuth without a unique state
16
+ get("/auth/google") {
17
+ val googleAuthUrl = "https://accounts.google.com/oauth/authorize?" +
18
+ "client_id=$clientId&" +
19
+ "redirect_uri=$redirectUri&" +
20
+ "response_type=code&" +
21
+ "scope=email"
22
+ call.respondRedirect(googleAuthUrl)
23
+ }
24
+ ```
25
+
26
+ **Correct (state parameter validation):**
27
+
28
+ ```kotlin
29
+ import java.security.SecureRandom
30
+ import java.util.Base64
31
+
32
+ @GetMapping("/auth/google")
33
+ fun initiateGoogleAuth(session: HttpSession, response: HttpServletResponse) {
34
+ // 1. Generate a random, unpredictable state
35
+ val state = ByteArray(32).let {
36
+ SecureRandom().nextBytes(it)
37
+ Base64.getUrlEncoder().withoutPadding().encodeToString(it)
38
+ }
39
+
40
+ // 2. Store it in the user's session
41
+ session.setAttribute("oauth_state", state)
42
+
43
+ // 3. Include it in the authorization request
44
+ val authUrl = "https://accounts.google.com/oauth/authorize?" +
45
+ "client_id=$clientId&" +
46
+ "redirect_uri=$redirectUri&" +
47
+ "response_type=code&" +
48
+ "state=$state"
49
+
50
+ response.sendRedirect(authUrl)
51
+ }
52
+
53
+ @GetMapping("/auth/google/callback")
54
+ fun handleGoogleCallback(@RequestParam code: String, @RequestParam state: String, session: HttpSession) {
55
+ // 4. Validate the state returned by the provider
56
+ val savedState = session.getAttribute("oauth_state") as? String
57
+
58
+ if (savedState == null || savedState != state) {
59
+ throw AccessDeniedException("Invalid OAuth state parameter. Potential CSRF attack.")
60
+ }
61
+
62
+ // 5. Clear the state once used
63
+ session.removeAttribute("oauth_state")
64
+
65
+ // Proceed to exchange code for tokens...
66
+ }
67
+ ```
68
+
69
+ **Best Practices:**
70
+ - Always use a random, high-entropy `state` value.
71
+ - Store the state in a secure, server-side session or an encrypted, `HttpOnly` cookie.
72
+ - Alternatively, use **PKCE (Proof Key for Code Exchange)** for public clients (like mobile apps), which provides even stronger protection against code interception.
73
+
74
+ **Tools:** Spring Security OAuth2 (handles state automatically), Ktor Authentication, Manual Review