Writing Detekt Security Rules for Kotlin

    1

    They do not find a @PreAuthorize on a suspend fun — which Spring silently ignores, because coroutine desugaring creates a state machine the proxy never instruments.

    Free

    Security scanned

    Works with the AI Agents you already use

    Claude CodeClaude CodeCursorCursorCodex CLICodex CLIMuseMuseDotsDots+22 more

    Writing Detekt Security Rules for Kotlin

    Example session with this skill installed

    Help me write a detekt rule to find hardcoded DES encryption in Kotlin code.

    • Read your context and instructions
    • Compiled the writing detekt security

    I have generated the detekt rule for detecting DES encryption calls, including the rule class, test suite, and configuration wiring.

    Dangerous Call Rule: Weak Cipher Detection

    package io.github.security.rules.a02
    
    import io.gitlab.arturbosch.detekt.api.*
    import org.jetbrains.kotlin.psi.KtCallExpression
    import org.jetbrains.kotlin.psi.psiUtil.contains
    
    /**
     * OWASP A02:2021 — Cryptographic Failures
     *
     * DES is considered cryptographically broken and insecure.
     * 
     * Non-compliant:
     *   Cipher.getInstance("DES")
     *
     * Compliant:
     *   Cipher.getInstance("AES/GCM/NoPadding")
     */
    class WeakCipherRule(config: Config) : SecurityRule(config) {
    
        override val issue = Issue(
            id = "WeakCipherDES",
            severity = Severity.Security,
            description = "DES is a broken cipher. Use AES/GCM instead.",
            debt = Debt.TEN_MINS,
        )
    
        private val weakAlgorithms = setOf("DES", "DESede")
    
        override fun visitCallExpression(expression: KtCallExpression) {
            super.visitCallExpression(expression)
            
            if (!expression.text.contains("getInstance")) return
    
            val arguments = expression.valueArguments
            if (arguments.isEmpty()) return
    
            val argumentText = arguments[0].getArgumentExpression()?.text?.replace("\"", "")
            
            if (weakAlgorithms.any { argumentText?.contains(it) == true }) {
                reportAt(expression, "Insecure encryption algorithm (DES) detected.")
            }
        }
    }
    

    Test Suite Structure

    class WeakCipherRuleTest {
        private val rule = WeakCipherRule(Config.empty)
    
        @Test
        fun `flags DES getInstance`() {
            val code = """val c = Cipher.getInstance("DES")"""
            assertThat(rule.lint(code)).hasSize(1)
        }
    
        @Test
        fun `ignores AES getInstance`() {
            val code = """val c = Cipher.getInstance("AES/GCM/NoPadding")"""
            assertThat(rule.lint(code)).isEmpty()
        }
    
        @Test
        fun `isolation - does not flag coroutine security issues`() {
            val code = """suspend fun secure() = withContext(Dispatchers.IO) {}"""
            assertThat(rule.lint(code)).isEmpty()
        }
    }
    

    Next steps

    1. Add WeakCipherRule to your SecurityRuleSetProvider.
    2. Append WeakCipherDES: active: true to your detekt.yml.
    3. Map WeakCipherDES to CWE-327 in your CweMapping.kt file.

    Connects securely to your tools. The creator never sees your data.

    About this skill

    Generic scanners find hardcoded passwords. They do not find a @PreAuthorize on a suspend fun — which Spring silently ignores, because coroutine desugaring creates a state machine the proxy never instruments. The annotation compiles, reads as protection, and the endpoint is unauthenticated.

    That class of bug is framework-specific, invisible to bytecode analysis, and exactly what a custom detekt rule is for.

    This is the method behind a 216-rule ruleset across seven frameworks — including the mistakes it made getting there.

    · The doctrine: one false positive is worse than ten missing rules, because suppression is not per-rule in practice — people disable the plugin, and your accurate rules die with the noisy one · Five archetypes that collapse most of the design decision · The five files a rule touches, all of which fail silently if missed · Precision without type resolution: exclude the constant case, check the argument not the call, bail out when you cannot tell · Three-layer tests, including the isolation test almost no ruleset has — a different rule's positive fixture must be silent in yours, which is what catches the over-broad predicate that quietly claims its neighbours' findings · A shared SafeExamples file at zero findings, as a release blocker · The cadence lesson: a push from 178 to 201 rules in large batches produced roughly 45 defects found in a later audit. Bulk addition hides bugs. · Scanning application.properties from a Kotlin visitor, with the per-file instance trap and reporting at the config file's own line · The near-misses that cost real credibility: DES matching DESede, auth matching author, server.ssl matching server.ssl.enabled

    Working Kotlin throughout, plus references on PSI patterns and their pitfalls, testing, false positives, ruleset structure, and config-file scanning.

    How to use

    Skills on Agensi run inside your AI agent. Copy the prompt, paste it into your agent, and it connects to Agensi and installs this skill for you. If a payment is needed, your agent shows it to you first.

    Reviews

    No reviews yet

    Be one of the first to try it. Every listed skill passes our trust checks below.

    Security scanned

    Passed our 8-point scan before listing

    Fresh listing

    Recently published to Agensi

    Free forever

    No account required to browse

    Trust & safety

    Security scanned

    Verified clean 1 day ago

    • Free to download with an account

    Listed1 day ago

    What's inside

    Frequently Asked Questions