Skip to content

Commit f624010

Browse files
authored
Merge pull request #27 from hexawulf/codex/perform-security-hardening-and-cleanup
Cleanup and hardening
2 parents 222b6e5 + 9721820 commit f624010

9 files changed

Lines changed: 154 additions & 221 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,4 @@ Thumbs.db
8484
replit.nixtarget/
8585
*.jar
8686
*.class
87+
attached_assets/

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ app.encryption.default-strength=4096
119119
app.encryption.max-expiry-days=3650
120120
```
121121

122+
Copy `src/main/resources/application-example.properties` to
123+
`src/main/resources/application.properties` and adjust values for
124+
your environment. **Do not** commit secrets to version control.
125+
122126
---
123127

124128
## 📖 Usage
@@ -188,6 +192,8 @@ keyjolt/
188192
- Configure proper firewall rules
189193
- Set up monitoring and alerting
190194
- Regular security updates
195+
- Restrict access to `/actuator` endpoints or disable them
196+
- Set `SPRING_PROFILES_ACTIVE=production` for production builds
191197

192198
### **Key Safety**
193199
- Private keys are generated server-side and immediately deleted

attached_assets/Pasted-1-User-Experience-Accessibility-Form-Validation-Feedback-When-users-enter-invalid-data-e-g--1750206002629_1750206002630.txt

Lines changed: 0 additions & 90 deletions
This file was deleted.

attached_assets/Pasted-Replit-Prompt-for-KeyJolt-Web-App-Project-Name-KeyJolt-PGP-Key-Generator-Description-Build-a-Jav-1750206032550_1750206032550.txt

Lines changed: 0 additions & 76 deletions
This file was deleted.

pom.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,6 @@
7171
<version>7.6.0</version>
7272
</dependency>
7373

74-
<!-- Commons IO -->
75-
<dependency>
76-
<groupId>commons-io</groupId>
77-
<artifactId>commons-io</artifactId>
78-
<version>2.11.0</version>
79-
</dependency>
8074

8175
<!-- Test Dependencies -->
8276
<dependency>
Lines changed: 107 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,108 @@
1-
@Bean
2-
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
3-
http
4-
// Add security headers
5-
.headers(headers -> headers
6-
.contentSecurityPolicy(csp -> csp
7-
.policyDirectives("default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'"))
8-
.referrerPolicy(referrer -> referrer
9-
.policy(org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER))
10-
.xssProtection(xss -> xss
11-
.block(true))
12-
.frameOptions(frame -> frame
13-
.deny())
14-
)
15-
16-
// Enable CORS with custom configuration
17-
.cors(Customizer.withDefaults())
18-
19-
// Disable CSRF (Cross-Site Request Forgery) protection.
20-
.csrf(csrf -> csrf.disable())
21-
22-
// Configure authorization rules for HTTP requests.
23-
.authorizeHttpRequests(authorize -> authorize
24-
.requestMatchers(
25-
"/", "/generate", "/api/generate", "/index",
26-
"/css/**", "/js/**", "/images/**",
27-
"/favicon.ico", "/favicon-16x16.png", "/favicon-32x32.png",
28-
"/apple-touch-icon.png", "/android-chrome-*.png",
29-
"/site.webmanifest", "/robots.txt",
30-
"/download/**"
31-
).permitAll()
32-
.requestMatchers(
33-
"/wp-admin/**", "/wordpress/**", "/wp-login.php"
34-
).denyAll()
35-
.anyRequest().authenticated()
36-
)
37-
38-
// Disable form-based login and HTTP Basic authentication
39-
.formLogin(formLogin -> formLogin.disable())
40-
.httpBasic(httpBasic -> httpBasic.disable())
41-
42-
// Configure session management to be stateless.
43-
.sessionManagement(session -> session
44-
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
45-
);
46-
47-
return http.build();
1+
package com.keyjolt.config;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.security.config.Customizer;
6+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
7+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
8+
import org.springframework.security.config.http.SessionCreationPolicy;
9+
import org.springframework.security.core.userdetails.User;
10+
import org.springframework.security.core.userdetails.UserDetails;
11+
import org.springframework.security.core.userdetails.UserDetailsService;
12+
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
13+
import org.springframework.security.crypto.password.PasswordEncoder;
14+
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
15+
import org.springframework.security.web.SecurityFilterChain;
16+
import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
17+
import org.springframework.web.cors.CorsConfiguration;
18+
import org.springframework.web.cors.CorsConfigurationSource;
19+
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
20+
21+
import java.util.List;
22+
23+
@Configuration // Indicates that this class contains Spring configuration
24+
@EnableWebSecurity // Enables Spring Security's web security support
25+
public class SecurityConfig {
26+
27+
// Bean for password encoding.
28+
@Bean
29+
public PasswordEncoder passwordEncoder() {
30+
return new BCryptPasswordEncoder();
31+
}
32+
33+
// Bean for configuring the security filter chain.
34+
@Bean
35+
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
36+
http
37+
// Enable CORS with custom configuration
38+
.cors(Customizer.withDefaults())
39+
40+
// Disable CSRF (Cross-Site Request Forgery) protection.
41+
.csrf(csrf -> csrf.disable())
42+
43+
// Configure authorization rules for HTTP requests.
44+
.authorizeHttpRequests(authorize -> authorize
45+
.requestMatchers(
46+
"/", "/generate", "/api/generate", "/index",
47+
"/css/**", "/js/**", "/images/**",
48+
"/favicon.ico", "/favicon-16x16.png", "/favicon-32x32.png",
49+
"/apple-touch-icon.png", "/android-chrome-*.png",
50+
"/site.webmanifest", "/robots.txt",
51+
"/download/**"
52+
).permitAll()
53+
.requestMatchers(
54+
"/wp-admin/**", "/wordpress/**", "/wp-login.php"
55+
).denyAll()
56+
.anyRequest().authenticated()
57+
)
58+
59+
// Disable form-based login and HTTP Basic authentication
60+
.formLogin(formLogin -> formLogin.disable())
61+
.httpBasic(httpBasic -> httpBasic.disable())
62+
63+
// Configure session management to be stateless.
64+
.sessionManagement(session -> session
65+
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
66+
)
67+
68+
// Add hardened security headers
69+
.headers(headers -> headers
70+
.httpStrictTransportSecurity(hsts -> hsts
71+
.includeSubDomains(true)
72+
.maxAgeInSeconds(31536000))
73+
.contentSecurityPolicy(csp -> csp
74+
.policyDirectives("default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'"))
75+
.referrerPolicy(referrer -> referrer
76+
.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER))
77+
.xssProtection(Customizer.withDefaults())
78+
);
79+
80+
return http.build();
81+
}
82+
83+
// Bean for an in-memory UserDetailsService.
84+
@Bean
85+
public UserDetailsService userDetailsService() {
86+
UserDetails adminUser = User.builder()
87+
.username("admin")
88+
.password(passwordEncoder().encode("admin123")) // Password must be encoded
89+
.roles("ADMIN") // Roles are automatically prefixed with "ROLE_"
90+
.build();
91+
92+
return new InMemoryUserDetailsManager(adminUser);
93+
}
94+
95+
// Bean for CORS configuration
96+
@Bean
97+
public CorsConfigurationSource corsConfigurationSource() {
98+
CorsConfiguration config = new CorsConfiguration();
99+
config.setAllowedOrigins(List.of("https://keyjolt.dev", "https://keyjolt.piapps.dev"));
100+
config.setAllowedMethods(List.of("GET", "POST"));
101+
config.setAllowedHeaders(List.of("*"));
102+
config.setAllowCredentials(true);
103+
104+
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
105+
source.registerCorsConfiguration("/**", config);
106+
return source;
107+
}
48108
}

src/main/java/com/keyjolt/util/FileUtils.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.keyjolt.util;
22

3-
import org.apache.commons.io.IOUtils;
43
import org.springframework.beans.factory.annotation.Value;
54
import org.springframework.stereotype.Component;
65
import org.slf4j.Logger;

0 commit comments

Comments
 (0)