Skip to content

Commit

Permalink
#44 front end JavaScript library with key obfuscated
Browse files Browse the repository at this point in the history
  • Loading branch information
drnow4u committed Mar 23, 2022
1 parent f930545 commit 0358336
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 55 deletions.
2 changes: 1 addition & 1 deletion js/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function secret() {
var password = 'wg2QIk2N' + 8 + 'YmTEd' + 3 + 'C/jnlkFGeIpdeGI+lKzK7rROePYU=';
var password = 'wg' + 2 + 'QIk' + 2 + 'N' + 8 + 'YmTEd' + 3 + 'C/jnlkFGeIpdeGI+lKzK' + 7 + 'rROePYU=';
return password
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
@Order(15)
public class Challenge15 extends Challenge {

private String dockerMountPath;
private final String dockerMountPath;

public Challenge15(ScoreCard scoreCard, @Value("${challengedockermtpath}") String dockerMountPath) {
super(scoreCard);
Expand All @@ -42,7 +42,7 @@ public List<RuntimeEnvironment.Environment> supportedRuntimeEnvironments() {
return List.of(RuntimeEnvironment.Environment.DOCKER);
}

private String getActualData() {
public String getActualData() {
try {
return Files.readString(Paths.get(dockerMountPath, "yourkey.txt"));
} catch (Exception e) {
Expand Down
41 changes: 0 additions & 41 deletions src/main/java/org/owasp/wrongsecrets/client/TokenController.java

This file was deleted.

59 changes: 59 additions & 0 deletions src/main/java/org/owasp/wrongsecrets/oauth/TokenController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.owasp.wrongsecrets.oauth;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;

@Slf4j
@Controller
public class TokenController {

private final String dockerMountPath;

public TokenController(@Value("${challengedockermtpath}") String dockerMountPath) {
this.dockerMountPath = dockerMountPath;
}


@PostMapping(path = "/token", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public ResponseEntity<?> clientCredentialToken(TokenRequest tokenRequest) {
if ("client_credentials".equals(tokenRequest.grant_type())
&& "WRONGSECRET_CLIENT_ID".equals(tokenRequest.client_id())
&& getActualData().equals(tokenRequest.client_secret())) {
return ResponseEntity.ok(
new TokenResponse(UUID.randomUUID().toString(), "bearer", 54321L, "user_info")
);
}
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.build();
}

public record TokenRequest(String grant_type,
String client_id,
String client_secret) {
}

public record TokenResponse(@JsonProperty("access_token") String accessToken,
@JsonProperty("token_type") String tokenType,
@JsonProperty("expires_in") Long expiresIn,
String scope) {
}

public String getActualData() {
try {
return Files.readString(Paths.get(dockerMountPath, "yourkey.txt"));
} catch (Exception e) {
log.warn("Exception during file reading, defaulting to default without cloud environment", e);
return "if_you_see_this_please_use_docker_instead";
}
}
}
4 changes: 3 additions & 1 deletion src/main/resources/explanations/challenge15.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
=== Docker COPY and WORKDIR

When we start new project usually we are focus on new festers implementation than on security aspect.
In such situation it easy to store secret or credential in front-end code.
Sometimes Single Page Application or mobile application need to access information for themself rather then on behalf of a user.
For this purpose OAuth provides the `client_credentials` flow to get access token.
In such situation it easy to store client secrets in front-end or mobile application code.

What about looking for it in the Development Tools in browser?
8 changes: 3 additions & 5 deletions src/main/resources/explanations/challenge15_hint.adoc
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
You can solve this challenge by the following steps:

1. Open main page in the browser
1. Open main page in the Chrome browser
2. Open development tools:
- select Network tab
- find request with path `/oauth/token`
- find in the request `Authorization` header
- decode Base64 heder value after `Basic`
- the first part before `:` is user name and the second is password
- find request with path `/token`
- find in the request body `client_secret`
2 changes: 1 addition & 1 deletion src/main/resources/explanations/challenge15_reason.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*Why using Single Page Application or Mobile application to put secrets in is a bad idea*
*Why using Single Page Application or Mobile application to put client secret in is a bad idea*

As you can tell by now, you can easily detect any secret that stored within a Single Page Application or Mobile application.
Authorization Code Flow with Proof Key for Code Exchange (PKCE)
9 changes: 5 additions & 4 deletions src/main/resources/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@
<script>
const password = secret();
const httpRequest = new XMLHttpRequest();
httpRequest.open("POST", "/oauth/token", true);
httpRequest.setRequestHeader("Authorization", "Basic " + btoa("john:" + password));
httpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
httpRequest.send("grant_type=client_credentials&scope=user_info");
httpRequest.open("POST", "/token", true);
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
httpRequest.send("grant_type=client_credentials"
+ "&client_id=" + encodeURIComponent("WRONGSECRET_CLIENT_ID")
+ "&client_secret=" + encodeURIComponent(password));
</script>
</body>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.owasp.wrongsecrets.challenges.docker;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.owasp.wrongsecrets.ScoreCard;
import org.owasp.wrongsecrets.challenges.Spoiler;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

@ExtendWith(MockitoExtension.class)
class Challenge15Test {

@Mock
private ScoreCard scoreCard;

@Test
void solveChallenge15WithoutFile(@TempDir Path dir) {
var challenge = new Challenge15(scoreCard, dir.toString());

Assertions.assertThat(challenge.answerCorrect("secretvalueWitFile")).isFalse();
Assertions.assertThat(challenge.answerCorrect("if_you_see_this_please_use_docker_instead")).isTrue();
}

@Test
void solveChallenge15WithMNTFile(@TempDir Path dir) throws Exception {
var testFile = new File(dir.toFile(), "yourkey.txt");
var secret = "secretvalueWitFile";
Files.writeString(testFile.toPath(), secret);

var challenge = new Challenge15(scoreCard, dir.toString());

Assertions.assertThat(challenge.answerCorrect("secretvalueWitFile")).isTrue();
}

@Test
void spoilShouldReturnCorrectAnswer(@TempDir Path dir) throws IOException {
var testFile = new File(dir.toFile(), "yourkey.txt");
var secret = "secretvalueWitFile";
Files.writeString(testFile.toPath(), secret);

var challenge = new Challenge15(scoreCard, dir.toString());

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

}

0 comments on commit 0358336

Please sign in to comment.