Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Challenge51: Misconfiguration of docker secret in code. #1611

Closed
wants to merge 10 commits into from
13 changes: 13 additions & 0 deletions k8s/challenge49docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3.8'

services:
db:
image: postgres:latest
environment:
POSTGRES_USER: wrongsecrets
POSTGRES_PASSWORD: sdfjklhjUYYkghjv;-jhkf
POSTGRES_DB: Acme
ports:
- "5432:5432"
volumes:
- ./postgres_data:/var/lib/postgresql/data
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.owasp.wrongsecrets.challenges.docker;

import org.owasp.wrongsecrets.challenges.FixedAnswerChallenge;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Challenge49 extends FixedAnswerChallenge {

private final String dockerSecret;

public Challenge49(@Value("${DOCKER_SECRET_CHALLENGE49}") String dockerSecret) {
this.dockerSecret = dockerSecret;
}

@Override
public String getAnswer() {
return this.dockerSecret;
}
}
1 change: 1 addition & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ challenge26ciphertext=gbU5thfgy8nwzF/qc1Pq59PrJzLB+bfAdTOrx969JZx1CKeG4Sq7v1uUpz
DEFAULT37=DEFAULT37
challenge27ciphertext=gYPQPfb0TUgWK630tHCWGwwME6IWtPWA51eU0Qpb9H7/lMlZPdLGZWmYE83YmEDmaEvFr2hX
challenge41password=UEBzc3dvcmQxMjM=
DOCKER_SECRET_CHALLENGE49=sdfjklhjUYYkghjv;-jhkf
commjoen marked this conversation as resolved.
Show resolved Hide resolved
management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true
Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/explanations/challenge49.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
=== Exposed Docker Secrets Challenge

In this challenge, you will explore the importance of securely managing sensitive information using Docker secrets. Docker secrets are intended to safely transmit and store sensitive data like passwords, API keys, and certificates within Docker services. However, improper handling or misconfigurations can inadvertently expose these secrets, leading to potential security risks.

*Acme Inc.*, a rapidly growing e-commerce platform, has recently experienced suspicious activities suggesting that sensitive customer data might have been compromised. An internal audit reveals that a developer inadvertently exposed database credentials by hardcoding them into the `challenge49docker-compose.yml` file and pushing it to a public Git repository. Additionally, the application was not utilizing Docker secrets effectively, leading to plaintext exposure of sensitive information within running containers.

You have been hired as Technical Security Consultant, your job is to secure the exposed secrets to protect the sensitive information? For now identify the misconfigurations and report the database password to fix the situation.
13 changes: 13 additions & 0 deletions src/main/resources/explanations/challenge49_hint.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This challenge can be solved using the following ways:

- *Acme Inc*. has a misconfigured docker-compose.yml file where sensitive information is exposed. Your task is to find these vulnerabilities.
1. Clone the repository containing the challenge files.
2. Locate the `challenge49docker-compose.yml` file in the repository.
3. Inspect the Environment Variables
4. Identify Hardcoded Credentials
Within the environment section, check for variables like:
- `POSTGRES_USER`
- `POSTGRES_PASSWORD`
- `POSTGRES_DB`
5. Extract the Database Password
- The value assigned to `POSTGRES_PASSWORD` is the database password.
22 changes: 22 additions & 0 deletions src/main/resources/explanations/challenge49_reason.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
*Why Proper Handling of Docker Secrets is Important?*

Docker secrets provide a secure way to manage sensitive information such as passwords, API keys, and certificates within Docker services. However, improper handling and misconfiguration can lead to serious security vulnerabilities.

If sensitive data like database credentials are hardcoded into files like docker-compose.yml and pushed to public repositories, it nullifies the security provided by Docker secrets. Anyone with access to the repository can access the credentials, leading to potential data breaches and unauthorized access.

Let's consider an example:

. Imagine a scenario where a developer hardcodes database credentials directly into the challenge49docker-compose.yml file and pushes it to a public Git repository:
*The file contains plaintext environment variables such as POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB. . This situation is analogous to writing down your passwords on a sticky note and leaving it on your computer monitor:
.An attacker can easily find the credentials and gain unauthorized access to the database.

To prevent such issues, it is crucial to ensure that sensitive information is managed securely and not exposed in version-controlled files. Always follow best practices for secret management and avoid hardcoding sensitive information in your repositories.

*Food for thought on Docker secrets*
Even when you keep secrets out of version control, Docker secrets have some considerations:
1.Access Control Misconfigurations: If you don't configure access controls correctly, unauthorized users may still access the secrets when they have access to the Docker environment.
2.Storage of Secrets on Disk: Docker secrets are stored on the manager node's filesystem (in Swarm mode). If the node is compromised, secrets stored in /var/lib/docker/swarm/secrets/ could be exposed.
3.Secret Rotation Challenges: Rotating secrets requires careful orchestration to update running services without downtime. How will you ensure all services receive the updated secrets seamlessly?
4.Potential for Offline Attacks: If secrets are not encrypted properly during storage or transmission, attackers could capture and attempt to decrypt them offline. Can you think of scenarios where weak encryption schemes might be exploited?

Always ensure that you're using robust encryption methods and following best practices for secret management to mitigate these risks.
13 changes: 13 additions & 0 deletions src/main/resources/wrong-secrets-configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -775,3 +775,16 @@ configurations:
category: *secrets
ctf:
enabled: false

- name: Challenge 49
short-name: "challenge-49"
sources:
- class-name: "org.owasp.wrongsecrets.challenges.docker.Challenge49"
explanation: "explanations/challenge49.adoc"
hint: "explanations/challenge49_hint.adoc"
reason: "explanations/challenge49_reason.adoc"
environments: *all_envs
difficulty: *easy
category: *secrets
ctf:
enabled: false
Shubham-Patel07 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.owasp.wrongsecrets.challenges.docker;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.owasp.wrongsecrets.challenges.Spoiler;

class Challenge49Test {

@Test
void spoilerShouldGiveAnswer() {
var challenge = new Challenge49("test");

assertThat(challenge.spoiler()).isEqualTo(new Spoiler("test"));
}

@Test
void rightAnswerShouldSolveChallenge() {
var challenge = new Challenge49("test");

assertThat(challenge.answerCorrect("test")).isTrue();
}

@Test
void incorrectAnswerShouldNotSolveChallenge() {
var challenge = new Challenge49("test");

assertThat(challenge.answerCorrect("wrong answer")).isFalse();
}
}
Loading