class SpringSecurityTagger

Overview

Spring-specific security tagger.

spring_auth already classifies authentication/authorization (@PreAuthorize/@Secured/@RolesAllowed annotations and HttpSecurity URL rules). This tagger covers the other Spring security signals a reviewer cares about — the protections Spring ships and the deviations from its secure defaults — that map cleanly onto an endpoint:

CSRF / security-headers / config CORS are detected from the security, MVC, and WebSocket config (pre-scanned once, like spring_auth's URL rules). The @CrossOrigin and input-validation signals are per-endpoint, line-based walks of the handler the endpoint maps to. Cross-file concerns (a custom Filter bean, a bespoke CorsConfigurationSource) are out of scope.

Defined in:

tagger/framework_taggers/java/spring_security.cr

Constant Summary

CSRF_DISABLE = /csrf\s*(?:\(\s*\)\s*\.\s*disable\b|\([^)]*\bdisable|\{[^}]*\bdisable)/

csrf().disable() (fluent), csrf(csrf -> csrf.disable()) / csrf(AbstractHttpConfigurer::disable) (lambda/method-ref), and Kotlin csrf { disable() }. Whole-chain disable.

FRAME_OPTIONS_DISABLE = /frameOptions\s*(?:\(\s*\)\s*\.\s*disable\b|\([^)]*\bdisable|\{[^}]*\bdisable)/

Clickjacking protection off: frameOptions().disable(), frameOptions(f -> f.disable()), Kotlin frameOptions { disable() }.

HEADERS_FULLY_DISABLED = /headers\s*(?:\(\s*\)\s*\.\s*disable\b|\([^)]*::\s*disable)/

Whole default header writer off. Restricted to the unambiguous forms — empty-paren fluent headers().disable() and the method-ref headers(HeadersConfigurer::disable) — so a nested per-header disable such as headers(h -> h.frameOptions(f -> f.disable())) is NOT mistaken for an all-headers-off (that one is caught by FRAME_OPTIONS_DISABLE).

IGNORING_ARGS = /(?:ignoringRequestMatchers|ignoringAntMatchers)\s*\(([^;]*?)\)/

ignoringRequestMatchers(...) / ignoringAntMatchers(...) — CSRF kept on for the chain but skipped for these (absolute) path patterns. Captured across line breaks: the arg group stops at the statement's ;, never crossing into the next statement. The inner quote scan pulls the path literal even when wrapped (e.g. new AntPathRequestMatcher("/api")).

MATCHER_CALL = /\b(?:securityMatcher|antMatcher)\s*\(/

Chain-level request matchers that scope a SecurityFilterChain to a URL subset. requestMatchers(...) is deliberately excluded: inside authorizeHttpRequests {…} it scopes an authorization rule, not the chain, and treating those as CSRF scopes would mis-attribute the rule.

SCOPE_BOUNDARY = /SecurityFilterChain\b|configure\s*\(\s*(?:final\s+)?HttpSecurity/

A SecurityFilterChain bean / WebSecurityConfigurerAdapter.configure body delimits one HttpSecurity scope. A CSRF-disable and any chain-level securityMatcher are associated within the same scope/block.

STATE_CHANGING_METHODS = Set {"POST", "PUT", "PATCH", "DELETE"}

Constructors

Class Method Summary

Instance Method Summary

Instance methods inherited from class FrameworkTagger

collect_files_by_extension(extension : String) : Array(String) collect_files_by_extension, read_file(path : String) : String | Nil read_file, read_source_context(endpoint : Endpoint) : Array(SourceContext) read_source_context, static_asset_route?(url : String) : Bool static_asset_route?

Constructor methods inherited from class FrameworkTagger

new(options : Hash(String, YAML::Any)) new

Class methods inherited from class FrameworkTagger

target_techs : Array(String) target_techs

Instance methods inherited from module FileHelper

all_files : Array(String) all_files, get_files_by_extension(extension : String) : Array(String) get_files_by_extension, get_files_by_prefix(prefix : String) : Array(String) get_files_by_prefix, get_files_by_prefix_and_extension(prefix : String, extension : String) : Array(String) get_files_by_prefix_and_extension, get_public_dir_files(base_path : String, folder : String) : Array(String) get_public_dir_files, get_public_files(base_path : String, anchors : Array(String) = ["shard.yml", "Gemfile"]) : Array(String) get_public_files

Instance methods inherited from class Tagger

name : String name, perform(endpoints : Array(Endpoint)) : Array(Endpoint) perform

Constructor methods inherited from class Tagger

new(options : Hash(String, YAML::Any)) new

Constructor Detail

def self.new(options : Hash(String, YAML::Any)) #

[View source]

Class Method Detail

def self.target_techs : Array(String) #

[View source]

Instance Method Detail

def perform(endpoints : Array(Endpoint)) : Array(Endpoint) #

[View source]