@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.
- package/config/rules/rules-registry-generated.json +134 -108
- package/core/rule-selection-service.js +11 -0
- package/docs/GENERATED_FILES_QUICK_REFERENCE.md +96 -0
- package/docs/GENERATED_FILE_HANDLING_SUMMARY.md +152 -0
- package/docs/skills/CREATE_NEW_DART_RULE.md +161 -14
- package/origin-rules/dart-en.md +151 -163
- package/package.json +2 -1
- package/rules/dart/D002_dispose_resources/config.json +25 -0
- package/rules/dart/D003_prefer_widgets_over_methods/config.json +14 -0
- package/rules/dart/D004_avoid_shrinkwrap_listview/config.json +13 -0
- package/rules/dart/D005_limit_widget_nesting/config.json +13 -0
- package/rules/dart/D006_prefer_extracting_large_callbacks/config.json +25 -0
- package/rules/dart/D007_prefer_init_first_dispose_last/config.json +10 -0
- package/rules/dart/D008_avoid_long_functions/config.json +12 -0
- package/rules/dart/D009_limit_function_parameters/config.json +13 -0
- package/rules/dart/D010_limit_cyclomatic_complexity/config.json +12 -0
- package/rules/dart/D011_prefer_named_parameters/config.json +12 -0
- package/rules/dart/D012_prefer_named_boolean_parameters/config.json +9 -0
- package/rules/dart/D013_single_public_class/config.json +10 -0
- package/rules/dart/D014_unsafe_collection_access/config.json +10 -0
- package/rules/dart/D015_copywith_all_parameters/config.json +9 -0
- package/rules/dart/D016_project_should_have_tests/config.json +24 -0
- package/rules/dart/D017_pubspec_dependencies_review/config.json +23 -0
- package/rules/dart/D018_remove_commented_code/config.json +13 -0
- package/rules/dart/D019_avoid_single_child_multi_child_widget/config.json +21 -0
- package/rules/dart/D020_limit_if_else_branches/config.json +12 -0
- package/rules/dart/D021_avoid_negated_boolean_checks/config.json +14 -0
- package/rules/dart/D022_use_setstate_correctly/config.json +14 -0
- package/rules/dart/D023_avoid_unnecessary_method_overrides/config.json +13 -0
- package/rules/dart/D024_avoid_unnecessary_stateful_widget/config.json +9 -0
- package/rules/dart/D025_avoid_nested_conditional_expressions/config.json +9 -0
- package/skill-assets/sunlint-code-quality/AGENTS.md +80 -0
- package/skill-assets/sunlint-code-quality/SKILL.md +176 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C006-verb-noun-functions.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C013-no-dead-code.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C014-dependency-injection.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C017-no-constructor-logic.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C018-generic-errors.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C019-error-log-level.md +29 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C020-no-unused-imports.md +30 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C022-no-unused-variables.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C023-no-duplicate-names.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C024-centralize-constants.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C029-catch-log-root-cause.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C030-custom-error-classes.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C033-separate-data-access.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C035-error-context-logging.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C041-no-hardcoded-secrets.md +25 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C042-boolean-naming.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C052-controller-parsing.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C060-superclass-logic.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/C067-no-hardcoded-config.md +24 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S003-open-redirect.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S004-no-log-credentials.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S005-server-authorization.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S006-default-credentials.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S007-output-encoding.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S009-approved-crypto.md +37 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S010-csprng.md +32 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S011-encrypted-client-hello.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S012-secrets-management.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S013-tls-connections.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S016-no-sensitive-query-string.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S017-parameterized-queries.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S019-email-input-sanitization.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S020-eval-code-execution.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S022-context-escaping.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S023-dynamic-js-encoding.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S025-server-validation.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S026-tls-encryption.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S027-mtls-validation.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S028-upload-limits.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S029-csrf-protection.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S030-directory-browsing.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S031-secure-cookie-flag.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S032-httponly-cookie.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S033-samesite-cookie.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S034-host-prefix-cookie.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S035-app-hostnames.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S036-internal-file-paths.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S037-anti-cache-headers.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S039-tls-certificate-validation.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S041-logout-invalidation.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S042-long-lived-sessions.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S044-critical-changes-reauth.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S045-brute-force-protection.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S047-oauth-csrf-protection.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S048-oauth-redirect-validation.md +37 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S049-auth-code-expiry.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S050-token-entropy.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S051-password-length.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S052-otp-entropy.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S053-generic-error-messages.md +32 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S054-no-default-admin.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S055-content-type-validation.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S056-log-injection.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S057-synchronized-time.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/csharp/S058-ssrf-protection.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/go/C006-verb-noun-functions.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/go/C013-no-dead-code.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/go/C014-dependency-injection.md +85 -0
- package/skill-assets/sunlint-code-quality/rules/go/C017-no-constructor-logic.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/go/C018-generic-errors.md +63 -0
- package/skill-assets/sunlint-code-quality/rules/go/C019-error-log-level.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/go/C020-no-unused-imports.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/go/C022-no-unused-variables.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/go/C023-no-duplicate-names.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/go/C024-centralize-constants.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/go/C029-catch-log-root-cause.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/go/C030-custom-error-classes.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/go/C033-separate-data-access.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/go/C035-error-context-logging.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/go/C041-no-hardcoded-secrets.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/go/C042-boolean-naming.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/go/C052-controller-parsing.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/go/C060-superclass-logic.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/go/C067-no-hardcoded-config.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/go/S003-open-redirect.md +80 -0
- package/skill-assets/sunlint-code-quality/rules/go/S004-no-log-credentials.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/go/S005-server-authorization.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/go/S006-default-credentials.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/go/S007-output-encoding.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/go/S009-approved-crypto.md +63 -0
- package/skill-assets/sunlint-code-quality/rules/go/S010-csprng.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S011-encrypted-client-hello.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/go/S012-secrets-management.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/S013-tls-connections.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/go/S016-no-sensitive-query-string.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/go/S017-parameterized-queries.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/go/S019-email-input-sanitization.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/go/S020-eval-code-execution.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/go/S022-context-escaping.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/S023-dynamic-js-encoding.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/go/S025-server-validation.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/go/S026-tls-encryption.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/go/S027-mtls-validation.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/go/S028-upload-limits.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/go/S029-csrf-protection.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S030-directory-browsing.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S031-secure-cookie-flag.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/go/S032-httponly-cookie.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/go/S033-samesite-cookie.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/S034-host-prefix-cookie.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/go/S035-app-hostnames.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/go/S036-internal-file-paths.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/go/S037-anti-cache-headers.md +43 -0
- package/skill-assets/sunlint-code-quality/rules/go/S039-tls-certificate-validation.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/go/S041-logout-invalidation.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/go/S042-long-lived-sessions.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/go/S044-critical-changes-reauth.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S045-brute-force-protection.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/go/S047-oauth-csrf-protection.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/go/S048-oauth-redirect-validation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/go/S049-auth-code-expiry.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/go/S050-token-entropy.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/go/S051-password-length.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/go/S052-otp-entropy.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/go/S053-generic-error-messages.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/go/S054-no-default-admin.md +43 -0
- package/skill-assets/sunlint-code-quality/rules/go/S055-content-type-validation.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/go/S056-log-injection.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/go/S057-synchronized-time.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/go/S058-ssrf-protection.md +70 -0
- package/skill-assets/sunlint-code-quality/rules/java/C006-verb-noun-functions.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/C013-no-dead-code.md +175 -0
- package/skill-assets/sunlint-code-quality/rules/java/C014-dependency-injection.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/java/C017-no-constructor-logic.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/java/C018-generic-errors.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/java/C019-error-log-level.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/java/C020-no-unused-imports.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/java/C022-no-unused-variables.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/java/C023-no-duplicate-names.md +37 -0
- package/skill-assets/sunlint-code-quality/rules/java/C024-centralize-constants.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/C029-catch-log-root-cause.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/java/C030-custom-error-classes.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/java/C033-separate-data-access.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/java/C035-error-context-logging.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/C041-no-hardcoded-secrets.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/java/C042-boolean-naming.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/java/C052-controller-parsing.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/java/C060-superclass-logic.md +32 -0
- package/skill-assets/sunlint-code-quality/rules/java/C067-no-hardcoded-config.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/java/S003-open-redirect.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S004-no-log-credentials.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S005-server-authorization.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/java/S006-default-credentials.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/java/S007-output-encoding.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/java/S009-approved-crypto.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/java/S010-csprng.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S011-encrypted-client-hello.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/java/S012-secrets-management.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/java/S013-tls-connections.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/java/S016-no-sensitive-query-string.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S017-parameterized-queries.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/java/S019-email-input-sanitization.md +32 -0
- package/skill-assets/sunlint-code-quality/rules/java/S020-eval-code-execution.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/java/S022-context-escaping.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/java/S023-dynamic-js-encoding.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/java/S025-server-validation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/java/S026-tls-encryption.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/java/S027-mtls-validation.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/java/S028-upload-limits.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/java/S029-csrf-protection.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/java/S030-directory-browsing.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S031-secure-cookie-flag.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S032-httponly-cookie.md +31 -0
- package/skill-assets/sunlint-code-quality/rules/java/S033-samesite-cookie.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/java/S034-host-prefix-cookie.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/java/S035-app-hostnames.md +23 -0
- package/skill-assets/sunlint-code-quality/rules/java/S036-internal-file-paths.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/java/S037-anti-cache-headers.md +37 -0
- package/skill-assets/sunlint-code-quality/rules/java/S039-tls-certificate-validation.md +43 -0
- package/skill-assets/sunlint-code-quality/rules/java/S041-logout-invalidation.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/java/S042-long-lived-sessions.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S044-critical-changes-reauth.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/java/S045-brute-force-protection.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S047-oauth-csrf-protection.md +33 -0
- package/skill-assets/sunlint-code-quality/rules/java/S048-oauth-redirect-validation.md +25 -0
- package/skill-assets/sunlint-code-quality/rules/java/S049-auth-code-expiry.md +23 -0
- package/skill-assets/sunlint-code-quality/rules/java/S050-token-entropy.md +20 -0
- package/skill-assets/sunlint-code-quality/rules/java/S051-password-length.md +20 -0
- package/skill-assets/sunlint-code-quality/rules/java/S052-otp-entropy.md +23 -0
- package/skill-assets/sunlint-code-quality/rules/java/S053-generic-error-messages.md +21 -0
- package/skill-assets/sunlint-code-quality/rules/java/S054-no-default-admin.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/java/S055-content-type-validation.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/java/S056-log-injection.md +38 -0
- package/skill-assets/sunlint-code-quality/rules/java/S057-synchronized-time.md +35 -0
- package/skill-assets/sunlint-code-quality/rules/java/S058-ssrf-protection.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C006-verb-noun-functions.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C013-no-dead-code.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C014-dependency-injection.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C017-no-constructor-logic.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C018-generic-errors.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C019-error-log-level.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C020-no-unused-imports.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C022-no-unused-variables.md +39 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C023-no-duplicate-names.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C024-centralize-constants.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C029-catch-log-root-cause.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C030-custom-error-classes.md +72 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C033-separate-data-access.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C035-error-context-logging.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C041-no-hardcoded-secrets.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C042-boolean-naming.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C052-controller-parsing.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C060-superclass-logic.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/C067-no-hardcoded-config.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S003-open-redirect.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S004-no-log-credentials.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S005-server-authorization.md +75 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S006-default-credentials.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S007-output-encoding.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S009-approved-crypto.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S010-csprng.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S011-encrypted-client-hello.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S012-secrets-management.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S013-tls-connections.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S016-no-sensitive-query-string.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S017-parameterized-queries.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S019-email-input-sanitization.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S020-eval-code-execution.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S022-context-escaping.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S023-dynamic-js-encoding.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S025-server-validation.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S026-tls-encryption.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S027-mtls-validation.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S028-upload-limits.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S029-csrf-protection.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S030-directory-browsing.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S031-secure-cookie-flag.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S032-httponly-cookie.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S033-samesite-cookie.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S034-host-prefix-cookie.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S035-app-hostnames.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S036-internal-file-paths.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S037-anti-cache-headers.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S039-tls-certificate-validation.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S041-logout-invalidation.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S042-long-lived-sessions.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S044-critical-changes-reauth.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S045-brute-force-protection.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S047-oauth-csrf-protection.md +74 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S048-oauth-redirect-validation.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S049-auth-code-expiry.md +70 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S050-token-entropy.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S051-password-length.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S052-otp-entropy.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S053-generic-error-messages.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S054-no-default-admin.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S055-content-type-validation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S056-log-injection.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S057-synchronized-time.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/kotlin/S058-ssrf-protection.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/php/C006-verb-noun-functions.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/php/C013-no-dead-code.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/php/C014-dependency-injection.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/php/C017-no-constructor-logic.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/php/C018-generic-errors.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/php/C019-error-log-level.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/C020-no-unused-imports.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/php/C022-no-unused-variables.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/php/C023-no-duplicate-names.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/php/C024-centralize-constants.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/php/C029-catch-log-root-cause.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/php/C030-custom-error-classes.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/php/C033-separate-data-access.md +79 -0
- package/skill-assets/sunlint-code-quality/rules/php/C035-error-context-logging.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/C041-no-hardcoded-secrets.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/php/C042-boolean-naming.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/php/C052-controller-parsing.md +66 -0
- package/skill-assets/sunlint-code-quality/rules/php/C060-superclass-logic.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/C067-no-hardcoded-config.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/php/S003-open-redirect.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/php/S004-no-log-credentials.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/php/S005-server-authorization.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/php/S006-default-credentials.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/php/S007-output-encoding.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/php/S009-approved-crypto.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/php/S010-csprng.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/php/S011-encrypted-client-hello.md +41 -0
- package/skill-assets/sunlint-code-quality/rules/php/S012-secrets-management.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/php/S013-tls-connections.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/php/S016-no-sensitive-query-string.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/php/S017-parameterized-queries.md +44 -0
- package/skill-assets/sunlint-code-quality/rules/php/S019-email-input-sanitization.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/S020-eval-code-execution.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/php/S022-context-escaping.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/php/S023-dynamic-js-encoding.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/php/S025-server-validation.md +63 -0
- package/skill-assets/sunlint-code-quality/rules/php/S026-tls-encryption.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/php/S027-mtls-validation.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/php/S028-upload-limits.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/php/S029-csrf-protection.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/php/S030-directory-browsing.md +40 -0
- package/skill-assets/sunlint-code-quality/rules/php/S031-secure-cookie-flag.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/php/S032-httponly-cookie.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/S033-samesite-cookie.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/php/S034-host-prefix-cookie.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/php/S035-app-hostnames.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/php/S036-internal-file-paths.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/php/S037-anti-cache-headers.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/php/S039-tls-certificate-validation.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/S041-logout-invalidation.md +63 -0
- package/skill-assets/sunlint-code-quality/rules/php/S042-long-lived-sessions.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/php/S044-critical-changes-reauth.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/php/S045-brute-force-protection.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/php/S047-oauth-csrf-protection.md +72 -0
- package/skill-assets/sunlint-code-quality/rules/php/S048-oauth-redirect-validation.md +54 -0
- package/skill-assets/sunlint-code-quality/rules/php/S049-auth-code-expiry.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/php/S050-token-entropy.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/php/S051-password-length.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/php/S052-otp-entropy.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/php/S053-generic-error-messages.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/php/S054-no-default-admin.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/php/S055-content-type-validation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/php/S056-log-injection.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/php/S057-synchronized-time.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/php/S058-ssrf-protection.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/python/C006-verb-noun-functions.md +30 -0
- package/skill-assets/sunlint-code-quality/rules/python/C013-no-dead-code.md +24 -0
- package/skill-assets/sunlint-code-quality/rules/python/C014-dependency-injection.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/python/C017-no-constructor-logic.md +30 -0
- package/skill-assets/sunlint-code-quality/rules/python/C018-generic-errors.md +25 -0
- package/skill-assets/sunlint-code-quality/rules/python/C019-error-log-level.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/python/C020-no-unused-imports.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/python/C022-no-unused-variables.md +24 -0
- package/skill-assets/sunlint-code-quality/rules/python/C023-no-duplicate-names.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/python/C024-centralize-constants.md +27 -0
- package/skill-assets/sunlint-code-quality/rules/python/C029-catch-log-root-cause.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/python/C030-custom-error-classes.md +28 -0
- package/skill-assets/sunlint-code-quality/rules/python/C033-separate-data-access.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/python/C035-error-context-logging.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/python/C041-no-hardcoded-secrets.md +23 -0
- package/skill-assets/sunlint-code-quality/rules/python/C042-boolean-naming.md +24 -0
- package/skill-assets/sunlint-code-quality/rules/python/C052-controller-parsing.md +34 -0
- package/skill-assets/sunlint-code-quality/rules/python/C060-superclass-logic.md +26 -0
- package/skill-assets/sunlint-code-quality/rules/python/C067-no-hardcoded-config.md +22 -0
- package/skill-assets/sunlint-code-quality/rules/python/S003-open-redirect.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S004-no-log-credentials.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S005-server-authorization.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S006-default-credentials.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S007-output-encoding.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S009-approved-crypto.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S010-csprng.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S011-encrypted-client-hello.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S012-secrets-management.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S013-tls-connections.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S016-no-sensitive-query-string.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S017-parameterized-queries.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/python/S019-email-input-sanitization.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S020-eval-code-execution.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/python/S022-context-escaping.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S023-dynamic-js-encoding.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S025-server-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S026-tls-encryption.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S027-mtls-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S028-upload-limits.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S029-csrf-protection.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S030-directory-browsing.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S031-secure-cookie-flag.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S032-httponly-cookie.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S033-samesite-cookie.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S034-host-prefix-cookie.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S035-app-hostnames.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S036-internal-file-paths.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/python/S037-anti-cache-headers.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S039-tls-certificate-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S041-logout-invalidation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S042-long-lived-sessions.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S044-critical-changes-reauth.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S045-brute-force-protection.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S047-oauth-csrf-protection.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S048-oauth-redirect-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S049-auth-code-expiry.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S050-token-entropy.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S051-password-length.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S052-otp-entropy.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S053-generic-error-messages.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S054-no-default-admin.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S055-content-type-validation.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S056-log-injection.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S057-synchronized-time.md +16 -0
- package/skill-assets/sunlint-code-quality/rules/python/S058-ssrf-protection.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C006-verb-noun-functions.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C013-no-dead-code.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C014-dependency-injection.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C017-no-constructor-logic.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C018-generic-errors.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C019-error-log-level.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C020-no-unused-imports.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C022-no-unused-variables.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C023-no-duplicate-names.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C024-centralize-constants.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C029-catch-log-root-cause.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C030-custom-error-classes.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C033-separate-data-access.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C035-error-context-logging.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C041-no-hardcoded-secrets.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C042-boolean-naming.md +42 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C052-controller-parsing.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C060-superclass-logic.md +67 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/C067-no-hardcoded-config.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S003-open-redirect.md +76 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S004-no-log-credentials.md +71 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S005-server-authorization.md +68 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S006-default-credentials.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S007-output-encoding.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S009-approved-crypto.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S010-csprng.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S011-encrypted-client-hello.md +45 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S012-secrets-management.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S013-tls-connections.md +70 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S016-no-sensitive-query-string.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S017-parameterized-queries.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S019-email-input-sanitization.md +56 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S020-eval-code-execution.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S022-context-escaping.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S023-dynamic-js-encoding.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S025-server-validation.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S026-tls-encryption.md +47 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S027-mtls-validation.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S028-upload-limits.md +65 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S029-csrf-protection.md +62 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S030-directory-browsing.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S031-secure-cookie-flag.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S032-httponly-cookie.md +36 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S033-samesite-cookie.md +46 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S034-host-prefix-cookie.md +50 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S035-app-hostnames.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S036-internal-file-paths.md +53 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S037-anti-cache-headers.md +52 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S039-tls-certificate-validation.md +51 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S041-logout-invalidation.md +58 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S042-long-lived-sessions.md +55 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S044-critical-changes-reauth.md +69 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S045-brute-force-protection.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S047-oauth-csrf-protection.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S048-oauth-redirect-validation.md +59 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S049-auth-code-expiry.md +73 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S050-token-entropy.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S051-password-length.md +60 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S052-otp-entropy.md +49 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S053-generic-error-messages.md +61 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S054-no-default-admin.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S055-content-type-validation.md +64 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S056-log-injection.md +48 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S057-synchronized-time.md +57 -0
- package/skill-assets/sunlint-code-quality/rules/typescript/S058-ssrf-protection.md +63 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Do Not Log Credentials Or Tokens
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: prevents sensitive credential exposure in monitoring systems
|
|
5
|
+
tags: logging, credentials, tokens, secrets, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Do Not Log Credentials Or Tokens
|
|
9
|
+
|
|
10
|
+
Logging systems are often less protected than core databases. Credentials or tokens in logs can be harvested by attackers or accidentally exposed to unauthorized personnel.
|
|
11
|
+
|
|
12
|
+
**Incorrect (logging sensitive data):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// Logging passwords
|
|
16
|
+
logger.info("Login attempt for user: {}, password: {}", user.username, user.password) // NEVER!
|
|
17
|
+
|
|
18
|
+
// Logging full request headers
|
|
19
|
+
logger.debug("Request headers: {}", request.headers)
|
|
20
|
+
// Authorization header contains Bearer tokens!
|
|
21
|
+
|
|
22
|
+
// Logging raw request body
|
|
23
|
+
logger.info("Incoming request body: {}", request.body())
|
|
24
|
+
// May contain passwords, credit card numbers, or PII
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Correct (sanitized logging):**
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
// Omit sensitive fields
|
|
31
|
+
logger.info("Login attempt for user: {}", user.username)
|
|
32
|
+
|
|
33
|
+
// Sanitize or mask headers
|
|
34
|
+
val safeHeaders = request.headers.toMutableMap().mapValues { (key, value) ->
|
|
35
|
+
if (key.equals("Authorization", ignoreCase = true) || key.equals("Cookie", ignoreCase = true)) {
|
|
36
|
+
"[REDACTED]"
|
|
37
|
+
} else {
|
|
38
|
+
value
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
logger.debug("Request headers: {}", safeHeaders)
|
|
42
|
+
|
|
43
|
+
// Use a data sanitizer for objects
|
|
44
|
+
fun sanitize(data: Map<String, Any?>): Map<String, Any?> {
|
|
45
|
+
val sensitiveKeys = setOf("password", "token", "secret", "credit_card", "cvv")
|
|
46
|
+
return data.mapValues { (key, value) ->
|
|
47
|
+
if (sensitiveKeys.any { key.contains(it, ignoreCase = true) }) "[REDACTED]" else value
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Sensitive Data strictly forbidden in logs:**
|
|
53
|
+
- Passwords (raw or encrypted).
|
|
54
|
+
- Authentication tokens (JWT, OAuth tokens, API Keys).
|
|
55
|
+
- Session IDs and Cookies.
|
|
56
|
+
- Payment information (Credit Card, CVV).
|
|
57
|
+
- Personal IDs (SSN, National ID).
|
|
58
|
+
|
|
59
|
+
**Tools:** Logback mask pattern, SonarQube, Manual Security Audit, Sentry Data Scrubbing
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Enforce Authorization At Trusted Service Layer
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: prevents unauthorized access to protected resources and data
|
|
5
|
+
tags: authorization, rbac, abac, security, access-control, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Enforce Authorization At Trusted Service Layer
|
|
9
|
+
|
|
10
|
+
Client-side checks are purely for UI/UX and can be trivially bypassed. Every request reaching the server must be authenticated and authorized against the required permissions in a trusted environment.
|
|
11
|
+
|
|
12
|
+
**Incorrect (trusting client state):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// Relying on a hidden field or value sent from client
|
|
16
|
+
@PostMapping("/user/update")
|
|
17
|
+
fun update(@RequestBody req: UpdateRequest): String {
|
|
18
|
+
// req.isAdmin is provided by the client's form!
|
|
19
|
+
if (req.isAdmin) {
|
|
20
|
+
db.updatePermissions(req.userId)
|
|
21
|
+
}
|
|
22
|
+
return "ok"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Insecure check in a Controller without proper security context
|
|
26
|
+
@DeleteMapping("/post/{id}")
|
|
27
|
+
fun delete(@PathVariable id: String) {
|
|
28
|
+
// No check if 'current user' owns this 'post'
|
|
29
|
+
postService.delete(id)
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Correct (server-side authorization):**
|
|
34
|
+
|
|
35
|
+
```kotlin
|
|
36
|
+
// Using Spring Security with Method Security
|
|
37
|
+
@PreAuthorize("hasRole('ADMIN')")
|
|
38
|
+
@DeleteMapping("/users/{id}")
|
|
39
|
+
fun deleteUser(@PathVariable id: String) {
|
|
40
|
+
userService.delete(id)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Data-level authorization (checking ownership)
|
|
44
|
+
@PutMapping("/posts/{id}")
|
|
45
|
+
fun updatePost(@PathVariable id: String, @RequestBody data: PostData) {
|
|
46
|
+
val post = postService.findById(id) ?: throw NotFoundException()
|
|
47
|
+
val currentUser = SecurityContextHolder.getContext().authentication.name
|
|
48
|
+
|
|
49
|
+
// Check ownership at the server layer
|
|
50
|
+
if (post.author != currentUser && !isAdmin(currentUser)) {
|
|
51
|
+
throw AccessDeniedException("You do not own this post")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
postService.update(id, data)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Ktor Authentication/Authorization
|
|
58
|
+
route("/admin") {
|
|
59
|
+
install(Authorization) {
|
|
60
|
+
check {
|
|
61
|
+
val user = call.principal<UserPrincipal>()
|
|
62
|
+
user?.roles?.contains("ADMIN") ?: false
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
get("/dashboard") { /* handle admin request */ }
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Never trust for Authorization:**
|
|
70
|
+
- Client-side Boolean flags (e.g., `user.isAdmin`).
|
|
71
|
+
- Parameters like `?role=admin` in the URL.
|
|
72
|
+
- Unsigned or unvalidated JWT claims from local storage.
|
|
73
|
+
- The existence of a "secret" URL (Security by Obscurity).
|
|
74
|
+
|
|
75
|
+
**Tools:** Spring Security, Ktor Auth, Shiro, OPA (Open Policy Agent), Manual Security Review
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Do Not Use Default Credentials
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: prevents trivial unauthorized access via publicly known default accounts
|
|
5
|
+
tags: credentials, default, passwords, configuration, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Do Not Use Default Credentials
|
|
9
|
+
|
|
10
|
+
Default credentials (e.g., `admin/admin`, `root/root`) are the first thing an attacker or automated bot will try. Using them effectively leaves your system wide open.
|
|
11
|
+
|
|
12
|
+
**Incorrect (default or common credentials in config):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// application.properties
|
|
16
|
+
spring.datasource.username=postgres
|
|
17
|
+
spring.datasource.password=postgres # DEFAULT!
|
|
18
|
+
|
|
19
|
+
// Hardcoded in code
|
|
20
|
+
val defaultAdminUser = "admin"
|
|
21
|
+
val defaultAdminPass = "admin" // CRITICAL!
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Correct (environment-based secrets):**
|
|
25
|
+
|
|
26
|
+
```kotlin
|
|
27
|
+
// In application.properties, use environment variables
|
|
28
|
+
// spring.datasource.password=${DB_PASSWORD}
|
|
29
|
+
|
|
30
|
+
// In Kotlin code, ensure no fallback to defaults
|
|
31
|
+
val dbPassword = System.getenv("DB_PASSWORD") ?: throw IllegalStateException("DB_PASSWORD must be provided")
|
|
32
|
+
|
|
33
|
+
// For development, use a local, git-ignored file (e.g., .env)
|
|
34
|
+
// Never commit these to version control.
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Commonly Blocked Defaults:**
|
|
38
|
+
- `admin / admin`
|
|
39
|
+
- `root / root` or `root / <empty>`
|
|
40
|
+
- `postgres / postgres`
|
|
41
|
+
- `sa / <empty>` (Common for SQL Server)
|
|
42
|
+
- `guest / guest`
|
|
43
|
+
|
|
44
|
+
**Security Best Practices:**
|
|
45
|
+
- Force users to change default passwords on first login.
|
|
46
|
+
- Disable default system accounts if not strictly needed.
|
|
47
|
+
- Use CI/CD to scan for common password patterns in configuration files.
|
|
48
|
+
|
|
49
|
+
**Tools:** Gitleaks, CI/CD Secret Scanning, Manual Review, SonarQube
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Output Encoding Before Interpreter Use
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: prevents Cross-Site Scripting (XSS) and other injection attacks
|
|
5
|
+
tags: xss, encoding, output, html, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Output Encoding Before Interpreter Use
|
|
9
|
+
|
|
10
|
+
Cross-Site Scripting (XSS) and other injection attacks occur when unescaped user data is sent back to the browser and interpreted as code. All output must be encoded based on the context in which it will be used (HTML, URL, JavaScript).
|
|
11
|
+
|
|
12
|
+
**Incorrect (no encoding):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// XSS vulnerability in Ktor
|
|
16
|
+
get("/greet") {
|
|
17
|
+
val name = call.parameters["name"]
|
|
18
|
+
call.respondText("<h1>Hello, $name</h1>", ContentType.Text.Html) // XSS!
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Thymeleaf - using utext (unescaped text) with user input
|
|
22
|
+
// <div th:utext="${userInput}"></div>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Correct (context-aware encoding):**
|
|
26
|
+
|
|
27
|
+
```kotlin
|
|
28
|
+
// Thymeleaf - use th:text (automatically escapes HTML)
|
|
29
|
+
// <div th:text="${userInput}"></div>
|
|
30
|
+
|
|
31
|
+
// Using a library like OWASP Java Encoder
|
|
32
|
+
import org.owasp.encoder.Encode
|
|
33
|
+
|
|
34
|
+
val safeHtml = Encode.forHtml(untrustedInput)
|
|
35
|
+
val safeAttr = Encode.forHtmlAttribute(untrustedInput)
|
|
36
|
+
val safeJs = Encode.forJavaScript(untrustedInput)
|
|
37
|
+
|
|
38
|
+
// Ktor - Using HTML DSL (automatically escapes)
|
|
39
|
+
call.respondHtml {
|
|
40
|
+
body {
|
|
41
|
+
h1 { +"Hello, $name" } // "+" operator escapes content
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Sanitizing HTML when you MUST allow some tags
|
|
46
|
+
val sanitizer = HtmlPolicyBuilder()
|
|
47
|
+
.allowElements("b", "i", "u")
|
|
48
|
+
.toFactory()
|
|
49
|
+
val cleanHtml = sanitizer.sanitize(untrustedHtml)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Encoding by Context:**
|
|
53
|
+
|
|
54
|
+
| Context | Purpose | Recommended Encoder |
|
|
55
|
+
|---------|---------|---------------------|
|
|
56
|
+
| HTML Body | `<div>...</div>` | `Encode.forHtml()` |
|
|
57
|
+
| HTML Attribute | `<div title="...">` | `Encode.forHtmlAttribute()` |
|
|
58
|
+
| URL Parameter | `?q=...` | `URLEncoder.encode(s, "UTF-8")` |
|
|
59
|
+
| JavaScript | `var x = '...';` | `Encode.forJavaScript()` |
|
|
60
|
+
| CSS | `color: ...` | `Encode.forCssString()` |
|
|
61
|
+
|
|
62
|
+
**Tools:** OWASP Java Encoder, HTML Sanitizer (Guava), SonarQube (S5131)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use Only Approved Crypto Algorithms
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: ensures cryptographic strength and protects against known attacks
|
|
5
|
+
tags: cryptography, algorithms, hashing, encryption, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use Only Approved Crypto Algorithms
|
|
9
|
+
|
|
10
|
+
Weak cryptographic algorithms (MD5, SHA1, DES) or insecure modes (ECB) have known vulnerabilities and can be broken with modern hardware. Using them puts data at risk of decryption or collision attacks.
|
|
11
|
+
|
|
12
|
+
**Incorrect (weak or deprecated algorithms):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// WEAK hash (MD5/SHA1)
|
|
16
|
+
val md = MessageDigest.getInstance("MD5")
|
|
17
|
+
val hash = md.digest(password.toByteArray())
|
|
18
|
+
|
|
19
|
+
// WEAK encryption mode (ECB mode is insecure)
|
|
20
|
+
val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
|
|
21
|
+
|
|
22
|
+
// WEAK algorithm
|
|
23
|
+
val desCipher = Cipher.getInstance("DES")
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Correct (approved strong algorithms):**
|
|
27
|
+
|
|
28
|
+
```kotlin
|
|
29
|
+
// STRONG hash for integrity
|
|
30
|
+
val digest = MessageDigest.getInstance("SHA-256")
|
|
31
|
+
val hash = digest.digest(data.toByteArray())
|
|
32
|
+
|
|
33
|
+
// STRONG authenticated encryption (GCM mode)
|
|
34
|
+
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
|
|
35
|
+
val spec = GCMParameterSpec(128, iv)
|
|
36
|
+
cipher.init(Cipher.ENCRYPT_MODE, secretKey, spec)
|
|
37
|
+
|
|
38
|
+
// For passwords - use specialized libraries like BCrypt or Argon2 (via Spring Security or Ktor)
|
|
39
|
+
val hashedPassword = BCrypt.withDefaults().hashToString(12, password.toCharArray())
|
|
40
|
+
val isMatched = BCrypt.verifyer().verify(password.toCharArray(), hashedPassword).verified
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Approved vs Prohibited:**
|
|
44
|
+
|
|
45
|
+
| Purpose | Approved | Prohibited |
|
|
46
|
+
|---------|----------|------------|
|
|
47
|
+
| General Hashing | SHA-256, SHA-512, SHA-3 | MD5, SHA-1 |
|
|
48
|
+
| Data Encryption | AES-GCM (256-bit) | DES, 3DES, AES-ECB |
|
|
49
|
+
| Password Hashing | Argon2id, bcrypt (cost >= 12) | SHA-*, plain AES, MD5 |
|
|
50
|
+
|
|
51
|
+
**Tools:** SonarQube (S2070, S4790), Semgrep, detekt (WeakCrypto)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use CSPRNG For Security Purposes
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: prevents predictable tokens, session hijacking, and brute-force attacks
|
|
5
|
+
tags: random, csprng, tokens, session, cryptography, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use CSPRNG For Security Purposes
|
|
9
|
+
|
|
10
|
+
Standard pseudo-random number generators (PRNGs) like `java.util.Random` are predictable. If used for security purposes (sessions, tokens, passwords), an attacker can predict future values by observing previous ones. Cryptographically Secure Pseudo-Random Number Generators (CSPRNG) must be used instead.
|
|
11
|
+
|
|
12
|
+
**Incorrect (predictable random):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// INSECURE - predictable!
|
|
16
|
+
val sessionId = Random().nextLong().toString(16)
|
|
17
|
+
|
|
18
|
+
// INSECURE - based on timestamp and weak random
|
|
19
|
+
val resetToken = "${System.currentTimeMillis()}-${Random().nextInt()}"
|
|
20
|
+
|
|
21
|
+
// INSECURE - Math.random()
|
|
22
|
+
val otp = (Math.random() * 1000000).toInt().toString()
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Correct (cryptographically secure):**
|
|
26
|
+
|
|
27
|
+
```kotlin
|
|
28
|
+
import java.security.SecureRandom
|
|
29
|
+
import java.util.Base64
|
|
30
|
+
|
|
31
|
+
// Cryptographically secure random source
|
|
32
|
+
val secureRandom = SecureRandom()
|
|
33
|
+
|
|
34
|
+
// Secure session ID or token
|
|
35
|
+
val bytes = ByteArray(32)
|
|
36
|
+
secureRandom.nextBytes(bytes)
|
|
37
|
+
val sessionId = Base64.getUrlEncoder().encodeToString(bytes) // 256-bit entropy
|
|
38
|
+
|
|
39
|
+
// Secure OTP generation
|
|
40
|
+
fun generateOTP(length: Int = 6): String {
|
|
41
|
+
val secureRandom = SecureRandom()
|
|
42
|
+
val stringBuilder = StringBuilder()
|
|
43
|
+
repeat(length) {
|
|
44
|
+
stringBuilder.append(secureRandom.nextInt(10))
|
|
45
|
+
}
|
|
46
|
+
return stringBuilder.toString()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Secure UUID v4 (random-based)
|
|
50
|
+
val token = java.util.UUID.randomUUID().toString()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**CSPRNG in JVM/Kotlin:**
|
|
54
|
+
|
|
55
|
+
| Source | Security Level | Purpose |
|
|
56
|
+
|--------|----------------|---------|
|
|
57
|
+
| `java.security.SecureRandom` | **High (CSPRNG)** | Security tokens, salts, keys |
|
|
58
|
+
| `java.util.Random` | Low (PRNG) | Simulations, low-priority sorting |
|
|
59
|
+
| `kotlin.random.Random` | Low (PRNG) | General non-security logic |
|
|
60
|
+
|
|
61
|
+
**Tools:** SonarQube (S2245), detekt (InsecureRandom), Manual Review
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Enable Encrypted Client Hello (ECH)
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: protects Server Name Indication (SNI) from eavesdropping and prevents leaking the visited website to the network
|
|
5
|
+
tags: tls, ech, sni, privacy, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Enable Encrypted Client Hello (ECH)
|
|
9
|
+
|
|
10
|
+
Encrypted Client Hello (ECH) is a TLS extension that encrypts the entire `ClientHello` message during the handshake. This protects the Server Name Indication (SNI), which otherwise would allow network observers (ISPs, public Wi-Fi operators) to see which specific domain you are connecting to.
|
|
11
|
+
|
|
12
|
+
**About ECH:**
|
|
13
|
+
ECH solves the privacy problem where, even with HTTPS, the name of the website you are visiting is sent in plain text (SNI) during the initial connection setup.
|
|
14
|
+
|
|
15
|
+
**Implementation (Server-side via Nginx/Infrastructure):**
|
|
16
|
+
|
|
17
|
+
Kotlin backend applications usually sit behind a reverse proxy like Nginx or a Cloud Load Balancer that handles TLS.
|
|
18
|
+
|
|
19
|
+
```nginx
|
|
20
|
+
# Nginx with ECH support (requires a build with ECH support)
|
|
21
|
+
ssl_ech on;
|
|
22
|
+
ssl_ech_key /etc/nginx/certs/ech_private.key;
|
|
23
|
+
ssl_ech_config_list /etc/nginx/certs/ech_configs.list;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**DNS Configuration:**
|
|
27
|
+
ECH requires an `HTTPS` DNS record to contain the public key used for encrypting the `ClientHello`.
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
# Example HTTPS DNS record
|
|
31
|
+
_https.example.com. IN HTTPS 1 . alpn="h2,h3" ipv4hint=1.2.3.4 ech="<base64_encoded_config>"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Client-side (Kotlin/JVM Environment):**
|
|
35
|
+
Current JVM TLS implementations and typical libraries (OkHttp, Ktor Client) depend on the underlying JVM provider. Security providers like Bouncy Castle or newer Java versions are adding support for modern TLS extensions.
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
// Ensure TLS 1.3 is enabled, as ECH is a TLS 1.3 extension
|
|
39
|
+
val client = OkHttpClient.Builder()
|
|
40
|
+
.connectionSpecs(listOf(ConnectionSpec.RESTRICTED_TLS)) // Enforces TLS 1.3
|
|
41
|
+
.build()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Benefits:**
|
|
45
|
+
- **Privacy:** Prevents network metadata leaks.
|
|
46
|
+
- **Security:** Reduces the effectiveness of censorship and site-specific traffic fingerprinting.
|
|
47
|
+
|
|
48
|
+
**Tools:** Cloudflare (supports ECH), Nginx with ECH, DNS HTTPS records, SSLLabs
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use Secrets Management For Backend Secrets
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: centralizes and secures sensitive credential storage and access control
|
|
5
|
+
tags: secrets, vault, credentials, configuration, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Use Secrets Management For Backend Secrets
|
|
9
|
+
|
|
10
|
+
Sensitive credentials should never reside in plain text within source code or configuration files. Use a dedicated secrets management system to centralize, audit, and rotate credentials securely.
|
|
11
|
+
|
|
12
|
+
**Incorrect (hardcoded or plain environment exposure):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// Hardcoded in code
|
|
16
|
+
const val API_KEY = "sk-live-123456"
|
|
17
|
+
|
|
18
|
+
// application.yml committed to git with real secrets
|
|
19
|
+
database:
|
|
20
|
+
password: "production_password_123"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Correct (automated secrets management):**
|
|
24
|
+
|
|
25
|
+
```kotlin
|
|
26
|
+
// Using a cloud-native Secrets Manager (AWS / GCP / Azure)
|
|
27
|
+
val dbPassword = secretsClient.getSecret("prod/db/password")
|
|
28
|
+
|
|
29
|
+
// Using Kubernetes Secrets integration
|
|
30
|
+
// In Spring Boot, these are often mapped to properties automatically:
|
|
31
|
+
@Value("\${db.password}")
|
|
32
|
+
private lateinit var dbPasswordFromSecret: String
|
|
33
|
+
|
|
34
|
+
// Using Spring Cloud Vault
|
|
35
|
+
// Secrets are retrieved automatically on startup from HashiCorp Vault
|
|
36
|
+
|
|
37
|
+
// Environment validation
|
|
38
|
+
val stripeKey = System.getenv("STRIPE_KEY")
|
|
39
|
+
?: throw IllegalStateException("Required secret STRIPE_KEY is missing")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Secrets Management Hierarchy:**
|
|
43
|
+
1. **Vaults:** (Best) HashiCorp Vault, AWS/GCP/Azure Secret Managers.
|
|
44
|
+
2. **Orchestrator Secrets:** Kubernetes Secrets, Docker Secrets.
|
|
45
|
+
3. **Environment Variables:** Scalable but requires careful process isolation.
|
|
46
|
+
4. **Local Env Files:** Only for local development, must be `.gitignore`d.
|
|
47
|
+
|
|
48
|
+
**Crucial Steps:**
|
|
49
|
+
- Enable Secret Rotation.
|
|
50
|
+
- Use Least Privilege for secret access.
|
|
51
|
+
- Audit logs to monitor who/what accessed which secret.
|
|
52
|
+
|
|
53
|
+
**Tools:** HashiCorp Vault, AWS Secrets Manager, Google Secret Manager, Spring Cloud Config
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Always Use TLS For All Connections
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: protects data in transit from eavesdropping and tampering
|
|
5
|
+
tags: tls, https, encryption, transport, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Always Use TLS For All Connections
|
|
9
|
+
|
|
10
|
+
Transmitting data over unencrypted HTTP, JDBC, or Redis connections exposes sensitive information to everyone on the network path. All connections in production must use TLS 1.2 or higher.
|
|
11
|
+
|
|
12
|
+
**Incorrect (unencrypted connections):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// HTTP API calls
|
|
16
|
+
val client = HttpClient(CIO)
|
|
17
|
+
client.get("http://api.sun-asterisk.vn/users")
|
|
18
|
+
|
|
19
|
+
// Unencrypted database connection
|
|
20
|
+
val url = "jdbc:postgresql://db.sun-asterisk.vn:5432/mydb"
|
|
21
|
+
|
|
22
|
+
// Redis without TLS
|
|
23
|
+
val config = Config().apply {
|
|
24
|
+
useSingleServer().setAddress("redis://redis.sun-asterisk.vn:6379")
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Correct (TLS/SSL everywhere):**
|
|
29
|
+
|
|
30
|
+
```kotlin
|
|
31
|
+
// HTTPS for all APIs
|
|
32
|
+
client.get("https://api.sun-asterisk.vn/users")
|
|
33
|
+
|
|
34
|
+
// TLS for Database (via JDBC parameters)
|
|
35
|
+
val url = "jdbc:postgresql://db.sun-asterisk.vn:5432/mydb?ssl=true&sslmode=verify-full"
|
|
36
|
+
|
|
37
|
+
// Redis with TLS
|
|
38
|
+
val config = Config().apply {
|
|
39
|
+
useSingleServer().setAddress("rediss://redis.sun-asterisk.vn:6380")
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Ktor: Force HTTPS using HSTS
|
|
43
|
+
install(HSTS) {
|
|
44
|
+
maxAgeInSeconds = 31536000 // 1 year
|
|
45
|
+
includeSubDomains = true
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Redirect HTTP to HTTPS in Ktor
|
|
49
|
+
install(HttpsRedirect) {
|
|
50
|
+
sslPort = 443
|
|
51
|
+
permanentRedirect = true
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Requirements:**
|
|
56
|
+
- Minimum TLS version: **1.2** (Recommended: **1.3**).
|
|
57
|
+
- Validate server certificates against a trusted CA (avoid `allowSelfSigned`).
|
|
58
|
+
- Use `rediss://` for secure Redis.
|
|
59
|
+
- Use `ssl=true` for database drivers.
|
|
60
|
+
|
|
61
|
+
**Tools:** SSLyze, Qualys SSL Labs, OWASP ZAP, Manual Review
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Do Not Pass Sensitive Data In Query String
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: prevents sensitive credential leakage in browser history, logs, and referrer headers
|
|
5
|
+
tags: url, query-string, sensitive-data, leakage, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Do Not Pass Sensitive Data In Query String
|
|
9
|
+
|
|
10
|
+
URL query strings are stored in browser history, server access logs, and transmitted in `Referer` headers. Sensitive data like tokens, passwords, or PII (Personally Identifiable Information) must never be part of a URL.
|
|
11
|
+
|
|
12
|
+
**Incorrect (sensitive data in URL):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// Token in URL
|
|
16
|
+
httpClient.get("https://api.sun-asterisk.vn/data?apiKey=$mySecretKey")
|
|
17
|
+
|
|
18
|
+
// Sending sensitive PII in URL
|
|
19
|
+
httpClient.get("https://api.sun-asterisk.vn/profile?email=$userEmail&phone=$phone")
|
|
20
|
+
|
|
21
|
+
// Password-based login via GET
|
|
22
|
+
@GetMapping("/login")
|
|
23
|
+
fun login(@RequestParam pass: String) { ... }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Correct (sensitive data in body or headers):**
|
|
27
|
+
|
|
28
|
+
```kotlin
|
|
29
|
+
// Token in Authorization Header (Stateless)
|
|
30
|
+
httpClient.get("https://api.sun-asterisk.vn/data") {
|
|
31
|
+
headers {
|
|
32
|
+
append(HttpHeaders.Authorization, "Bearer $accessToken")
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Credentials in POST Body
|
|
37
|
+
@PostMapping("/login")
|
|
38
|
+
fun login(@RequestBody credentials: LoginRequest) { ... }
|
|
39
|
+
|
|
40
|
+
// Sensitive search via POST session-based
|
|
41
|
+
@PostMapping("/api/secure-search")
|
|
42
|
+
fun secureSearch(@RequestBody query: SecureSearchRequest) { ... }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Where Query Strings Leak:**
|
|
46
|
+
1. **Server Logs:** Almost all web servers (NGINX, Apache) log the full requested URL.
|
|
47
|
+
2. **Browser History:** Browser "Back" button or history allows anyone with local access to see the sensitive URL.
|
|
48
|
+
3. **Referer Headers:** If the page redirects or the user clicks a link, the URL (with tokens) is sent to the next site.
|
|
49
|
+
4. **Forward Proxies/CDNs:** Any intermediate network device may log the full URL.
|
|
50
|
+
|
|
51
|
+
**Tools:** Semgrep, SonarQube (S2245), Manual Review, OWASP Secure Headers
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Always Use Parameterized Queries
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: prevents SQL and NoSQL injection attacks
|
|
5
|
+
tags: injection, sql, nosql, database, parameterized, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Always Use Parameterized Queries
|
|
9
|
+
|
|
10
|
+
SQL injection is one of the top security vulnerabilities. Direct string concatenation allows attackers to execute arbitrary database commands, steal data, or destroy databases.
|
|
11
|
+
|
|
12
|
+
**Incorrect (string concatenation):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// SQL Injection vulnerability
|
|
16
|
+
val userId = request.params["id"]
|
|
17
|
+
val query = "SELECT * FROM users WHERE id = '$userId'"
|
|
18
|
+
val result = connection.createStatement().executeQuery(query)
|
|
19
|
+
|
|
20
|
+
// Attacker input: ' OR '1'='1
|
|
21
|
+
// Resulting query: SELECT * FROM users WHERE id = '' OR '1'='1'
|
|
22
|
+
// Returns ALL users!
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Correct (parameterized queries):**
|
|
26
|
+
|
|
27
|
+
```kotlin
|
|
28
|
+
// Parameterized query using PreparedStatement
|
|
29
|
+
val userId = request.params["id"]
|
|
30
|
+
val query = "SELECT * FROM users WHERE id = ?"
|
|
31
|
+
val preparedStatement = connection.prepareStatement(query)
|
|
32
|
+
preparedStatement.setString(1, userId)
|
|
33
|
+
val result = preparedStatement.executeQuery()
|
|
34
|
+
|
|
35
|
+
// Using an ORM or Database Library like Exposed or Spring Data JPA
|
|
36
|
+
val user = transaction {
|
|
37
|
+
User.find { Users.id eq userId }.firstOrNull()
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Tools:** SonarQube (S2077, S3649), Semgrep, CodeQL, detekt
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Sanitize Input Before Sending Emails
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: prevents email header injection and spam abuse
|
|
5
|
+
tags: email, injection, sanitization, input-validation, security, kotlin
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Sanitize Input Before Sending Emails
|
|
9
|
+
|
|
10
|
+
Email header injection occurs when an attacker can inject CRLF (Carriage Return + Line Feed) characters into email fields (Subject, From, To, etc.). This allows them to manipulate the SMTP protocol to add their own headers (like `Bcc:` or `Cc:`) and send unauthorized spam via your server.
|
|
11
|
+
|
|
12
|
+
**Incorrect (unsanitized input):**
|
|
13
|
+
|
|
14
|
+
```kotlin
|
|
15
|
+
// Email injection vulnerability
|
|
16
|
+
val subject = request.getParameter("subject") // Attacker: "Hello\r\nBcc: spam@evil.com"
|
|
17
|
+
val helper = MimeMessageHelper(message)
|
|
18
|
+
helper.setSubject(subject) // Now Bcc: spam@evil.com is part of the email headers!
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Correct (sanitized email fields):**
|
|
22
|
+
|
|
23
|
+
```kotlin
|
|
24
|
+
fun sanitizeEmailHeader(input: String): String {
|
|
25
|
+
// Remove all CRLF characters to prevent header injection
|
|
26
|
+
return input.replace("[\r\n]".toRegex(), "").trim()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fun isValidEmail(email: String): Boolean {
|
|
30
|
+
val emailRegex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$".toRegex()
|
|
31
|
+
return emailRegex.matches(email) && !email.contains("\n") && !email.contains("\r")
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@PostMapping("/api/contact")
|
|
35
|
+
fun send(@RequestBody req: ContactRequest) {
|
|
36
|
+
if (!isValidEmail(req.to)) throw ValidationException("Invalid email format")
|
|
37
|
+
|
|
38
|
+
val helper = MimeMessageHelper(message)
|
|
39
|
+
helper.setTo(sanitizeEmailHeader(req.to))
|
|
40
|
+
helper.setSubject(sanitizeEmailHeader(req.subject))
|
|
41
|
+
helper.setText(req.body) // Message body is usually safe from header injection
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Prevention Strategies:**
|
|
46
|
+
- **Whitelisting:** Strictly validate email formats.
|
|
47
|
+
- **Header Stripping:** Automatically strip or replace all `\r` and `\n` characters from variables that will be used in email headers.
|
|
48
|
+
- **Modern Libraries:** Use high-level mailing libraries (like Spring Mail or Ktor Mail) that often perform basic sanitization, but always double-check and manually sanitize user input.
|
|
49
|
+
|
|
50
|
+
**Tools:** OWASP ESAPI, Hibernate Validator (@Email), Manual Review
|