Skip to content

Conversation

@dev-ricks
Copy link
Owner

@dev-ricks dev-ricks commented Nov 13, 2025

Add HSTS header.
Added/refactored basic security standards.


Note

Adds configurable HSTS and stricter RBAC, introduces partial-update validation, scaffolds rate limiting with Bucket4j and extensive tests, and updates security docs/config.

  • Security:
    • HSTS: Injects Strict-Transport-Security via SecurityConfig with HstsProperties; adds prod/dev/insecure request tests.
    • RBAC: Restricts "/actuator/**" to ROLE_ADMIN, protects API routes, permits public/docs; adds @PreAuthorize on controllers; conditional OAuth2 resource server.
    • Validation: Adds @AtLeastOneFieldNotNull and new *UpdateRequest DTOs for partial updates.
  • Rate Limiting:
    • Adds bucket4j-core dependency; introduces prototype services/filter (TokenBucketService, RateLimitService, RateLimitFilter) with comprehensive unit/integration tests.
  • Config:
    • Externalizes DB creds in application.yml using env vars.
  • Tests:
    • Updates controller tests/ITs to use JWT-based auth and authorization paths; adds security header and auth ITs.
  • Docs:
    • Adds docs/security/SECURITY_HARDENING_PLAN.md and SECURITY_TRACKING.md for phased hardening and tracking.

Written by Cursor Bugbot for commit 039972a. This will update automatically on new commits. Configure here.

add comprehensive security documentation including architecture, data flow, and incident response plans
A beginning set of tests to drive the phase1 requirements for TDD use.

Git: NA
Modified security configuration to have roles considered for API user access.  Made modifications to code to get the first set of phase1 tdd tests to run.  Also had to make some changes to the tests since I am using the Oauth package to how to mock out the users and roles for the tests.

Git: NA
Created TokenBucketService that will be the go-between for token buckets that are going to be used for rate limiting.  Started with a prototype and then converted into bucket4j.

Git: NA
Added preliminary tests to prove out a design.  Added some expected classes for rate limiting to allow for compile but not impl yet. Updated to latest spring boot web version.

Git: NA
…o_security_standards' into security/phase1_foundation

# Conflicts:
#	.idea/.gitignore
#	docs/security/SECURITY_IMPLEMENTATION_PLAN.md
Feature adds HSTS transport security.

Closes: SEC-P1-01
Feature adds HSTS transport security.

Closes: SEC-P1-01
@dev-ricks dev-ricks self-assigned this Nov 13, 2025
@dev-ricks dev-ricks added the enhancement New feature or request label Nov 13, 2025
@dev-ricks dev-ricks merged commit 92277de into main Nov 13, 2025
1 of 2 checks passed
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

.anyRequest().authenticated())
.oauth2ResourceServer(oauth2 -> oauth2.jwt(
Customizer.withDefaults()));
.requestMatchers("/actuator/health", "/actuator/health/**", "/actuator/info", "/actuator/**").hasRole("ADMIN")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Actuator Health: Authentication Breaks Expected Access

The actuator endpoints now require ADMIN role, but the comment still says "Permits unauthenticated access to basic Actuator endpoints for health/info". This creates a critical security misconfiguration where health checks requiring authentication will break monitoring systems and load balancers that expect unauthenticated access to /actuator/health.

Fix in Cursor Fix in Web

}
resp.setHeader(SecurityConfig.STRICT_TRANSPORT_SECURITY_HEADER, value.toString());
} else if (resp.getHeader(SecurityConfig.STRICT_TRANSPORT_SECURITY_HEADER) != null) {
resp.setHeader(SecurityConfig.STRICT_TRANSPORT_SECURITY_HEADER, "");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Header Null: An Unnecessary Risk

Setting a header to empty string and then to null is redundant and incorrect. The setHeader method with null value may throw NullPointerException or have undefined behavior depending on the servlet container. To remove a header, only one call is needed, and passing null is not the correct approach.

Fix in Cursor Fix in Web


public RateLimitResult tryConsume(String key) {
return null;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Rate Limiter Null Reference Causes App Crash

The tryConsume method returns null, which will cause NullPointerException when the rate limit filter attempts to call methods like isAllowed() on the result. This stub implementation is incomplete and will crash the application if rate limiting is enabled.

Fix in Cursor Fix in Web


public RateLimitFilter(RateLimitService service) {

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Uninitialized service field causes null pointer.

The constructor accepts a RateLimitService parameter but never assigns it to the rateLimitService field. This leaves the field uninitialized as null, which will cause NullPointerException when doFilterInternal attempts to use it.

Fix in Cursor Fix in Web

username: postgres
password: postgres
username: ${DB_USERNAME:postgres}
password: ${DB_PASSWORD:}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Database Password Default: Security Vulnerability

The database password defaults to an empty string when DB_PASSWORD environment variable is not set. This allows the application to connect to PostgreSQL with no password, which is a security vulnerability. The application should fail to start if the password is not provided rather than defaulting to an insecure empty value.

Fix in Cursor Fix in Web

resp.setHeader(SecurityConfig.STRICT_TRANSPORT_SECURITY_HEADER, "");
resp.setHeader(SecurityConfig.STRICT_TRANSPORT_SECURITY_HEADER, null);
}
}, org.springframework.security.web.access.intercept.AuthorizationFilter.class);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: HSTS Header Security Gap

The HSTS filter calls chain.doFilter() before adding the header, but the filter is added after AuthorizationFilter. If authorization fails and returns a 403/401 response, the filter chain may not complete normally, potentially preventing the HSTS header from being added to error responses. The header should be set before calling chain.doFilter() or the filter should be positioned differently.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants