Skip to content

Semgrep kotlin rules


Summary:

Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting')

Severity: Critical

CWE: CWE-113

Description:

The application passes user-controlled input from HttpServletRequest methods (such as getParameter(), getHeader(), getParameterMap(), or getPathInfo()) directly to HttpServletResponse.setHeader() or HttpServletResponse.addHeader() methods without proper sanitization of CR (\r) and LF (\n) characters. This creates a critical HTTP response splitting vulnerability where attackers can inject CRLF sequences to terminate the current header section and inject arbitrary HTTP headers or even complete HTTP responses. Attackers can exploit this to perform Cross-Site Scripting (XSS) by injecting malicious content, cache poisoning by manipulating cache-control headers, session fixation by setting cookies, or HTTP request smuggling attacks that can bypass security controls.

Remediation:

Consider implementing strict input validation and sanitization before passing any user- controlled data to setHeader() or addHeader() methods. Use String.replace() with a regex pattern to remove CR and LF characters: val sanitized = userInput.replace(Regex( "[\\r\\n]+"), ""). Can also use org.apache.commons.text.StringEscapeUtils. unescapeJava() for proper escaping of control characters. Recommended to use an allowlist approach where you validate that header values match expected patterns (e.g., alphanumeric characters only) rather than attempting to sanitize arbitrary input. Consider whether user input should ever directly control HTTP headers - in most cases, a safer design uses user input to select from predefined safe header values rather than directly incorporating the input. Modern servlet containers provide some response splitting protections, but application-level validation is critical as these protections are not comprehensive and may be bypassed.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_cors_rule-PermissiveCORSInjection

Summary:

Permissive cross-domain policy with untrusted domains

Severity: Critical

CWE: CWE-942

Description:

User-controlled input is used to set the Access-Control-Allow-Origin header via HttpServletResponse.setHeader() or addHeader(). This allows attackers to inject malicious origins, enabling cross-domain attacks that can lead to data theft, spoofing, and unauthorized access to sensitive information.

Remediation:

Consider maintaining a static allowlist of trusted origins and validating incoming origin values against this list before setting the Access-Control-Allow-Origin header. Recommended to never directly reflect the request origin header without validation. Avoid using the wildcard * when credentials are involved, as this creates security vulnerabilities. Implement server-side validation to ensure only approved domains can access your resources.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_crypto_rule-CipherECBMode

Summary:

Inadequate Encryption Strength

Severity: Critical

CWE: CWE-326

Description:

The application uses javax.crypto.Cipher.getInstance() with ECB (Electronic Code Book) mode, which does not provide semantic security. ECB mode encrypts identical plaintext blocks into identical ciphertext blocks, revealing patterns in the encrypted data. This allows attackers to identify repeated data, perform block substitution attacks, and in many cases deduce information about the plaintext without breaking the encryption. The famous ECB penguin image demonstrates how ECB preserves visual patterns even after encryption, making it completely unsuitable for encrypting structured or patterned data.

Remediation:

Replace ECB mode with GCM mode for authenticated encryption using javax.crypto.Cipher.getInstance("AES/GCM/NoPadding"). GCM provides both confidentiality and authenticity protection, making it the recommended choice for modern applications. Generate a unique 12-byte nonce for each encryption operation using java.security.SecureRandom and pass it to the cipher via GCMParameterSpec. Never reuse nonces with the same key as this catastrophically breaks GCM security. If GCM is not available in your environment, use CBC mode with HMAC authentication as a fallback, but ensure proper IV generation and MAC-then-encrypt construction. For Kotlin projects, consider using Google's Tink library which provides safe authenticated encryption primitives with secure defaults.


kotlin_crypto_rule-CipherIntegrity

Summary:

Use of a broken or risky cryptographic algorithm

Severity: Critical

CWE: CWE-327

Description:

The application uses javax.crypto.Cipher.getInstance() with cipher modes (CBC, OFB, CTR, or ECB) that provide no integrity protection, making the ciphertext susceptible to tampering by adversaries. Without authentication, attackers can modify ciphertext bits to alter the resulting plaintext in predictable ways, enabling bit-flipping attacks, padding oracle attacks, and chosen-ciphertext attacks. These modes only provide confidentiality, but modern security requires both confidentiality and authenticity to prevent undetected modification of encrypted data.

Remediation:

Use authenticated encryption with associated data (AEAD) by migrating to AES-GCM mode with javax.crypto.Cipher.getInstance("AES/GCM/NoPadding"). GCM provides both encryption and authentication in a single operation, protecting against tampering without requiring manual MAC implementation. Generate unique 12-byte nonces using java.security.SecureRandom for each encryption and pass them via GCMParameterSpec. Never reuse nonces with the same key. If AES-GCM is not available, implement encrypt-then-MAC using CBC mode with HMAC-SHA256, but note this requires careful implementation to avoid timing attacks. For Kotlin applications, strongly consider using Google's Tink library which provides safe AEAD primitives with secure defaults and prevents common implementation errors.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_crypto_rule-CipherPaddingOracle

Summary:

Use of a broken or risky cryptographic algorithm

Severity: Critical

CWE: CWE-327

Description:

The application uses javax.crypto.Cipher.getInstance() with CBC mode and PKCS5Padding, which is susceptible to padding oracle attacks. Adversaries can potentially decrypt messages by exploiting timing differences or error messages that reveal whether padding is valid or invalid after decryption. By repeatedly modifying ciphertext and observing the system's response to padding validation, attackers can decrypt data byte-by-byte without knowing the encryption key. This vulnerability is particularly dangerous when error messages distinguish between padding errors and MAC failures, or when timing differences reveal padding validation results.

Remediation:

Migrate to authenticated encryption using AES-GCM mode with javax.crypto.Cipher.getInstance("AES/GCM/NoPadding"), which eliminates padding oracle vulnerabilities by using a stream cipher mode that requires no padding. GCM provides built-in authentication that detects any ciphertext modification before decryption begins. Generate unique 12-byte nonces using java.security.SecureRandom for each encryption operation and pass them via GCMParameterSpec. If CBC mode must be retained for legacy compatibility, implement encrypt-then-MAC with constant-time comparison and ensure all decryption errors return identical error messages and timing characteristics. For Kotlin applications, strongly consider using Google's Tink library which provides AEAD primitives that are immune to padding oracle attacks.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_endpoint_rule-UnvalidatedRedirect

Summary:

URL redirection to untrusted site ('Open Redirect')

Severity: Critical

CWE: CWE-601

Description:

Open redirect vulnerability detected in HTTP response handling. This rule identifies user-controlled input (from request parameters, headers, or cookies) being passed directly to HttpServletResponse.sendRedirect() or addHeader("Location") without validation. Attackers can craft malicious URLs that redirect users to phishing sites while appearing to originate from a trusted domain, facilitating credential theft and social engineering attacks.

Remediation:

Consider validating redirect URLs against an allowlist of trusted domains or paths before performing the redirect. Recommended to use relative paths (e.g., /dashboard) instead of absolute URLs when redirecting within the same application. If external redirects are required, maintain an allowlist of approved domains and validate that the redirect URL matches using allowedDomains.any { url.startsWith(it) }. Alternatively, use indirect references (e.g., redirect IDs mapped to safe URLs) rather than accepting raw URLs from user input.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_file_rule-FileUploadFileName

Summary:

Improper limitation of a pathname to a restricted directory ('Path Traversal')

Severity: Critical

CWE: CWE-22

Description:

Path traversal vulnerability in file upload handling detected using methods like 'FileItem.getName()' or 'Part.getSubmittedFileName()'. These methods return filenames directly from client requests, which can be manipulated to include path traversal sequences like '../' or absolute paths. Using unsanitized filenames can allow attackers to write files to arbitrary locations on the server filesystem, potentially overwriting critical files.

Remediation:

Consider extracting only the base filename without any path components from 'getName()' or 'getSubmittedFileName()' results. Recommended to strip all path separator characters like '/', '\', and '..' sequences before using the filename. Validate file extensions against a strict allowlist of permitted types. Generate random filenames instead of using client-provided names when possible, storing the original name separately in metadata.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_inject_rule-FileDisclosure

Summary:

Files or directories accessible to external parties

Severity: Critical

CWE: CWE-552

Description:

The application uses user-controlled input from HttpServletRequest.getParameter() to construct view paths in Spring MVC's ModelAndView constructor or setViewName(), Struts ActionForward paths, or servlet RequestDispatcher.forward()/include() calls, which enables arbitrary file disclosure. When attackers control the view or forward path, they can manipulate it to access sensitive files outside the intended view directory, including application binaries (JAR files, class files), configuration files, or other protected resources. This occurs because frameworks resolve view names to file paths, and insufficient validation allows path traversal sequences or direct file references to bypass security boundaries. The vulnerability is particularly severe in Spring MVC and Struts applications where view resolution mechanisms can be exploited to access arbitrary files on the server filesystem.

Remediation:

