diff --git a/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/HealthControllerTest.java b/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/HealthControllerTest.java index 695fa221..fb329bd5 100644 --- a/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/HealthControllerTest.java +++ b/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/HealthControllerTest.java @@ -8,6 +8,7 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; 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.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -27,6 +28,8 @@ class HealthControllerTest { .andExpect(jsonPath("$.msg").isNotEmpty()) .andExpect(jsonPath("$.data.message").value("UP")) .andExpect(jsonPath("$.timestamp").isNotEmpty()) - .andExpect(jsonPath("$.requestId").isNotEmpty()); + .andExpect(jsonPath("$.requestId").isNotEmpty()) + .andExpect(header().string("Content-Security-Policy", org.hamcrest.Matchers.containsString("default-src 'self'"))) + .andExpect(header().string("Content-Security-Policy", org.hamcrest.Matchers.containsString("object-src 'none'"))); } } diff --git a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java index 28ee57ba..46940e56 100644 --- a/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java +++ b/server/skillhub-auth/src/main/java/com/iflytek/skillhub/auth/config/SecurityConfig.java @@ -33,6 +33,17 @@ import org.springframework.security.web.util.matcher.RequestMatcher; @EnableWebSecurity @EnableMethodSecurity public class SecurityConfig { + private static final String CONTENT_SECURITY_POLICY = String.join("; ", + "default-src 'self'", + "script-src 'self' 'unsafe-inline' 'unsafe-eval'", + "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com", + "img-src 'self' data: blob: https:", + "font-src 'self' data: https://fonts.gstatic.com", + "connect-src 'self' ws: wss: http://localhost:* https://localhost:*", + "object-src 'none'", + "base-uri 'self'", + "frame-ancestors 'none'", + "form-action 'self'"); private final CustomOAuth2UserService customOAuth2UserService; private final SkillHubOAuth2AuthorizationRequestResolver authorizationRequestResolver; @@ -156,6 +167,7 @@ public class SecurityConfig { ) .headers(headers -> headers .contentTypeOptions(contentTypeOptions -> {}) + .contentSecurityPolicy(csp -> csp.policyDirectives(CONTENT_SECURITY_POLICY)) .frameOptions(frameOptions -> frameOptions.deny()) .httpStrictTransportSecurity(hsts -> hsts .includeSubDomains(true) diff --git a/web/index.html b/web/index.html index ceca1d26..107e37f9 100644 --- a/web/index.html +++ b/web/index.html @@ -3,6 +3,10 @@ + SkillHub