Sensitive information in source code - API Key - kotlin

Sensitive information in source code - API Key - kotlin

Need

Secure storage and retrieval of sensitive information, such as API keys, in source code

Context

  • Usage of Kotlin for developing secure and modern applications
  • Usage of javax.servlet-api for Kotlin Servlet development

Description

Non compliant code

        import javax.servlet.*
import javax.servlet.http.*
import java.io.IOException

class AppServlet : HttpServlet() {
    companion object {
        private const val API_KEY = "1234567890abcdef" // Hardcoded sensitive information
    }

    @Throws(ServletException::class, IOException::class)
    override fun doGet(request: HttpServletRequest, response: HttpServletResponse) {
        // Use the API key (not recommended)
    }
}
        
        

In the code below, a Kotlin HttpServlet named AppServlet contains a hardcoded API key.

The API key is defined as a constant inside the class, making it easily accessible to anyone with access to the source code. If this code is shared or pushed to a public repository, the key could be exposed, leading to potential security threats.

To mitigate this risk, sensitive information should never be stored in the source code. Instead, it should be retrieved from a secure source, such as an environment variable or a secret management system.

Steps

  • Remove sensitive information (API key) from the source code.
  • Store the API key in a secure location, such as an environment variable.
  • Update the code to retrieve the API key at runtime.
  • Ensure the secure location is accessible only to authorized users or processes.
  • Consider using encryption or a secrets manager for enhanced security.
  • Regularly review and update security measures to protect sensitive information.

Compliant code

        import javax.servlet.*
import javax.servlet.http.*
import java.io.IOException

class SecureAppServlet : HttpServlet() {
    private lateinit var apiKey: String

    @Throws(ServletException::class)
    override fun init() {
        apiKey = System.getenv("API_KEY") ?: throw ServletException("API_KEY not set in environment variables")
    }

    @Throws(ServletException::class, IOException::class)
    override fun doGet(request: HttpServletRequest, response: HttpServletResponse) {
        // Use the API key securely
    }
}
        
        

The secure version of this code retrieves the API key from an environment variable instead of hardcoding it in the source code.

- The init() method initializes the API key by retrieving it from the environment.
- If the key is not set, the servlet throws an exception to prevent execution without a valid key.
- This approach ensures that the API key is not stored in the source code and can be changed without modifying the application.

To set the API key in a UNIX-based system:

                export API_KEY=your_api_key

            
In Windows:
                setx API_KEY "your_api_key"

            

References