# Hardcoded Secrets

#### Tools recognizing this:

<kbd>Opengrep</kbd> <kbd>Fortify</kbd> <kbd>Checkmarx</kbd> <kbd>SonarQube</kbd> <kbd>Snyk</kbd> <kbd>Semgrep</kbd> <kbd>CodeQL</kbd>

## What are Hardcoded Secrets and How Do They Impact Security?

Hardcoded secrets are sensitive credentials, API keys, or passwords that are directly embedded in source code. This is a significant security risk as it can expose sensitive information to unauthorized users, especially when code is shared or made public.

The risks of hardcoded secrets include:

* Exposure of sensitive credentials in version control systems
* Difficulty in rotating or changing credentials
* Potential unauthorized access to systems and services
* Compliance violations and security audit failures

This guide covers hardcoded secrets, examples, prevention methods, and how to properly manage sensitive credentials in your applications.

## One Simple Hardcoded Secret Example

Consider this common example of hardcoded credentials:

{% code overflow="wrap" %}

```
const dbConnection = mysql.createConnection({
    host: 'localhost',
    user: 'admin',
    password: 'secretP@ssw0rd123!'
});
```

{% endcode %}

This exposes the database credentials directly in the code, making them:

<mark style="color:red;">Visible to anyone with code access</mark>

The credentials should instead be stored in:

<kbd>Environment variables</kbd> <kbd>Secret management systems</kbd> <kbd>Configuration files (outside version control)</kbd>

## Hardcoded Secrets Prevention Methods: How to Fix Your Code

The most effective way to fix hardcoded secrets is to externalize them from the code using environment variables or secure secret management systems.

Environment variables and secret managers provide a secure way to store and access sensitive credentials while keeping them separate from the application code.

### Code Samples

{% tabs %}
{% tab title="Java" %}
**Vulnerable Code**

<pre class="language-java"><code class="lang-java">public class ApiClient {
    private static final String API_KEY = <a data-footnote-ref href="#user-content-fn-1">"1234567890abcdef"</a>;
    private static final String API_SECRET = "secretKey123!";
    
    public void makeApiCall() {
        // Use API_KEY and API_SECRET
    }
}
</code></pre>

**Fixed Code**

```java
public class ApiClient {
    private static final String API_KEY = System.getenv("API_KEY");
    private static final String API_SECRET = System.getenv("API_SECRET");
    
    public void makeApiCall() {
        if (API_KEY == null || API_SECRET == null) {
            throw new IllegalStateException("API credentials not configured");
        }
        // Use API_KEY and API_SECRET
    }
}
```

**Fix Explanation**

The vulnerable code contains hardcoded API credentials directly in the source code. The fix uses environment variables to retrieve sensitive credentials at runtime. Added null checks to ensure credentials are properly configured. Credentials can now be easily rotated without code changes.
{% endtab %}

{% tab title="JavaScript" %}
**Vulnerable Code**

```javascript
const config = {
    apiKey: 'abcdef123456',
    apiSecret: 'secretKey789!',
    endpoint: 'https://api.example.com'
};

axios.post(config.endpoint, data, {
    headers: { 'Authorization': config.apiKey }
});
```

**Fixed Code**

```javascript
require('dotenv').config();

const config = {
    apiKey: process.env.API_KEY,
    apiSecret: process.env.API_SECRET,
    endpoint: process.env.API_ENDPOINT
};

if (!config.apiKey || !config.apiSecret) {
    throw new Error('Missing required API credentials');
}

axios.post(config.endpoint, data, {
    headers: { 'Authorization': config.apiKey }
});
```

**Fix Explanation**

The vulnerable code exposes API credentials directly in the source code. The fix uses dotenv to load environment variables. Credentials are accessed through process.env. Added validation to ensure required credentials are present.
{% endtab %}

{% tab title="Python" %}
**Vulnerable Code**

```python
class DatabaseConnection:
    def __init__(self):
        self.username = "admin"
        self.password = "db_password123!"
        self.host = "database.example.com"
        
    def connect(self):
        return mysql.connector.connect(
            user=self.username,
            password=self.password,
            host=self.host
        )
```

**Fixed Code**

```python
from os import environ
from dotenv import load_dotenv

class DatabaseConnection:
    def __init__(self):
        load_dotenv()
        self.username = environ.get('DB_USERNAME')
        self.password = environ.get('DB_PASSWORD')
        self.host = environ.get('DB_HOST')
        
    def connect(self):
        if not all([self.username, self.password, self.host]):
            raise ValueError("Missing database credentials")
        return mysql.connector.connect(
            user=self.username,
            password=self.password,
            host=self.host
        )
```

