Loading...
Loading...
OWASP Security Checklist
npx skill4agent add leavesfly/jimi security-checklist@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin/users")
public List<User> getUsers() {
return userService.findAll();
}// Use BCrypt to encrypt password
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String hashedPassword = encoder.encode(rawPassword);// ❌ Unsafe
String query = "SELECT * FROM users WHERE username = '" + username + "'";
// ✓ Safe: Use parameterized queries
String query = "SELECT * FROM users WHERE username = ?";
PreparedStatement stmt = conn.prepareStatement(query);
stmt.setString(1, username);// ✓ Use parameter binding
Query query = new Query(Criteria.where("username").is(username));// ❌ Unsafe
Runtime.getRuntime().exec("ls " + userInput);
// ✓ Safe: Validate and escape
if (userInput.matches("[a-zA-Z0-9]+")) {
ProcessBuilder pb = new ProcessBuilder("ls", userInput);
pb.start();
}# application.yml
server:
error:
include-stacktrace: never # Do not expose stack trace in production
spring:
devtools:
restart:
enabled: false # Disable devtools in production# Maven dependency check
mvn dependency:tree
mvn versions:display-dependency-updates
# OWASP Dependency Check
mvn org.owasp:dependency-check-maven:check// Session configuration
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.maximumSessions(1)
.maxSessionsPreventsLogin(true);
return http.build();
}// ❌ Insecure deserialization
ObjectInputStream ois = new ObjectInputStream(inputStream);
Object obj = ois.readObject();
// ✓ Use secure formats like JSON
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);log.warn("Failed login attempt: user={}, ip={}",
username, request.getRemoteAddr());
log.info("Password changed: user={}, timestamp={}",
username, System.currentTimeMillis());// ✓ URL validation
private boolean isAllowedUrl(String url) {
try {
URL u = new URL(url);
String host = u.getHost();
return ALLOWED_HOSTS.contains(host);
} catch (MalformedURLException e) {
return false;
}
}// Output escaping
String safe = HtmlUtils.htmlEscape(userInput);
// Content Security Policy
response.setHeader("Content-Security-Policy",
"default-src 'self'; script-src 'self' 'unsafe-inline'");// Spring Security enables CSRF automatically
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());// X-Frame-Options
response.setHeader("X-Frame-Options", "DENY");X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'# application.yml
spring:
datasource:
password: ${DB_PASSWORD} # Read from environment variables