Never use user input directly to construct view names or forward paths. Instead, use an indirect reference mapping where user input selects from a predefined set of valid view names (e.g., a Map that maps user-provided identifiers to actual view paths). For Spring MVC, use controller method return values with hardcoded view names and pass user data only as model attributes. Implement strict input validation using an allowlist of permitted view identifiers, rejecting any input containing path traversal sequences (.., /, \) or absolute path indicators. Consider using Spring's RedirectView with the setContextRelative(true) option for safer redirects, or use HTTP redirects to predefined URLs instead of server-side forwards. For Struts applications, define all forward mappings in configuration files rather than constructing them dynamically. Modern frameworks like Spring Boot with Thymeleaf or FreeMarker provide better isolation between user input and view resolution, reducing this risk when configured properly.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_inject_rule-HttpParameterPollution

Summary:

Improper neutralization of argument delimiters in a command ('Argument Injection')

Severity: Critical

CWE: CWE-88

Description:

The application concatenates user input from HttpServletRequest.getParameter() into HTTP URLs used with Apache HttpClient's HttpGet or GetMethod constructors without proper encoding, which enables HTTP Parameter Pollution (HPP) attacks. When user input containing URL special characters like &, =, ?, or % is directly incorporated into query strings, attackers can inject additional parameters or override existing ones. For example, if user input admin&role=user is concatenated into a URL, it could split into two parameters, potentially bypassing authorization checks or manipulating application logic. This vulnerability is particularly dangerous because different server-side technologies handle duplicate parameters differently (first value, last value, or array), allowing attackers to exploit inconsistent parameter parsing to bypass security controls or alter application behavior.

Remediation:

Always use proper URL encoding functions like java.net.URLEncoder.encode() or Google Guava's UrlEscapers.urlPathSegmentEscaper().escape() to sanitize user input before incorporating it into URLs. For modern Kotlin applications, consider using URIBuilder from Apache HttpComponents which provides a safer API for constructing URLs with automatic parameter encoding (e.g., URIBuilder(baseUrl).addParameter("key", userInput).build()). This approach separates parameter names and values, preventing injection attacks. When using Kotlin with Spring's RestTemplate or WebClient, use URI template variables with uriVariables parameter which handles encoding automatically. Implement input validation to reject any user input containing URL special characters (&, =, ?, #, %) before encoding. For API clients, consider using higher-level HTTP libraries like Ktor Client or OkHttp which provide builder patterns with built-in parameter encoding. Never rely on manual string concatenation for building URLs with dynamic content.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_inject_rule-SqlInjection

Summary:

Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

Severity: Critical

CWE: CWE-89

Description:

The application constructs SQL queries using user-controlled input with string concatenation or Kotlin string templates in APIs like java.sql.Statement.executeQuery(), Connection.prepareStatement(), Hibernate's Session.createQuery(), Spring JDBC's JdbcTemplate.query(), or JPA's EntityManager.createQuery(), which enables SQL injection attacks. When user input is directly incorporated into SQL query strings (e.g., statement.executeQuery("SELECT * FROM users WHERE id = $userId") or using String.format() or StringBuilder), attackers can inject malicious SQL to bypass authentication, extract sensitive data, modify database contents, or execute administrative operations. Unlike languages with prepared statements, string concatenation provides no separation between SQL code and data, allowing attackers to manipulate query logic with special characters like quotes, comments (--), or SQL keywords. This vulnerability affects all database operations including queries, updates, and stored procedure calls.

Remediation:

Use parameterized queries with bind variables through JDBC PreparedStatement, Spring's NamedParameterJdbcTemplate, or JPA/Hibernate parameter binding. For JDBC, replace string concatenation with placeholders: connection.prepareStatement("SELECT * FROM users WHERE id = ?").apply { setInt(1, userId) }. For Spring JDBC, use named parameters: jdbcTemplate.queryForObject("SELECT * FROM users WHERE id = :id", mapOf("id" to userId), ...). For JPA/Hibernate, use parameter binding in JPQL: entityManager.createQuery("... WHERE id = :id").setParameter("id", userId). Kotlin's Exposed framework provides a type-safe DSL that prevents SQL injection by design. For dynamic queries, use query builders like jOOQ or Exposed rather than string concatenation. When using Spring Data JPA, leverage @Query annotations with parameter binding or derived query methods which are safe by default. Never use string templates or concatenation for SQL construction. For complex dynamic queries, use criteria builders or specification patterns that construct queries programmatically with proper parameterization. The JDBI library offers a fluent API with automatic parameter binding for Kotlin applications.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_password_rule-ConstantDBPassword

Summary:

Use of hard-coded password

Severity: Critical

CWE: CWE-259

Description:

A hard-coded password was detected in a call to java.sql.DriverManager.getConnection(). This is dangerous because passwords embedded directly in source code can be easily extracted by anyone with access to the codebase or compiled binaries, leading to unauthorized database access. Hard-coded credentials make it extremely difficult to audit access, rotate compromised credentials, or enforce security policies across environments.

Remediation:

Consider loading database passwords from secure external sources rather than hard-coding them in your application. Recommended approaches include using a Key Management System (KMS) which provides audit logging and easy credential rotation in the event of a breach. For Google Cloud Platform, consider using Cloud Key Management (https://cloud.google.com/kms/docs). For Amazon Web Services, consider AWS Key Management (https://aws.amazon.com/kms/). For on-premise deployments or cloud-agnostic solutions, consider Hashicorp Vault (https://www.vaultproject.io/). Alternatively, use environment variables or configuration files with restricted permissions, stored outside version control. This separation ensures credentials can be managed independently from application code and rotated without requiring code changes.

OWASP:

  • A2:2017-Broken Authentication
  • A07:2021-Identification and Authentication Failures

kotlin_password_rule-EmptyDBPassword

Summary:

Missing authentication for critical function (database)

Severity: Critical

CWE: CWE-306

Description:

An empty password was detected in a call to java.sql.DriverManager.getConnection(). This establishes an unauthenticated database connection, which is dangerous because it allows anyone with network access to the database to execute queries without providing credentials. This violates the principle of least privilege and can lead to unauthorized data access, modification, or deletion. Unauthenticated database connections bypass critical access controls and audit mechanisms.

Remediation:

Consider configuring your database server to require authentication and restricting user privileges to only the queries and operations necessary for the application. Consult your database server's documentation for instructions on creating users with passwords and setting appropriate permissions. Once authentication is enabled, load credentials from secure external sources such as a Key Management System (KMS), which provides audit logging and credential rotation capabilities. For Google Cloud Platform, consider Cloud Key Management (https://cloud.google.com/kms/docs). For Amazon Web Services, consider AWS Key Management (https://aws.amazon.com/kms/). For on-premise or cloud-agnostic deployments, consider Hashicorp Vault (https://www.vaultproject.io/). Alternatively, use environment variables or externalized configuration files with restricted file permissions, ensuring credentials are never committed to version control.

OWASP:

  • A2:2017-Broken Authentication
  • A07:2021-Identification and Authentication Failures

kotlin_script_rule-ScriptInjection

Summary:

Improper control of generation of code ('Code Injection')

Severity: Critical

CWE: CWE-94

Description:

User-controlled input is passed to script evaluation functions such as ScriptEngine.eval(), Invocable.invokeFunction(), or Invocable.invokeMethod(). This allows attackers to execute arbitrary code within the application context, potentially leading to complete system compromise, data exfiltration, or privilege escalation. Script injection vulnerabilities are particularly dangerous as they provide direct code execution capabilities.

Remediation:

Consider avoiding the use of dynamic script evaluation with user input entirely. Recommended to refactor code to use static method calls or predefined operations instead. If script evaluation is absolutely necessary, implement strict allowlist validation for function names and parameters. Never pass unsanitized user input to eval(), invokeFunction(), or invokeMethod() as these functions execute arbitrary code with the application's privileges.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_smtp_rule-InsecureSmtp

Summary:

Improper validation of certificate with host mismatch

Severity: Critical

CWE: CWE-297

Description:

Insecure SMTP configuration detected with Apache Commons Email classes (SimpleEmail, MultiPartEmail, HtmlEmail, ImageHtmlEmail) that do not enable server identity verification. Without setSSLCheckServerIdentity(true), the application is vulnerable to man-in-the-middle attacks where attackers can intercept email communications even when SSL/TLS is enabled.

Remediation:

Consider enabling SSL server identity verification by calling setSSLCheckServerIdentity(true) on all Apache Commons Email instances. Recommended to always use this setting in conjunction with setSSLOnConnect(true) to ensure both encryption and proper certificate validation. This prevents man-in-the-middle attacks by verifying the server's certificate matches the expected hostname before transmitting sensitive email content.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_smtp_rule-SmtpClient

Summary:

Improper neutralization of special elements used in a command

Severity: Critical

CWE: CWE-77

Description:

SMTP header injection vulnerability detected in MimeMessage operations. This rule identifies user input passed to MimeMessage.setSubject(), addHeader(), setDescription(), or setDisposition() without sanitization. Attackers can inject carriage return (CR) and line feed (LF) characters to add arbitrary email headers, potentially enabling spam relay, phishing, or email content manipulation.

Remediation:

Consider sanitizing user input before passing it to SMTP header methods by removing or replacing newline characters (CR/LF). Recommended to use safe email libraries like Apache Commons Email or Simple Java Mail, which automatically filter special characters that can lead to header injection. For manual sanitization, remove \r and \n characters using input.replace("\\r", "").replace("\\n", "") or validate that input contains no control characters before constructing email headers.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_ssrf_rule-SSRF

Summary:

Server-Side Request Forgery (SSRF)

Severity: Critical

CWE: CWE-918

Description:

This rule detected user-controlled input being used to construct Kotlin network connections through java.net.URL, java.net.URI, or java.net.InetSocketAddress without proper validation. The patterns identify cases where non-literal values are passed to constructors like URL(), URI(), or InetSocketAddress(), followed by methods such as connect(), openConnection(), openStream(), getContent(), or the content property. When user input controls URLs or hostnames in these network operations, Server-Side Request Forgery (SSRF) vulnerabilities arise that allow attackers to force the server to access internal resources, cloud metadata endpoints (169.254.169.254), administrative interfaces, or perform network scanning that bypasses firewall protections and network segmentation.

Remediation:

Consider implementing a strict URL allowlist that validates user input against approved domains before constructing URL or URI objects. Use Kotlin's extension functions with java.net.URI to parse and validate the scheme, host, and port components, rejecting any URLs that don't match the allowlist. Implement DNS rebinding protection by resolving hostnames using InetAddress.getByName() and blocking connections to private IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and cloud metadata addresses (169.254.169.254). For Kotlin applications using OkHttp or other HTTP clients, configure custom interceptors or DNS resolvers that enforce IP address filtering. Network-level defenses can include running the application in containerized environments with egress filtering rules that prevent connections to internal networks. Consider using a server-side mapping approach where user input provides keys that map to pre-configured safe URLs rather than accepting arbitrary URLs.

OWASP:

  • A1:2017-Injection
  • A10:2021-Server-Side Request Forgery

kotlin_strings_rule-FormatStringManipulation

Summary:

Use of externally-controlled format string

Severity: Critical

CWE: CWE-134

Description:

Using user input from HttpServletRequest.getParameter() directly in format string methods like String.format(), Formatter.format(), PrintStream.printf(), or PrintStream.format() creates a format string injection vulnerability. Attackers can inject malicious format specifiers (such as %s, %x, %n) to cause exceptions that crash the application, or use format specifiers to access and leak sensitive data from unused arguments passed to the formatting function. This is particularly dangerous when the format string is concatenated with user input without proper sanitization.

Remediation:

Consider treating the format string as a constant and using user input only as arguments to the format function, never as part of the format string itself. For example, instead of String.format(userInput + " result", value), use String.format("%s result", userInput) where the format string "%s result" is hardcoded and safe. If dynamic formatting is required, implement a strict allowlist of permitted format patterns and validate user input against this list before use. Alternatively, use simple string concatenation or template strings where format specifiers cannot be injected. Recommended to sanitize or reject any input containing format specifier characters like '%' when building format strings, and consider using structured logging frameworks that separate message templates from user data.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_templateinjection_rule-TemplateInjection

Summary:

Improper control of generation of code ('Code Injection')

Severity: Critical

CWE: CWE-94

Description:

Server-side template injection vulnerability detected in Velocity, FreeMarker, or Pebble template engine. User-controlled input is passed directly to template methods like 'Velocity.evaluate()', 'Configuration.getTemplate()', or 'PebbleEngine.getTemplate().evaluate()'. This allows attackers to inject malicious template code that executes arbitrary code on the server.

Remediation:

Consider using a safe template configuration that restricts template access to trusted locations only. Recommended to use 'VelocityContext' with predefined variables instead of passing user input directly in template strings or template names. Never allow user input to control template content or template file paths. Validate and sanitize all inputs used in template operations against a strict allowlist of permitted values.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_xpathi_rule-XpathInjection

Summary:

Improper neutralization of data within XPath expressions ('XPath Injection')

Severity: Critical

CWE: CWE-643

Description:

XPath injection vulnerability detected when user input is passed to XPath.compile() or XPath.evaluate() without proper sanitization. This allows attackers to manipulate XPath queries to extract unauthorized data from XML documents or bypass security controls. Untrusted input must be properly parameterized before being used in XPath expressions.

Remediation:

Consider using XPathVariableResolver to parameterize XPath queries instead of concatenating user input directly into XPath expressions. Recommended to call setXPathVariableResolver() on the XPath object and reference variables in the query string using $variableName syntax. If parameterization is not feasible, validate and sanitize all user input against a strict allowlist before inclusion in XPath expressions.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_xxe_rule-SaxParserXXE

Summary:

Improper restriction of XML external entity reference ('XXE')

Severity: Critical

CWE: CWE-611

Description:

The application uses SAXParserFactory.newInstance() and newSAXParser() to create an XML parser without disabling external entity processing, making it vulnerable to XML External Entity (XXE) attacks. When the SAX parser processes untrusted XML input without proper security features configured, attackers can exploit external entity references to read arbitrary files, perform SSRF attacks against internal services, exfiltrate data through out-of-band channels, or trigger Denial of Service through entity expansion attacks like billion laughs.

Remediation:

Configure the SAXParserFactory to disable DOCTYPE declarations entirely by calling setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) before creating the parser. This prevents all XXE vulnerabilities, entity expansion attacks, and billion laughs DoS by blocking DTD processing completely. Alternatively, enable XMLConstants.FEATURE_SECURE_PROCESSING for additional security restrictions. Example: val factory = SAXParserFactory.newInstance(); factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); val parser = factory.newSAXParser(); parser.parse(inputStream, handler); Additional guidance at https://cheatsheatseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_xxe_rule-XMLRdr