**Fix Explanation**

The vulnerable code contains hardcoded database credentials. The fix uses environment variables loaded through python-dotenv. Added validation to ensure all required credentials are available. Credentials can be managed separately from the code.
{% endtab %}

{% tab title="C#" %}
**Vulnerable Code**

```csharp
public class PaymentService
{
    private readonly string apiKey = "pk_test_51ABC123";
    private readonly string apiSecret = "sk_test_98XYZ456";

    public async Task ProcessPayment(decimal amount)
    {
        var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = 
            new AuthenticationHeaderValue("Bearer", apiSecret);
        // Process payment
    }
}
```

**Fixed Code**

```csharp
public class PaymentService
{
    private readonly string apiKey;
    private readonly string apiSecret;

    public PaymentService(IConfiguration configuration)
    {
        apiKey = configuration["Payment:ApiKey"] 
            ?? throw new ArgumentNullException("Payment:ApiKey");
        apiSecret = configuration["Payment:ApiSecret"]
            ?? throw new ArgumentNullException("Payment:ApiSecret");
    }

    public async Task ProcessPayment(decimal amount)
    {
        var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = 
            new AuthenticationHeaderValue("Bearer", apiSecret);
        // Process payment
    }
}
```

**Fix Explanation**

The vulnerable code contains hardcoded payment API credentials. The fix uses ASP.NET Core's configuration system. Credentials are injected through dependency injection. Added null checks to ensure credentials are configured.
{% endtab %}

{% tab title="PHP" %}
**Vulnerable Code**

```php
class S3Client
{
    private $accessKey = 'AKIAIOSFODNN7EXAMPLE';
    private $secretKey = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY';
    
    public function uploadFile($file)
    {
        $s3 = new Aws\S3\S3Client([
            'credentials' => [
                'key'    => $this->accessKey,
                'secret' => $this->secretKey,
            ],
            'region'  => 'us-west-2',
            'version' => 'latest'
        ]);
        // Upload file
    }
}
```

**Fixed Code**

```php
class S3Client
{
    private $accessKey;
    private $secretKey;
    
    public function __construct()
    {
        $this->accessKey = getenv('AWS_ACCESS_KEY_ID');
        $this->secretKey = getenv('AWS_SECRET_ACCESS_KEY');
        
        if (!$this->accessKey || !$this->secretKey) {
            throw new RuntimeException('AWS credentials not configured');
        }
    }
    
    public function uploadFile($file)
    {
        $s3 = new Aws\S3\S3Client([
            'credentials' => [
                'key'    => $this->accessKey,
                'secret' => $this->secretKey,
            ],
            'region'  => 'us-west-2',
            'version' => 'latest'
        ]);
        // Upload file
    }
}
```

**Fix Explanation**

The vulnerable code contains hardcoded AWS credentials. The fix uses environment variables to store credentials. Added validation to ensure credentials are available. Follows AWS security best practices for credential management.
{% endtab %}

{% tab title="C/C++" %}
**Vulnerable Code**

```cpp
class AuthService {
private:
    const std::string API_KEY = "my-static-api-key-123";
    const std::string API_SECRET = "my-static-secret-456";

public:
    bool authenticate() {
        // Use API_KEY and API_SECRET for authentication
        return true;
    }
};
```

**Fixed Code**

```cpp
class AuthService {
private:
    std::string API_KEY;
    std::string API_SECRET;

public:
    AuthService() {
        char* apiKey = std::getenv("API_KEY");
        char* apiSecret = std::getenv("API_SECRET");
        
        if (!apiKey || !apiSecret) {
            throw std::runtime_error("Missing API credentials");
        }
        
        API_KEY = std::string(apiKey);
        API_SECRET = std::string(apiSecret);
    }

    bool authenticate() {
        // Use API_KEY and API_SECRET for authentication
        return true;
    }
};
```

**Fix Explanation**

The vulnerable code contains hardcoded API credentials. The fix uses environment variables through std::getenv. Added validation to ensure credentials are available. Credentials can be managed externally from the application.
{% endtab %}
{% endtabs %}

## Need more help in preventing Hardcoded Secrets?

[Mobb](https://mobb.ai) supports fixing many forms of Hardcoded Secrets vulnerabilities, and can mitigate your issues in batch.

Start now for free at [app.mobb.ai](https://app.mobb.ai)

### We'd love your feedback!

We're excited to hear your thoughts and ideas about fixing vulnerabilities.

[Book a meeting](https://calendly.com/mobbai/demo) or [Contact us](https://content.mobb.ai/contact) if you have any corrections, questions or suggestions. Start now for free at <https://app.mobb.ai>

[^1]: This is the vulnerable part
