A few days ago, a friend of mine had a security issue where the database credentials for their project were exposed. After investigating, we discovered that this happened due to a .git
configuration commit, which inadvertently included sensitive information. To avoid such risks, I highly recommend managing sensitive credentials through operating system environment variables instead of hard-coding them into your project files. This approach ensures that critical information remains separate from your codebase, enhancing security.
In this post, I’ll walk you through the steps to set up environment variables for an Apache web server. This method will help you securely manage sensitive data like database credentials and API keys, protecting them from potential exposure in your version control system.
Expanding on the topic of managing sensitive credentials in software projects, it’s essential to understand both the risks involved and the best practices that can prevent such incidents. Your friend’s experience highlights a common yet critical security vulnerability—exposing sensitive information like database credentials through version control systems such as Git.
The Risks of Exposed Credentials
When sensitive information is hard-coded into project files, it becomes inherently vulnerable, especially if these files are committed to a version control system. This could lead to unauthorized access if the code is accidentally shared, whether publicly or within a team with varying levels of access. Once credentials are exposed, they can be exploited by attackers to gain unauthorized access to databases, APIs, or other critical infrastructure, potentially leading to data breaches, financial loss, and damage to the organization’s reputation.
Common Causes of Credential Exposure
Several factors can contribute to the accidental exposure of credentials:
- Committing Configuration Files: Developers may inadvertently commit configuration files containing sensitive information to the repository, particularly during rapid development cycles or when collaborating with others.
- Inadequate Use of .gitignore: Failing to properly configure the
.gitignore
file can result in sensitive files being tracked by Git. This is especially dangerous for files like.env
files, which are often used to store environment variables locally. - Lack of Environment-Specific Configuration: Using the same configuration across different environments (e.g., development, testing, production) without adequately securing credentials can lead to exposure, especially in shared or public environments.
Best Practices for Managing Sensitive Credentials
To mitigate the risks of credential exposure, developers should adopt best practices that prioritize security and reduce the chances of sensitive information being included in version control. Here are some recommended approaches:
- Use Environment Variables: Storing sensitive credentials in environment variables rather than hard-coding them into project files is one of the most effective ways to keep them secure. Environment variables are managed by the operating system, separate from the codebase, reducing the risk of accidental exposure. Tools like
dotenv
can help load these variables into the application’s environment without including them in the code. - Implement Secrets Management Solutions: For more complex projects or those operating in production environments, consider using a dedicated secrets management tool like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault. These tools offer robust solutions for storing, accessing, and auditing sensitive information, ensuring that only authorized services and individuals have access.
- Properly Configure .gitignore: Always ensure that sensitive files, such as those containing environment variables, are listed in the
.gitignore
file. This prevents Git from tracking these files and inadvertently committing them to the repository. Additionally, use global Git ignore rules for files that should never be committed, regardless of the project. More information on this can be found in the Git documentation. - Rotate Credentials Regularly: Even with secure practices in place, it’s important to rotate credentials periodically. This reduces the risk of long-term exposure and limits the impact if credentials are accidentally leaked. Automated scripts or tools can help manage and rotate secrets across different environments. Learn more about best practices in secret rotation from this guide by Auth0.
- Audit and Monitor: Regularly audit your repositories and environments for any accidental inclusion of sensitive information. Tools like
git-secrets
,truffleHog
, andGitleaks
can scan your codebase for exposed secrets and alert you to potential risks. Additionally, monitoring access to critical systems can help detect unauthorized use of credentials. - Educate Your Team: Security is a team effort. Ensure that all team members, including developers, operations staff, and DevOps engineers, are aware of the importance of handling credentials securely. Provide training on best practices and the use of tools that can help safeguard sensitive information. The OWASP Foundation offers valuable resources and guidelines to help teams enhance their security posture.
Apache Config Folder
If you have Apache installed, go to the following directory.
cd /etc/apache2/sites-available
Take Config File Backup
Duplicate the original configuration file with different name. You can revert if anything wrong.
cp 000-default.conf 000-default.conf.back
Edit 000-defualt.conf
You have to modify the default conf file for environment configuraiton. User nano or vi editor.
vi 000-default.conf
Configure Enviroment Variables
Modify the file and include all of you sensitive information like database, SMTP and AWS credentials.
<VirtualHost *:80>
SetEnv DB_USERNAME Your_Username
SetEnv DB_PASSWORD Your_Password
SetEnv SMTP_USERNAME Your_SMTP_Username
SetEnv SMTP_PASSWORD Your_SMTP_Password
</VirtualHost>
Disable Apache Configuration
Edit php.ini file.
$vi /etc/php/8.0/apache2/php.ini
Disable phpinfo() Function
Include phpinfo in disable functions list and save the php.ini
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,phpinfo,
Restart Apache Server
Save the above file and restart your Apache server.
$/etc/init.d/apache2 restart
XAMPP
If you are using XAMPP, it has a different config settings.
XAMPP Location
Got to XAMPP httpd configuration location.
cd /opt/lampp/etc
Take Backup
Copy the httpd.conf with different name.
cp httpd.conf httpd.conf.back
Edit httpd.conf
You have to modify the default conf file for environment configuraiton. User nano or vi editor.
vi httpd.conf
Configure Enviroment Variables
You can include SetEnv values.
SetEnv DB_USERNAME Your_Username
SetEnv DB_PASSWORD Your_Password
SetEnv SMTP_USERNAME Your_SMTP_Username
SetEnv SMTP_PASSWORD Your_SMTP_Password
Restart XAMPP Server
Save the above file and restart your XAMPP server.
$/opt/lampp/lampp restart
PHP Configuration
You can read evniroment variables using getenv method.
<?php
$DB_USERNAME = getenv('DB_USERNAME');
$DB_PASSWORD = getenv('DB_PASSWORD');
//SMTP credentials
$SMTP_USERNAME = getenv('SMTP_USERNAME');
$SMTP_PASSWORD = getenv('SMTP_PASSWORD');
$SMTP_HOST = getenv('SMTP_HOST');
function getDB()
{
$dbhost = 'localhost';
$dbuser = $DB_USERNAME;
$dbpass = $DB_PASSWORD;
$dbname = 'Your_Database_Name';
$dbConnection = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbConnection->exec("set names utf8");
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbConnection;
}
?>