Summary:

Improper restriction of XML external entity reference ('XXE')

Severity: Critical

CWE: CWE-611

Description:

The application uses XMLReaderFactory.createXMLReader() to create an XML parser without disabling external entity processing, making it vulnerable to XML External Entity (XXE) attacks. When the XMLReader processes untrusted XML input with external entity support enabled, attackers can exploit this to read arbitrary files from the filesystem, conduct SSRF attacks against internal network services, exfiltrate sensitive data, or cause Denial of Service through entity expansion attacks. The XMLReaderFactory class is deprecated and lacks modern security configuration options.

Remediation:

Migrate to SAXParserFactory instead of the deprecated XMLReaderFactory and configure it to disable DOCTYPE declarations using setFeature("http://apache.org/xml/features/disallow-doctype-decl", true). This prevents XXE attacks, entity expansion vulnerabilities, and billion laughs DoS by completely blocking DTD processing. Alternatively, enable XMLConstants.FEATURE_SECURE_PROCESSING for comprehensive security restrictions. Example: val factory = SAXParserFactory.newInstance(); factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); val parser = factory.newSAXParser(); parser.parse(inputStream, handler); See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_xxe_rule-XMLStreamRdr

Summary:

Improper restriction of XML external entity reference ('XXE')

Severity: Critical

CWE: CWE-611

Description:

The application uses XMLInputFactory.newFactory() and createXMLStreamReader() to create a StAX XML parser without disabling external entity processing, making it vulnerable to XML External Entity (XXE) attacks. When the XMLStreamReader processes untrusted XML input with DTD support and external entities enabled, attackers can exploit this to read arbitrary files, perform SSRF attacks to internal systems, exfiltrate data through external DTD references, or cause Denial of Service through billion laughs and quadratic blowup entity expansion attacks.

Remediation:

Configure the XMLInputFactory to disable both DTD support and external entities before creating the stream reader by setting setProperty(XMLInputFactory.SUPPORT_DTD, false) and setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false). Disabling DTD support prevents XXE attacks, entity expansion vulnerabilities, and billion laughs DoS by blocking all DTD processing. Example: val factory = XMLInputFactory.newFactory(); factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); val reader = factory.createXMLStreamReader(inputStream); Additional guidance at https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_password_rule-HardcodePassword

Summary:

Use of hard-coded password

Severity: High

CWE: CWE-259

Description:

A hard-coded password was detected in sensitive cryptographic or authentication APIs including KeyStore.load(), PBEKeySpec(), PasswordAuthentication(), KeyManagerFactory.init(), DriverManager.getConnection(), and related methods. This is dangerous because passwords embedded directly in source code can be easily extracted by anyone with access to the codebase, decompiled bytecode, or binary artifacts. Hard-coded credentials cannot be rotated without code changes, make access auditing nearly impossible, and expose systems to compromise if the source code or compiled application is leaked.

Remediation:

