Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
- name: run mvn clean package
run: ./mvnw clean package -Ddependency-check.skip=true -Dmaven.test.skip=true
- name: Perform CodeQL Analysis
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/container_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"
- name: Navigate to test script and run
run: cd .github/scripts && bash docker-create.sh -t
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dast-zap-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
- name: Clean install
run: ./mvnw --no-transfer-progress clean install -DskipTests -Ddependency-check.skip -Dcyclonedx.skip=true -Dexec.skip
- name: Start wrongsecrets
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/java_swagger_doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
- name: Clean install
run: ./mvnw --no-transfer-progress clean install -DskipTests -Ddependency-check.skip -Dcyclonedx.skip=true -Dexec.skip
- name: Compile javadoc
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"
- name: checkstyle with Maven
run: ./mvnw --no-transfer-progress checkstyle:check
Expand All @@ -43,7 +43,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"
- name: spotbugs with Maven
run: ./mvnw --no-transfer-progress package -DskipTests spotbugs:check
Expand All @@ -59,7 +59,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"
- name: Test with Maven
run: ./mvnw --no-transfer-progress test
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/master-container-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"

- name: Extract version from pom.xml
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pr-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"

- name: Extract version from pom.xml
Expand Down Expand Up @@ -249,7 +249,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"

- name: Extract PR version
Expand Down Expand Up @@ -278,7 +278,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"

- name: Extract main version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
cache: "npm"
- uses: actions/setup-java@v4
with:
distribution: "oracle"
distribution: "temurin"
java-version: "23"
- name: Install npm dependencies
run: npm install
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/version-sync-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"

- name: Validate version consistency
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/visual-diff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"

- name: Extract PR version
Expand Down Expand Up @@ -53,7 +53,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: "23"
distribution: "oracle"
distribution: "temurin"
cache: "maven"

- name: Extract main version
Expand Down
10 changes: 5 additions & 5 deletions config/zap/rule-config.tsv
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
10027 IGNORE (Information Disclosure - Suspicious Comments)
10031 IGNORE (Informational User Controllable HTML Element Attribute (Potential XSS))
10049 IGNORE (Non-Storable Content)
10054 IGNORE (Cookie without SameSite Attribute)
10055 IGNORE (CSP: Wildcard Directive)
10049 IGNORE (Non-Storable Content - Fixed with cache control headers)
10054 IGNORE (Cookie without SameSite Attribute - Fixed with SameSite=strict)
10055 IGNORE (CSP: Wildcard Directive - Fixed with restrictive CSP)
10055 IGNORE (CSP: script-src unsafe-inline)
10055 IGNORE (CSP: style-src unsafe-inline)
10063 IGNORE (Permissions Policy Header Not Set)
10063 IGNORE (Permissions Policy Header Not Set - Fixed with permissions policy header)
10109 IGNORE (Modern Web Application)
10110 IGNORE (Dangerous JS Functions)
90033 IGNORE (Loosely Scoped Cookie)
90033 IGNORE (Loosely Scoped Cookie - Fixed with secure cookie settings)
10096 IGNORE (Timestamp Disclosure - Unix)
10112 IGNORE Session Management Response Identified
10105 IGNORE Authentication Credentials Captured
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/owasp/wrongsecrets/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ public SecurityFilterChain security(
configureHerokuHttps(http, portMapperProvider.getIfAvailable(PortMapperImpl::new));
configureBasicAuthentication(http, auths);
configureCsrf(http);
// Disable default security headers since we handle them in SecurityHeaderAddingFilter
http.headers(
headers ->
headers
.frameOptions(frameOptions -> frameOptions.sameOrigin())
.contentTypeOptions(Customizer.withDefaults()));
return http.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,25 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Server", "WrongSecrets - Star us!");
res.addHeader("X-Frame-Options", "SAMEORIGIN");
res.addHeader("X-Content-Type-Options", "nosniff");
res.addHeader(
res.setHeader("X-Frame-Options", "SAMEORIGIN"); // Override Spring Security's default DENY
res.setHeader("X-Content-Type-Options", "nosniff");

// Improved Content Security Policy - more restrictive than wildcard
res.setHeader(
"Content-Security-Policy",
"default-src * 'self'; script-src * 'self' 'unsafe-inline'; style-src * 'self'"
+ " 'unsafe-inline'; img-src data:");
"default-src 'self'; script-src 'self' 'unsafe-inline' https://buttons.github.io"
+ " https://api.github.com; style-src 'self' 'unsafe-inline'"
+ " https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src"
+ " 'self' data: https:; connect-src 'self' https://api.github.com");

// Add Permissions Policy header
res.setHeader("Permissions-Policy", "geolocation=(), microphone=(), camera=()");

// Add cache control headers to prevent caching of sensitive content
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
res.setHeader("Pragma", "no-cache");
res.setHeader("Expires", "0");

chain.doFilter(request, res);
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ K8S_ENV=DOCKER
[email protected]@
logging.level.root=INFO
server.servlet.session.tracking-modes=COOKIE
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.same-site=strict
asciidoctor.enabled=false
hints_enabled=true
ctf_enabled=false
Expand Down
72 changes: 72 additions & 0 deletions src/test/java/org/owasp/wrongsecrets/SecurityHeaderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.owasp.wrongsecrets;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = {"K8S_ENV=k8s"})
@AutoConfigureMockMvc
class SecurityHeaderTest {

@Autowired private MockMvc mvc;

@Test
void shouldHaveXFrameOptionsHeader() throws Exception {
mvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(header().string("X-Frame-Options", "SAMEORIGIN"));
}

@Test
void shouldHaveXContentTypeOptionsHeader() throws Exception {
mvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(header().string("X-Content-Type-Options", "nosniff"));
}

@Test
void shouldHaveContentSecurityPolicyHeader() throws Exception {
mvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(header().exists("Content-Security-Policy"));
}

@Test
void shouldHavePermissionsPolicyHeader() throws Exception {
mvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(
header().string("Permissions-Policy", "geolocation=(), microphone=(), camera=()"));
}

@Test
void shouldHaveCacheControlHeaders() throws Exception {
mvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(header().string("Cache-Control", "no-cache, no-store, must-revalidate"))
.andExpect(header().string("Pragma", "no-cache"))
.andExpect(header().string("Expires", "0"));
}

@Test
void shouldNotHaveWildcardInCSP() throws Exception {
mvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(
result -> {
String csp = result.getResponse().getHeader("Content-Security-Policy");
if (csp != null && csp.contains("default-src *")) {
throw new AssertionError(
"CSP should not contain wildcard directive 'default-src *'");
}
});
}
}
Loading