Merge pull request #501 from shivachethanreddy/rails-5-1-encrypted-secrets-fix
Add bonus documentation for Rails encrypted secrets
This commit is contained in:
@@ -103,6 +103,14 @@ Visit the [RailsGoat Wiki](https://github.com/OWASP/railsgoat/wiki) for detailed
|
|||||||
- Code examples
|
- Code examples
|
||||||
- Remediation steps
|
- Remediation steps
|
||||||
|
|
||||||
|
## Bonus Security Topics
|
||||||
|
|
||||||
|
Additional documentation covering advanced and modern Rails security concepts:
|
||||||
|
|
||||||
|
- [Bonus: Encrypted Secrets and Credentials in Rails 5.1+](docs/bonus_encrypted_secrets.md)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Docker Installation
|
## Docker Installation
|
||||||
|
|
||||||
**Requirements:** [Docker](https://docs.docker.com/engine/installation/) and [Docker Compose](https://docs.docker.com/compose/install/) 1.6.0+
|
**Requirements:** [Docker](https://docs.docker.com/engine/installation/) and [Docker Compose](https://docs.docker.com/compose/install/) 1.6.0+
|
||||||
|
|||||||
@@ -1,4 +1,15 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
# NOTE:
|
||||||
|
# RailsGoat intentionally uses an insecure approach for key management.
|
||||||
|
# This is done to demonstrate bad practices for educational purposes.
|
||||||
|
#
|
||||||
|
# In real-world Rails applications:
|
||||||
|
# - Rails 5.1 supports encrypted secrets via config/secrets.yml
|
||||||
|
# - Rails 5.2+ supports encrypted credentials via credentials.yml.enc
|
||||||
|
# - Secrets are commonly provided via environment variables (ENV)
|
||||||
|
#
|
||||||
|
# Hardcoding keys or omitting secure secret management must NEVER be done
|
||||||
|
# in production applications.
|
||||||
if Rails.env.production?
|
if Rails.env.production?
|
||||||
# Specify env variable/location/etc. to retrieve key from
|
# Specify env variable/location/etc. to retrieve key from
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
# Bonus: Encrypted Secrets in Rails 5.1+
|
||||||
|
|
||||||
|
This bonus section explains how modern Rails applications manage sensitive
|
||||||
|
information such as secret keys, API tokens, and credentials.
|
||||||
|
|
||||||
|
RailsGoat intentionally does NOT follow these practices by default, because it
|
||||||
|
is designed to demonstrate insecure patterns for educational purposes.
|
||||||
|
However, real-world applications should always protect secrets properly.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What Are Application Secrets?
|
||||||
|
|
||||||
|
Application secrets include:
|
||||||
|
- `secret_key_base`
|
||||||
|
- API keys
|
||||||
|
- OAuth client secrets
|
||||||
|
- Encryption keys
|
||||||
|
- Database credentials
|
||||||
|
|
||||||
|
If these values are exposed, attackers may be able to:
|
||||||
|
- Hijack user sessions
|
||||||
|
- Forge cookies
|
||||||
|
- Access third-party services
|
||||||
|
- Decrypt sensitive data
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Problem with Hardcoded Secrets
|
||||||
|
|
||||||
|
Hardcoding secrets directly in source code is dangerous because:
|
||||||
|
- Source code is often shared publicly
|
||||||
|
- Secrets can be leaked via Git history
|
||||||
|
- Compromised secrets are difficult to rotate
|
||||||
|
|
||||||
|
Example of an insecure approach:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
SECRET_KEY_BASE = "hardcoded_secret_value"
|
||||||
|
```
|
||||||
|
|
||||||
|
Once committed, this secret is effectively public forever.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rails 5.1: Encrypted Secrets
|
||||||
|
|
||||||
|
Rails 5.1 introduced encrypted secrets using `config/secrets.yml`.
|
||||||
|
|
||||||
|
A typical secure configuration looks like this:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
production:
|
||||||
|
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
||||||
|
```
|
||||||
|
|
||||||
|
In this approach:
|
||||||
|
- Secrets are stored outside the codebase
|
||||||
|
- Environment variables are injected at runtime
|
||||||
|
- Different environments can use different secrets
|
||||||
|
|
||||||
|
This pattern is commonly used in:
|
||||||
|
- Docker
|
||||||
|
- CI/CD pipelines
|
||||||
|
- Cloud platforms
|
||||||
|
|
||||||
|
## Rails 5.2+: Encrypted Credentials
|
||||||
|
|
||||||
|
Rails 5.2 introduced encrypted credentials, which are now the recommended
|
||||||
|
approach.
|
||||||
|
|
||||||
|
Credentials are stored in:
|
||||||
|
|
||||||
|
- `config/credentials.yml.enc`
|
||||||
|
|
||||||
|
They are encrypted using a master key stored in:
|
||||||
|
|
||||||
|
- `config/master.key`
|
||||||
|
|
||||||
|
Credentials are edited using:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rails credentials:edit
|
||||||
|
```
|
||||||
|
|
||||||
|
Example usage in application code:
|
||||||
|
```ruby
|
||||||
|
Rails.application.credentials.secret_key_base
|
||||||
|
```
|
||||||
|
## Important Rules
|
||||||
|
|
||||||
|
- `master.key` must **NEVER** be committed to version control
|
||||||
|
- `credentials.yml.enc` **is safe** to commit
|
||||||
|
- Secrets can be rotated without changing application code
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Why RailsGoat Is Different
|
||||||
|
|
||||||
|
RailsGoat intentionally avoids secure secret management in order to:
|
||||||
|
|
||||||
|
- Demonstrate insecure patterns
|
||||||
|
- Teach developers how vulnerabilities arise
|
||||||
|
- Provide hands-on security training
|
||||||
|
|
||||||
|
This is a deliberate design choice and should **NOT** be copied into real
|
||||||
|
applications.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recommended Best Practices
|
||||||
|
|
||||||
|
For real-world Rails applications:
|
||||||
|
|
||||||
|
- Never hardcode secrets
|
||||||
|
- Use environment variables or encrypted credentials
|
||||||
|
- Never commit `master.key`
|
||||||
|
- Rotate secrets regularly
|
||||||
|
- Restrict access to production secrets
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user