Consider loading passwords and sensitive credentials from secure external sources instead of hard-coding them in your application. Recommended approaches include using a Key Management System (KMS) which provides centralized credential management, audit logging, and easy rotation in case of security breaches. For Google Cloud Platform, consider Cloud Key Management (https://cloud.google.com/kms/docs). For Amazon Web Services, consider AWS Key Management (https://aws.amazon.com/kms/). For on-premise deployments or cloud-agnostic solutions, consider Hashicorp Vault (https://www.vaultproject.io/). Additional secure options include environment variables, externalized configuration files with restricted permissions, or secrets management tools specific to your deployment platform. Ensure that credentials are never committed to version control systems and are managed independently from application code to enable rotation without deployment.

OWASP:

  • A2:2017-Broken Authentication
  • A07:2021-Identification and Authentication Failures

Summary:

Sensitive cookie without 'HttpOnly' flag

Severity: Medium

CWE: CWE-1004

Description:

The application creates a javax.servlet.http.Cookie object and adds it to the HttpServletResponse using addCookie() without calling setHttpOnly(true) on the cookie instance. The HttpOnly flag is a browser security directive that prevents client-side JavaScript from accessing the cookie through document.cookie. When a user becomes the target of a Cross-Site Scripting (XSS) attack, an attacker can steal sensitive cookies such as session identifiers, authentication tokens, or other security- critical data that should remain server-side only.

Remediation:

Consider calling setHttpOnly(true) on all Cookie objects that contain sensitive data before adding them to the response. This should be done immediately after instantiating the cookie: val cookie = Cookie("sessionId", value); cookie.setHttpOnly( true); response.addCookie(cookie). The HttpOnly flag is particularly critical for session cookies, authentication tokens, and CSRF tokens that should never be accessible to JavaScript. Note that HttpOnly cookies can still be sent to the server in requests and accessed by server-side code, so this protection does not interfere with normal authentication flows. For Spring Boot applications, recommended to configure session cookies globally via server.servlet.session.cookie.http-only=true in application properties rather than managing this per-cookie.

OWASP:

  • A6:2017-Security Misconfiguration
  • A05:2021-Security Misconfiguration

Summary:

Sensitive cookie in HTTPS session without 'Secure' attribute

Severity: Medium

CWE: CWE-614

Description:

The application creates a javax.servlet.http.Cookie object and adds it to the HttpServletResponse using addCookie() without calling setSecure(true) on the cookie instance. The Secure flag is a browser security directive that instructs the browser to only transmit the cookie over HTTPS connections. Without this flag, cookies can be transmitted over unencrypted HTTP connections, exposing them to network eavesdropping and man-in-the-middle attacks where attackers on the network path can intercept sensitive cookie values including session identifiers and authentication tokens.

Remediation:

Consider calling setSecure(true) on all Cookie objects that contain sensitive data before adding them to the response. This should be done immediately after instantiating the cookie: val cookie = Cookie("sessionId", value); cookie.setSecure(true); response. addCookie(cookie). The Secure flag is essential for any cookie containing security- critical information when your application is served over HTTPS. Be aware that setting this flag will prevent the cookie from being sent over HTTP connections, so ensure your application enforces HTTPS for all authenticated pages. For Spring Boot applications, recommended to configure session cookies globally via server.servlet.session.cookie. secure=true in application properties, and consider enabling server.ssl.enabled=true with HSTS headers to enforce HTTPS throughout the application.

OWASP:

  • A6:2017-Security Misconfiguration
  • A05:2021-Security Misconfiguration

Summary:

Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting')

Severity: Medium

CWE: CWE-113

Description:

The application passes user-controlled input from HttpServletRequest methods (such as getParameter(), getHeader(), or getPathInfo()) directly to the javax.servlet.http. Cookie constructor or setValue() method without proper sanitization of CR (\r) and LF (\n) characters. When these CRLF characters reach the HTTP response headers, the server may interpret them as header terminators, causing the output stream to be parsed as two separate HTTP responses instead of one. Attackers can exploit this by injecting additional HTTP headers and response bodies to mount Cross-Site Scripting (XSS), cache poisoning, or session fixation attacks where they control the content of the injected second response.

Remediation:

Consider sanitizing all user input before using it in cookie values by removing or replacing CR (\r) and LF (\n) characters. Use String.replace() with a regex pattern like [\\r\\n]+ to strip these characters: val sanitized = userInput.replace(Regex( "[\\r\\n]+"), ""). Alternatively, can use org.apache.commons.text.StringEscapeUtils. escapeJava() which properly escapes control characters including CRLF sequences. Recommended to implement input validation that rejects requests containing unexpected control characters rather than attempting to sanitize them, as this provides defense in depth. Modern servlet containers (Servlet 3.0+) provide some protection against response splitting, but application-level validation remains essential as container protections may not cover all attack vectors. Consider using a web application firewall (WAF) as an additional layer of protection to detect and block HTTP response splitting attempts.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_crypto_rule-BlowfishKeySize

Summary:

Inadequate encryption strength

Severity: Medium

CWE: CWE-326

Description:

The application uses javax.crypto.KeyGenerator.getInstance("Blowfish") with a key size less than 128 bits, making the ciphertext vulnerable to brute force attacks. Blowfish supports key sizes from 32 to 448 bits, but keys smaller than 128 bits provide inadequate security for modern applications. Additionally, Blowfish itself has a 64-bit block size which makes it vulnerable to birthday attacks after processing approximately 32GB of data with the same key, making it unsuitable for high-throughput encryption scenarios.

Remediation:

Consider migrating to AES-256-GCM for authenticated encryption, which is the recommended standard for modern applications. Use javax.crypto.KeyGenerator.getInstance("AES") with keyGen.init(256) to generate 256-bit keys. For scenarios requiring authenticated encryption, use the GCM mode with Cipher.getInstance("AES/GCM/NoPadding") which provides both confidentiality and integrity protection without requiring manual MAC implementation. If Blowfish must be used for legacy compatibility, ensure key sizes are at minimum 128 bits by calling keyGen.init(128) or higher. For new Kotlin applications, consider using the Tink cryptography library which provides safe defaults and prevents common misconfiguration issues.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_crypto_rule-CipherDESInsecure

Summary:

Inadequate encryption strength

Severity: Medium

CWE: CWE-326

Description:

The application uses javax.crypto.Cipher.getInstance() with DES encryption, which is cryptographically broken and should not be used for modern applications. DES has a 56-bit effective key length that makes it vulnerable to brute force attacks, with practical demonstrations of breaking DES in less than 24 hours using specialized hardware. The small 64-bit block size also makes DES susceptible to birthday attacks. NIST officially deprecated DES in 2005 and recommends AES as the replacement standard for symmetric encryption.

Remediation:

Replace DES with AES-256-GCM for authenticated encryption using javax.crypto.Cipher.getInstance("AES/GCM/NoPadding"). Generate AES keys with javax.crypto.KeyGenerator.getInstance("AES") and initialize with 256-bit key size using keyGen.init(256). The GCM mode provides both encryption and authentication, protecting against tampering without requiring separate MAC implementation. Ensure proper IV/nonce handling by generating random 12-byte nonces with java.security.SecureRandom for each encryption operation and never reusing nonces with the same key. For Kotlin projects, consider using Google's Tink library which provides safe cryptographic APIs with secure defaults and prevents common implementation mistakes.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_crypto_rule-CipherDESedeInsecure

Summary:

Use of a broken or risky cryptographic algorithm

Severity: Medium

CWE: CWE-327

Description:

The application uses javax.crypto.Cipher.getInstance() with Triple DES (DESede/3DES) encryption, which is deprecated and no longer recommended for modern applications. While Triple DES was designed to address DES vulnerabilities by applying the cipher three times, it still suffers from the 64-bit block size limitation making it vulnerable to birthday attacks after encrypting approximately 32GB of data with the same key. NIST officially deprecated Triple DES for new applications in 2017 and disallowed its use after 2023, recommending AES as the replacement standard.

Remediation:

Migrate to AES-256-GCM for modern authenticated encryption by using javax.crypto.Cipher.getInstance("AES/GCM/NoPadding"). Generate 256-bit AES keys with javax.crypto.KeyGenerator.getInstance("AES") and keyGen.init(256). GCM mode provides both confidentiality and authenticity without requiring manual MAC implementation, and has better performance than Triple DES on modern hardware. Generate unique 12-byte nonces for each encryption operation using java.security.SecureRandom and never reuse nonces with the same key as this catastrophically breaks GCM security. For Kotlin applications, consider using the Tink cryptography library which provides high-level APIs with secure defaults and built-in protection against common cryptographic pitfalls.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_crypto_rule-CustomMessageDigest

Summary:

Use of a broken or risky cryptographic algorithm

Severity: Medium

CWE: CWE-327

Description:

The application implements a custom class extending java.security.MessageDigest, which is extremely error-prone and likely to introduce cryptographic vulnerabilities. Designing secure hash functions requires deep expertise in cryptanalysis, and even minor implementation errors can completely break security properties like collision resistance and pre-image resistance. Custom hash implementations are susceptible to length extension attacks, weak avalanche effects, and cryptanalytic weaknesses that may not be immediately apparent. NIST recommends using proven, well-analyzed hash functions from the SHA-2 or SHA-3 families.

Remediation:

Use industry-standard hash functions from Java's security providers instead of implementing custom digests. For general-purpose hashing, use java.security.MessageDigest.getInstance("SHA-256") which provides excellent security and performance. For applications requiring higher security margins, use SHA-512 with MessageDigest.getInstance("SHA-512"). If password hashing is the goal, use dedicated password hashing algorithms like Argon2, bcrypt, or scrypt via the Bouncy Castle library, as general-purpose hash functions are unsuitable for password storage. For HMAC operations, use javax.crypto.Mac.getInstance("HmacSHA256") rather than manually implementing HMAC with custom digests. Kotlin applications can also use Google's Tink library which provides safe hashing APIs with secure defaults.

OWASP:

  • A6:2017-Security Misconfiguration
  • A04:2021-Insecure Design

kotlin_crypto_rule-HazelcastSymmetricEncryption

Summary:

Inadequate encryption strength

Severity: Medium

CWE: CWE-326

Description:

The application configures Hazelcast network communications using com.hazelcast.config.SymmetricEncryptionConfig(), which typically defaults to weak symmetric ciphers like DES or Blowfish that provide neither integrity protection nor secure authentication. Symmetric encryption alone cannot prevent man-in-the-middle attacks or verify the identity of cluster members, allowing attackers to potentially join the cluster or intercept sensitive data. Additionally, the default symmetric ciphers in older Hazelcast versions are cryptographically weak and vulnerable to practical attacks.

Remediation:

Use Hazelcast's TLS/SSL encryption instead of symmetric encryption by configuring SSLConfig with proper certificate-based authentication. This provides both encryption and mutual authentication between cluster members, preventing unauthorized nodes from joining. Configure TLS with config.networkConfig.sslConfig and use strong cipher suites by setting sslConfig.setProperty("javax.net.ssl.cipherSuites", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"). Ensure certificates are properly validated and use modern TLS 1.2 or 1.3 protocols. For additional security, enable Hazelcast's member authentication using shared secrets or integrate with enterprise authentication systems. Avoid using symmetric encryption entirely unless required for specific legacy compatibility scenarios, and if necessary, ensure strong algorithms like AES-256 are configured explicitly.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_crypto_rule-InsufficientKeySizeRsa

Summary:

Inadequate encryption strength

Severity: Medium

CWE: CWE-326

Description:

The application uses KeyPairGenerator.getInstance() with RSA or DSA algorithms and initializes keys with sizes less than 2048 bits, providing inadequate security for modern applications. RSA and DSA keys smaller than 2048 bits are vulnerable to factorization attacks using increasingly powerful computing resources. NIST deprecated 1024-bit RSA/DSA keys in 2013 and now recommends minimum 2048-bit keys for security through 2030, with 3072-bit keys recommended for longer-term protection. Smaller key sizes can be broken by well-funded adversaries or may become vulnerable as computing power increases.

Remediation:

Use minimum 2048-bit keys for RSA and DSA by calling keyGen.initialize(2048) when initializing the KeyPairGenerator. For applications requiring security beyond 2030, consider 3072-bit or 4096-bit keys with keyGen.initialize(3072). For new applications, strongly consider migrating to elliptic curve cryptography (ECC) using the ECDSA algorithm with P-256 or P-384 curves, which provides equivalent security to RSA-2048/3072 with significantly smaller key sizes and better performance. Use KeyPairGenerator.getInstance("EC") and specify curves via ECGenParameterSpec("secp256r1") for P-256 or ECGenParameterSpec("secp384r1") for P-384. For Kotlin applications, consider using the Tink library which provides safe key generation with secure defaults.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_crypto_rule-NullCipher

Summary:

Use of a broken or risky cryptographic algorithm

Severity: Medium

CWE: CWE-327

Description:

The application uses javax.crypto.NullCipher(), which implements the Cipher interface by returning ciphertext identical to the supplied plaintext, providing absolutely no encryption or security. NullCipher is intended solely for testing scenarios where encryption needs to be temporarily disabled, but its accidental use in production code introduces catastrophic confidentiality risks. Data encrypted with NullCipher is transmitted and stored in plaintext, exposing sensitive information to anyone with network or storage access. This is particularly dangerous when encryption logic is conditionally enabled, as a configuration error could silently disable all encryption.

Remediation:

Replace NullCipher with proper authenticated encryption using AES-256-GCM via javax.crypto.Cipher.getInstance("AES/GCM/NoPadding"). Generate proper AES keys with javax.crypto.KeyGenerator.getInstance("AES") and keyGen.init(256). For testing scenarios that require encryption to be disabled, use dependency injection or feature flags to control cipher selection, and ensure test-only configurations cannot be accidentally deployed to production. Consider using separate interfaces for test and production cipher implementations, with compile-time checks to prevent NullCipher from being included in production builds. For Kotlin projects, use Google's Tink library which provides safe encryption primitives and makes it impossible to accidentally use NullCipher through its high-level APIs.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_crypto_rule-RsaNoPadding

Summary:

Use of RSA algorithm without OAEP

Severity: Medium

CWE: CWE-780

Description:

The application uses javax.crypto.Cipher.getInstance() with RSA encryption without proper padding (NoPadding), which is cryptographically insecure and vulnerable to multiple attacks. RSA without padding is deterministic, meaning identical plaintexts produce identical ciphertexts, allowing attackers to identify patterns and repeated data. It is also vulnerable to chosen-ciphertext attacks where attackers can manipulate ciphertext to create related plaintexts, and fails to provide semantic security. Proper padding schemes like OAEP (Optimal Asymmetric Encryption Padding) add randomness and structure to prevent these attacks and ensure that RSA encryption is non-deterministic and secure.

Remediation:

Use RSA with OAEP padding by specifying javax.crypto.Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding") for encryption operations. OAEP adds randomness and structural protections that make RSA encryption semantically secure and resistant to attacks. For digital signatures, use PSS padding with Signature.getInstance("SHA256withRSA/PSS") which provides stronger security guarantees than PKCS1 padding. Note that RSA is computationally expensive and should typically only be used for encrypting symmetric keys or small amounts of data, not for bulk encryption. For encrypting large amounts of data, use hybrid encryption where RSA encrypts an AES key, and AES-GCM encrypts the actual data. For modern Kotlin applications, consider using Google's Tink library which enforces proper padding schemes and prevents common RSA misconfigurations.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_crypto_rule-WeakMessageDigest

Summary:

Use of a broken or risky cryptographic algorithm (SHA1/MD5)

Severity: Medium

CWE: CWE-327

Description:

The application uses MessageDigest.getInstance() or Signature.getInstance() with cryptographically broken hash algorithms including MD2, MD4, MD5, or SHA-1. These algorithms are vulnerable to collision attacks where attackers can create two different inputs that produce the same hash output. MD5 collisions have been practical since 2004, and SHA-1 collisions were demonstrated in 2017 with the SHAttered attack. Using these algorithms for digital signatures allows attackers to forge signatures, and using them for integrity verification allows undetected tampering. NIST deprecated SHA-1 for digital signatures in 2011 and for all cryptographic purposes after 2030.

Remediation:

Migrate to secure hash functions from the SHA-2 or SHA-3 families. For general-purpose hashing and integrity verification, use SHA-256 with MessageDigest.getInstance("SHA-256"). For digital signatures, use SHA-256 or stronger with Signature.getInstance("SHA256withRSA") or Signature.getInstance("SHA256withECDSA"). For applications requiring higher security margins or longer-term protection, use SHA-512 with MessageDigest.getInstance("SHA-512"). For HMAC operations, use javax.crypto.Mac.getInstance("HmacSHA256"). If password hashing is the use case, do not use general-purpose hash functions; instead use dedicated password hashing algorithms like Argon2, bcrypt, or scrypt via the Bouncy Castle library. For Kotlin applications, consider using Google's Tink library which provides safe hashing APIs with secure defaults and prevents use of weak algorithms.

OWASP:

  • A6:2017-Security Misconfiguration
  • A04:2021-Insecure Design

kotlin_crypto_rule-WeakTLSProtocol

Summary:

Improper certificate validation

Severity: Medium

CWE: CWE-295

Description:

The application uses deprecated and insecure TLS/SSL configurations including org.apache.http.impl.client.DefaultHttpClient() or javax.net.ssl.SSLContext.getInstance("SSL"). DefaultHttpClient from Apache HttpClient 4.x is deprecated and uses insecure defaults including accepting outdated TLS/SSL protocol versions vulnerable to known attacks. The generic "SSL" context may enable SSL 3.0, TLS 1.0, and TLS 1.1, all of which have known vulnerabilities including POODLE, BEAST, and others that allow attackers to decrypt traffic or perform man-in-the-middle attacks. Modern applications should use TLS 1.2 or TLS 1.3 exclusively.

Remediation:

For HTTP clients, migrate from deprecated Apache HttpClient to modern alternatives like OkHttp or use Java 11's built-in HttpClient which has secure defaults. If Apache HttpClient must be used, upgrade to HttpClient 5.x and explicitly configure TLS 1.2+ with proper certificate validation. For SSLContext, use SSLContext.getInstance("TLSv1.2") or SSLContext.getInstance("TLSv1.3") instead of the generic "SSL" or "TLS" options to ensure only secure protocol versions are enabled. Configure enabled protocols explicitly with sslEngine.setEnabledProtocols(arrayOf("TLSv1.2", "TLSv1.3")) and specify strong cipher suites that support forward secrecy. For Kotlin projects using OkHttp, configure the client with ConnectionSpec.MODERN_TLS to enforce TLS 1.2+ automatically, or use ConnectionSpec.RESTRICTED_TLS for the most secure configuration.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_crypto_rule-WeakTLSProtocolVersion

Summary:

Inadequate encryption strength

Severity: Medium

CWE: CWE-326

Description:

The application uses javax.net.ssl.SSLContext.getInstance() or SSLEngine.setEnabledProtocols() to enable insecure TLS protocol versions including SSL, TLS 1.0, TLS 1.1, or DTLS 1.0/1.1. These protocols have known vulnerabilities such as POODLE (SSL 3.0), BEAST (TLS 1.0), and weak cipher suites that allow attackers to decrypt traffic, perform downgrade attacks, or conduct man-in-the-middle attacks. PCI DSS and other compliance frameworks require disabling TLS versions prior to 1.2. Relying on system defaults is insufficient as applications may be deployed on older systems with insecure default configurations, and explicit configuration is required for compliance and security guarantees.

Remediation:

Explicitly configure TLS 1.2 or TLS 1.3 as minimum protocol versions by using SSLContext.getInstance("TLSv1.2") or SSLContext.getInstance("TLSv1.3"). If using the generic "TLS" context, explicitly restrict enabled protocols with sslEngine.setEnabledProtocols(arrayOf("TLSv1.2", "TLSv1.3")) to override potentially insecure defaults. For DTLS (Datagram TLS), use SSLContext.getInstance("DTLSv1.2") or DTLSv1.3. Configure strong cipher suites that support forward secrecy by setting sslEngine.setEnabledCipherSuites() with suites like TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384. For Kotlin applications using OkHttp, configure with ConnectionSpec.MODERN_TLS or ConnectionSpec.RESTRICTED_TLS to automatically enforce secure protocol versions. Avoid relying on system defaults; explicitly specify security configurations in all deployment environments to ensure compliance and consistent security posture.

OWASP:

  • A3:2017-Sensitive Data Exposure
  • A02:2021-Cryptographic Failures

kotlin_csrf_rule-SpringCSRFDisabled

Summary:

Cross-Site Request Forgery (CSRF)

Severity: Medium

CWE: CWE-352

Description:

CSRF protection has been explicitly disabled using HttpSecurity.csrf().disable() or CsrfConfigurer.disable(). This removes safeguards against Cross-Site Request Forgery attacks, allowing malicious websites to trick authenticated users into performing unintended actions. Without CSRF protection, attackers can forge requests that appear legitimate, potentially leading to unauthorized state changes, data modification, or privilege escalation.

Remediation:

Consider keeping CSRF protection enabled for all state-changing operations. Recommended to remove the .csrf().disable() call and rely on Spring Security's default CSRF token validation. CSRF protection should only be disabled for truly stateless REST APIs that use token-based authentication (e.g., JWT) and do not rely on cookies for authentication. For browser-based applications using session cookies, CSRF protection is essential.

OWASP:

  • A5:2017-Broken Access Control
  • A01:2021-Broken Access Control

kotlin_endpoint_rule-WeakHostNameVerification

Summary:

Improper Certificate Validation

Severity: Medium

CWE: CWE-295

Description:

Weak or disabled hostname verification detected in SSL/TLS implementation. This rule identifies custom HostnameVerifier.verify() implementations that always return true, or empty X509TrustManager methods (checkClientTrusted(), checkServerTrusted(), getAcceptedIssuers()). These implementations disable certificate validation, making the application vulnerable to man-in-the-middle attacks where attackers can intercept and decrypt HTTPS traffic.

Remediation:

Consider implementing proper certificate validation instead of disabling hostname verification. Recommended to use the default HostnameVerifier and X509TrustManager implementations provided by the JDK, which perform standard certificate chain validation. If custom verification is required, ensure HostnameVerifier.verify() performs actual hostname matching against certificate subject/SAN fields. Never return true unconditionally or leave trust manager methods empty, as this accepts any certificate including self-signed and expired ones.


kotlin_file_rule-FilenameUtils

Summary:

Improper limitation of a pathname to a restricted directory ('Path Traversal')

Severity: Medium

CWE: CWE-22

Description:

Path traversal vulnerability detected using Apache Commons FilenameUtils methods such as 'normalize()', 'getName()', 'getExtension()', 'getBaseName()', or 'isExtensions()'. User-controlled input is processed by these methods which can be manipulated with path traversal sequences like '../' to access files outside the intended directory. This may allow unauthorized file access.

Remediation:

Consider validating all file paths against a strict allowlist of permitted files or directories before using 'FilenameUtils' methods. Recommended to check for directory traversal sequences like '..' and reject any paths containing them. Use canonical path resolution and verify the resolved path remains within the intended base directory. Never trust user input for file paths without thorough validation and sanitization.

OWASP:

  • A5:2017-Broken Access Control
  • A01:2021-Broken Access Control

kotlin_inject_rule-CommandInjection

Summary:

Improper neutralization of special elements used in an OS command ('OS Command Injection')

Severity: Medium

CWE: CWE-78

Description:

The application uses Runtime.getRuntime().exec() or ProcessBuilder.command() with user-controlled input concatenated using Kotlin string templates or string concatenation, which enables arbitrary command injection. When user input is directly incorporated into shell commands through string interpolation (e.g., Runtime.getRuntime().exec("sh -c $userInput") or ProcessBuilder.command("bash", "-c", userInput)), attackers can inject shell metacharacters to execute malicious commands. This is particularly dangerous when using shell invocation (sh, bash, etc.) as it allows command chaining with operators like ;, &&, ||, and command substitution with backticks or $().

Remediation:

Consider using ProcessBuilder with argument arrays instead of shell invocation to execute commands safely. When using ProcessBuilder, pass each argument as a separate element in the command list rather than concatenating them into a single string (e.g., ProcessBuilder("program", arg1, arg2) instead of ProcessBuilder("sh", "-c", "program $arg1 $arg2")). This approach prevents shell interpretation of special characters. For dynamic command arguments, validate and sanitize all user input against a strict allowlist of expected values. The Apache Commons Exec library provides additional utilities for safe command execution with argument quoting. Avoid invoking shell interpreters (sh, bash, etc.) entirely unless absolutely necessary, and if required, use proper escaping mechanisms specific to the target shell. For Kotlin applications, consider using higher-level libraries or creating wrapper functions that enforce safe command construction patterns.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_inject_rule-ELInjection

Summary:

Improper neutralization of special elements used in an expression language statement ('Expression Language Injection')

Severity: Medium

CWE: CWE-917

Description:

The application uses Java Expression Language (EL) APIs such as ExpressionFactory.createMethodExpression(), ExpressionFactory.createValueExpression(), or ELProcessor.eval() with user-controlled input, which allows arbitrary code execution through EL injection. EL expressions can access Java objects and invoke methods on them, making dynamic EL evaluation extremely dangerous when user input is incorporated. Attackers can craft malicious EL expressions to execute arbitrary Java code, access sensitive data, or manipulate application state. This vulnerability commonly occurs in Java web applications using JSP, JSF, or Spring frameworks where EL is used to dynamically evaluate expressions from user input.

Remediation:

Avoid using dynamic EL expression evaluation with user-controlled input entirely if possible. Instead, use static EL expressions defined in JSP/JSF templates or configuration files. If dynamic evaluation is absolutely necessary, implement strict input validation using an allowlist of permitted expression patterns and reject any input containing EL special characters like $, {, }, or .. Consider using safer alternatives such as simple property lookups or implementing a custom domain-specific language with limited functionality. For Spring applications, avoid using SpELExpressionParser with untrusted input. If EL must be used, consider using javax.el.ELResolver with a custom implementation that restricts access to specific beans and methods. The OWASP ESAPI library provides utilities for sanitizing EL expressions, though complete prevention through architectural changes is strongly recommended.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_inject_rule-LDAPInjection

Summary:

Improper neutralization of special elements used in an LDAP query ('LDAP Injection')

Severity: Medium

CWE: CWE-90

Description:

The application uses user-controlled input in LDAP operations through javax.naming.directory.DirContext.search(), LdapContext.search(), LdapConnection.search(), or Spring LDAP's LdapTemplate methods without proper sanitization, which enables LDAP injection attacks. Unlike SQL, LDAP lacks prepared statement interfaces, making it vulnerable when user input containing LDAP special characters like *, (, ), \, |, &, or ! is directly incorporated into search filters or distinguished names. Attackers can manipulate LDAP queries to bypass authentication, access unauthorized data, or enumerate directory contents. For example, injecting *)(uid=*))(|(uid=* into a filter can change the query logic to return all entries. This vulnerability is common in applications using LDAP for authentication or directory lookups where user input constructs search filters or DN paths.

Remediation:

Implement strict input validation and escaping for all user input used in LDAP queries. For LDAP search filters, escape special characters using LDAP encoding functions that convert characters like *, (, ), \, and NUL to their escaped equivalents (e.g., \2a for *). The UnboundID LDAP SDK provides Filter.encodeValue() for safe filter construction, while Spring LDAP offers LdapEncoder.filterEncode() for escaping filter values and LdapEncoder.nameEncode() for DN components. For Kotlin applications, create wrapper functions that automatically apply escaping to all LDAP parameters. When constructing LDAP filters, use parameterized filter builders rather than string concatenation. Implement an allowlist validation for DN components and attribute names, restricting them to expected alphanumeric patterns. Consider using Spring LDAP's LdapTemplate with its built-in sanitization features, or the UnboundID SDK's Filter class which provides safer programmatic filter construction. For authentication use cases, validate usernames against strict patterns before incorporating them into LDAP queries.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_inject_rule-OgnlInjection

Summary:

Expression injection (OGNL)

Severity: Medium

CWE: CWE-917

Description:

The application uses user-controlled input with Apache Struts 2 OGNL (Object-Graph Navigation Language) APIs such as OgnlUtil.getValue(), OgnlUtil.setValue(), TextParseUtil.translateVariables(), or ValueStack.findValue() without proper sanitization, which enables arbitrary code execution through OGNL expression injection. OGNL is an extremely powerful expression language in Struts 2 that can access Java objects, invoke methods, and execute arbitrary code. When user input is incorporated into OGNL expressions, attackers can craft malicious expressions to instantiate objects, call static methods, access runtime context, or execute system commands. This vulnerability has been exploited in numerous critical Struts 2 CVEs and can lead to complete server compromise. The risk is particularly severe because OGNL evaluation operates with full Java reflection capabilities and application privileges.

Remediation:

Avoid using dynamic OGNL expression evaluation with user-controlled input entirely. Instead, use Struts 2's parameterized actions where user input is bound to action properties through type-safe setters rather than evaluated as expressions. If OGNL must be used, never pass user input directly to OgnlUtil methods, ValueStack operations, or TextParseUtil functions. For Struts 2 applications, upgrade to the latest version which includes improved OGNL sandboxing and security manager configurations. Configure struts.ognl.expressionMaxLength to limit expression complexity and enable struts.ognl.enableEvalExpression=false to disable dangerous evaluation features. Consider migrating away from Struts 2 to modern frameworks like Spring Boot with Spring MVC which avoid dynamic expression evaluation. If migration isn't feasible, implement strict input validation using allowlists and consider using Struts 2's ParametersInterceptor with properly configured excludeParams and acceptParamNames to prevent malicious parameter injection. The OWASP ModSecurity Core Rule Set provides WAF rules to detect common OGNL injection patterns as a defense-in-depth measure.


kotlin_inject_rule-SpotbugsPathTraversalAbsolute

Summary:

Improper limitation of a pathname to a restricted directory ('Path Traversal')

Severity: Medium

CWE: CWE-22

Description:

The application uses user-controlled input from HttpServletRequest.getParameter() or Spring's @RequestParam to construct file paths in operations like java.io.File(), java.nio.file.Paths.get(), FileInputStream(), FileReader(), or ClassLoader.getResourceAsStream() without proper validation, which enables path traversal attacks. When user input contains absolute paths (e.g., /etc/passwd), parent directory references (../), or symbolic links, attackers can access files outside the intended directory, including system files, application source code, configuration files containing credentials, or other users' data. This vulnerability is particularly dangerous because Java's file APIs will honor absolute paths and directory traversal sequences, allowing attackers to bypass intended access controls. The risk extends to file upload scenarios, resource loading, and any file operation where user input influences the file path.

Remediation:

Use FilenameUtils.getName() from Apache Commons IO to extract only the filename component, stripping any directory path information before constructing file paths. For Kotlin applications, implement strict validation that rejects any user input containing path traversal sequences (.., /, \), absolute path indicators, or null bytes. Consider using an allowlist approach where user input selects from a predefined set of valid filenames rather than directly constructing paths. When file paths must be constructed, use Path.normalize().startsWith(baseDirectory) to verify that resolved paths remain within the intended directory. For temporary files, use Files.createTempFile() with a safe prefix and ignore user-provided filenames entirely. Avoid using ClassLoader.getResourceAsStream() with user input; instead, use a mapping of safe identifiers to resource paths. For Spring Boot applications, configure spring.resources.static-locations appropriately and use ResourceLoader with proper validation. Consider implementing a virtual filesystem or using UUIDs as filenames while storing the user-provided names separately in a database. Never trust user input for file operations without comprehensive validation and sandboxing.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_ldap_rule-AnonymousLDAP

Summary:

Missing authentication for critical function (LDAP)

Severity: Medium

CWE: CWE-306

Description:

Setting Context.SECURITY_AUTHENTICATION to "none" disables authentication for LDAP connections, allowing anonymous binds to the directory server. This exposes the LDAP server to unauthorized access and enables attackers to query, modify, or extract sensitive directory information without credentials. Anonymous LDAP authentication should never be used in production environments.

Remediation:

Never set Context.SECURITY_AUTHENTICATION to "none" for LDAP connections. Recommended to use "simple" authentication with proper credentials (username and password) or stronger mechanisms like SASL for LDAP binds. Consider implementing certificate-based authentication or Kerberos for enhanced security. Always validate that LDAP connections are authenticated and use encrypted transports (LDAPS) to protect credentials in transit.

OWASP:

  • A2:2017-Broken Authentication
  • A07:2021-Identification and Authentication Failures

kotlin_perm_rule-DangerousPermissions

Summary:

Insecure inherited permissions

Severity: Medium

CWE: CWE-277

Description:

Granting dangerous permissions such as ReflectPermission("suppressAccessChecks") or RuntimePermission("createClassLoader") to a PermissionCollection can compromise application security by allowing unauthorized code execution or access control bypass. These permissions enable reflection-based access checks to be suppressed or custom class loaders to be created, which are common attack vectors.

Remediation:

Avoid granting ReflectPermission("suppressAccessChecks") or RuntimePermission("createClassLoader") as these permissions can enable security bypass attacks. Consider applying the principle of least privilege by granting only the minimal permissions required for the application's specific functionality. If reflection or class loading capabilities are necessary, implement them through controlled, audited interfaces rather than blanket permissions.

OWASP:

  • A5:2017-Broken Access Control
  • A01:2021-Broken Access Control

kotlin_perm_rule-OverlyPermissiveFilePermissionInline

Summary:

Incorrect permission assignment for critical resource

Severity: Medium

CWE: CWE-732

Description:

Setting overly permissive file permissions using PosixFilePermissions.fromString() with world-readable or world-writable access can expose sensitive data to unauthorized users on the system. Permissions that grant read, write, or execute access to the "others" group allow any user on the system to access the file, creating potential security vulnerabilities.

Remediation:

Use restrictive file permissions when calling PosixFilePermissions.fromString(). Consider using "rw-------" (owner-only read/write) or "rw-r-----" (owner read/write, group read) instead of permissions that grant world-readable or world-writable access. Recommended to follow the principle of least privilege and only grant file access to the specific users or groups that require it.

OWASP:

  • A5:2017-Broken Access Control
  • A01:2021-Broken Access Control

kotlin_strings_rule-BadHexConversion

Summary:

Incorrect type conversion or cast

Severity: Medium

CWE: CWE-704

Description:

Using Integer.toHexString() to convert bytes from MessageDigest.digest() to hexadecimal strings in a loop can produce incorrect output due to sign extension and missing leading zeros. When a signed byte is converted to an int, values 0x80-0xFF become negative and may produce incorrect hex representations. Additionally, Integer.toHexString() omits leading zeros for values less than 0x10, resulting in single-character hex strings instead of the required two characters per byte.

Remediation:

Consider using joinToString() with a lambda that properly formats each byte, such as digest.joinToString("") { "%02x".format(it) }, which ensures each byte is represented as exactly two hexadecimal characters with leading zeros when needed. Alternatively, use Apache Commons Codec's Hex.encodeHexString() which handles the conversion correctly, or convert to unsigned integers before calling Integer.toHexString() with "%02x".format(byte.toInt() and 0xFF). The key is to mask the byte with 0xFF to prevent sign extension and use format strings that pad with leading zeros to ensure consistent two-character output per byte.

OWASP:

  • A6:2017-Security Misconfiguration
  • A05:2021-Security Misconfiguration

kotlin_strings_rule-ModifyAfterValidation

Summary:

Collapse of data into unsafe value

Severity: Medium

CWE: CWE-182

Description:

Modifying a string using methods like replace(), replaceAll(), replaceFirst(), or concat() after validating it with Pattern.matcher() creates a time-of-check to time-of-use (TOCTOU) vulnerability. The validation is performed on the original string, but the modified version is used afterwards, potentially bypassing security checks. This violates the CERT secure coding guideline IDS11-J which requires performing all string modifications before validation to ensure the validated content matches what will actually be used by the application.

Remediation:

Consider restructuring the code to perform all string modifications (replace, replaceAll, replaceFirst, concat operations) before applying validation with Pattern.matcher(). This ensures that the exact string being validated is the same string that will be used in subsequent operations. For example, if you need to sanitize user input by removing certain characters and then validate the result, perform the removal first and validate the cleaned string. Recommended to create a single processing pipeline where: (1) raw input is received, (2) all necessary transformations are applied, (3) the final transformed string is validated, and (4) only the validated string is used. This prevents attackers from bypassing validation by exploiting the differences between the checked and used values.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_strings_rule-NormalizeAfterValidation

Summary:

Incorrect behavior order: validate before canonicalize

Severity: Medium

CWE: CWE-180

Description:

Calling Normalizer.normalize() after validating a string with Pattern.matcher() creates a time-of-check to time-of-use vulnerability. Unicode normalization can change the representation of characters (for example, converting composed characters to decomposed form or vice versa), potentially introducing characters that were filtered out during validation. This violates the CERT secure coding guideline IDS01-J which requires normalizing strings before validation to ensure that the validation operates on the final form of the data that will be used by the application.

Remediation:

Consider calling Normalizer.normalize() before applying any validation with Pattern.matcher() to ensure the validation examines the final normalized form of the string. For example, normalize the input string first using a normalization form like NFC (Canonical Decomposition followed by Canonical Composition) or NFD (Canonical Decomposition), then apply pattern matching to the normalized result. Recommended to establish a consistent processing order: (1) receive raw input, (2) normalize using Normalizer.normalize() with an appropriate form, (3) validate the normalized string, and (4) use only the validated normalized string. This prevents attackers from bypassing validation by using alternate Unicode representations that normalize to dangerous characters after validation completes.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_unsafe_rule-ExternalConfigControl

Summary:

External control of system or configuration setting

Severity: Medium

CWE: CWE-15

Description:

External control of database configuration detected when user input from HttpServletRequest.getParameter() is passed to Connection.setCatalog(). This allows attackers to access unauthorized database catalogs or cause errors by providing nonexistent catalog names, potentially leading to data exposure or service disruption.

Remediation:

Consider using hardcoded catalog names rather than accepting them from user input. Recommended to validate any external catalog values against a strict allowlist of permitted catalog names before passing to setCatalog(). If dynamic catalog selection is required, map user-provided identifiers to predefined catalog names using a lookup table rather than passing input directly to the database connection.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_xml_rule-SAMLIgnoreComments

Summary:

Weak authentication

Severity: Medium

CWE: CWE-1390

Description:

Setting BasicParserPool.setIgnoreComments(false) in SAML authentication allows XML comments to be processed during parsing. This is dangerous because attackers can inject XML comments into SAML assertions to manipulate authentication logic, potentially bypassing signature verification and gaining unauthorized access. The OpenSAML BasicParserPool.setIgnoreComments() API should be set to true to prevent comment-based authentication bypass vulnerabilities.

Remediation:

Consider configuring the BasicParserPool to ignore XML comments by calling setIgnoreComments(true) instead of false. This prevents attackers from manipulating SAML assertions through carefully crafted XML comments that could bypass signature validation. When XML comments are not ignored, they can be used to break up element content or inject additional data that alters the semantic meaning of SAML assertions after signature verification. It is recommended to always set ignoreComments to true in production SAML configurations to maintain the integrity of authentication flows. Additionally, consider validating SAML assertions against a strict schema and implementing defense-in-depth measures such as verifying issuer identity, checking assertion timestamps, and enforcing audience restrictions.

OWASP:

  • A5:2017-Broken Access Control
  • A01:2021-Broken Access Control

kotlin_xml_rule-XmlDecoder

Summary:

Deserialization of untrusted data

Severity: Medium

CWE: CWE-502

Description:

Calling XMLDecoder.readObject() deserializes XML content into Java objects, which is dangerous when processing untrusted data. This Java Beans API allows arbitrary code execution because attackers can craft malicious XML that instantiates objects, invokes methods, and executes system commands during deserialization. The java.beans.XMLDecoder class should never be used with untrusted input as it provides no safe way to restrict deserialization.

Remediation:

Consider replacing XMLDecoder with a safer alternative such as Jackson, Gson, or other JSON/XML parsing libraries that do not execute arbitrary code during deserialization. If you must parse XML-encoded objects, use a standard XML parser with strict schema validation and manually construct objects from the parsed data rather than relying on automatic deserialization. For data serialization needs, prefer JSON-based formats with libraries that default to safe deserialization practices. If XMLDecoder usage is absolutely required for compatibility reasons, implement a custom restrictive ClassLoader that only allows deserialization of explicitly whitelisted classes, and validate all input against a strict schema before processing. However, be aware that even with restrictions, XMLDecoder carries significant security risks and complete replacement is the recommended approach.

OWASP:

  • A8:2017-Insecure Deserialization
  • A08:2021-Software and Data Integrity Failures

kotlin_xml_rule-XsltTransform

Summary:

XML injection (aka Blind XPath injection)

Severity: Medium

CWE: CWE-91

Description:

XSLT transformations using TransformerFactory.newTransformer() or Transformer.transform() with user-controlled stylesheets are dangerous because XSLT processors can execute arbitrary code through extension functions and external document access. Attackers can craft malicious XSL stylesheets that invoke Java methods, read files, or execute system commands when processed by the javax.xml.transform API, leading to remote code execution vulnerabilities.

Remediation:

Consider restricting XSLT transformations to only use trusted, application- controlled stylesheets stored in secure locations rather than accepting user- provided XSL content. If user input must influence transformations, use a parameterized approach where only specific values are passed to a trusted stylesheet via Transformer.setParameter() instead of allowing full stylesheet control. When creating TransformerFactory instances, disable external entity processing and extension functions by setting the ACCESS_EXTERNAL_DTD and ACCESS_EXTERNAL_STYLESHEET properties to empty strings, and configure the XMLConstants.FEATURE_SECURE_PROCESSING feature to true. Additionally, consider running XSLT transformations in a sandboxed environment with restricted permissions, validate all stylesheet sources against a strict whitelist, and implement comprehensive input validation to prevent injection attacks through transformation parameters.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_xss_rule-WicketXSS

Summary:

Improper neutralization of input during web page generation ('Cross-site Scripting')

Severity: Medium

CWE: CWE-79

Description:

The application is disabling Apache Wicket's built-in HTML escaping by calling setEscapeModelStrings(false) on Wicket components within Kotlin code. This creates a Cross-Site Scripting (XSS) vulnerability when the component displays user-supplied data, as malicious JavaScript or HTML markup will be rendered directly in the browser without sanitization. Wicket's default auto-escaping protects against XSS by encoding HTML special characters, and disabling this protection removes a critical security control. This is particularly dangerous in Label components, dynamic panels, or any component that renders user input in Kotlin-based web applications using the Wicket framework.

Remediation:

Consider keeping Wicket's default auto-escaping enabled by ensuring setEscapeModelStrings(true) is called or relying on Wicket's default behavior which automatically escapes HTML. If you need to render rich HTML content from trusted sources, consider using Wicket's Label component with explicit model validation rather than disabling escaping globally. For user-generated content that must include formatting, use a whitelist-based HTML sanitizer library like OWASP Java HTML Sanitizer or Jsoup with a restrictive allowlist before passing content to Wicket components. Additionally, implement Content Security Policy (CSP) headers to provide defense-in-depth against XSS even if escaping is bypassed. See the Wicket Component API documentation at https://nightlies.apache.org/wicket/apidocs/9.x/org/apache/wicket/Component.html for proper usage of escaping features in Kotlin applications.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

kotlin_xss_rule-XSSReqParamToServletWriter

Summary:

Improper neutralization of input during web page generation ('Cross-site Scripting')

Severity: Medium

CWE: CWE-79

Description:

The application is writing user-supplied data from HTTP request parameters directly to the HTTP response via HttpServletResponse.getWriter().write() within Kotlin servlet code. This creates a reflected Cross-Site Scripting (XSS) vulnerability where attackers can inject malicious JavaScript by crafting request parameters obtained via HttpServletRequest.getParameter() that are echoed back in the HTTP response without HTML encoding. Without proper output encoding, malicious scripts embedded in request parameters will execute in victims' browsers, potentially leading to session hijacking, credential theft, or defacement attacks in Kotlin-based web applications.

Remediation:

Consider using the OWASP Java Encoder library's Encode.forHtml() function to escape user input before writing to the servlet response in Kotlin code. If writing plain text responses, set the Content-Type to text/plain with response.contentType = "text/plain; charset=UTF-8" to prevent browsers from interpreting output as HTML. For modern Kotlin web applications, prefer using template engines like Ktor's HTML DSL, Thymeleaf, or FreeMarker which provide automatic context-aware escaping instead of manually writing to servlet output streams. For JavaScript, CSS, or URL contexts, use specialized encoding functions from OWASP Java Encoder (Encode.forJavaScript(), Encode.forCssString(), Encode.forUriComponent()). Implement Content Security Policy (CSP) headers as an additional defense layer against XSS attacks.

OWASP:

  • A1:2017-Injection
  • A03:2021-Injection

rules_lgpl_kotlin_other_rule-android-kotlin-webview-debug

Summary:

Leftover debug code

Severity: Medium

CWE: CWE-489

Description:

Remote WebView debugging is enabled via setWebContentsDebuggingEnabled(true). This allows remote debugging tools, such as Chrome DevTools, to connect to the WebView and inspect or manipulate its content. In production builds, this can expose sensitive information including user data, session tokens, authentication credentials, and application logic to unauthorized parties.

Remediation:

Consider disabling WebView debugging in production builds while keeping it available for development. Recommended to use BuildConfig.DEBUG to conditionally enable debugging only in debug builds with WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG). This ensures remote debugging capabilities are automatically disabled when building release versions of the application.

OWASP:

  • A6:2017-Security Misconfiguration
  • A05:2021-Security Misconfiguration