class RustSecurityTagger
- RustSecurityTagger
- FrameworkTagger
- Tagger
- Reference
- Object
Overview
Rust-specific security tagger.
rust_auth already classifies authentication (request guards,
extractors, auth middleware), so this tagger covers the other
framework-level security protections that a reviewer wants to know
are (or are not) in front of an endpoint. Each protection maps onto a
tag whose description says whether the configuration is hardened or a
risk:
- cors — CORS middleware. Permissive configs (any origin, wildcard) are flagged as a risk; restricted allow-lists are recorded as informational.
- rate-limit — request throttling (actix-governor / tower_governor / actix-limitation / tower limit).
- security-headers — hardening response headers (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, …).
- body-limit — request body size cap (DoS mitigation). A disabled limit is flagged as a risk.
Detection is two-pronged:
-
Source middleware — every
.rsfile is pre-scanned for the builder calls above. The enclosing Actixweb::scope("/x")(if any) gives the URL prefix the protection applies to; app-wide middleware (App::new().wrap(..),Router::new().layer(..)) maps to/so it tags every endpoint. Test modules (#[cfg(test)]) andtests//benches//examples/files are skipped so test-only middleware can't taint real endpoints. -
Loco config — Loco wires its middleware in
config/*.yaml(middlewares: { cors:, limit_payload:, secure_headers: }) rather than in code, so those files are parsed too and applied app-wide.
Scope mapping errs toward false negatives (a too-narrow prefix tags fewer endpoints) rather than false positives, in keeping with the rest of Noir's tagging.
Defined in:
tagger/framework_taggers/rust/rust_security.crConstant Summary
-
BODY_LIMIT_DISABLED_PATTERNS =
[{/DefaultBodyLimit::disable\s*\(/, "DefaultBodyLimit::disable()"}] -
--- Request body size limit ----------------------------------------
-
BODY_LIMIT_PATTERNS =
[{/DefaultBodyLimit::max\s*\(/, "axum DefaultBodyLimit"}, {/\bDefaultBodyLimit\b/, "axum DefaultBodyLimit"}, {/\bRequestBodyLimitLayer\b/, "tower-http RequestBodyLimitLayer"}, {/\bPayloadConfig\b/, "actix PayloadConfig"}, {/\b(?:Json|Form|Payload)Config\b[^=]*\.limit\s*\(/, "actix config limit"}] -
CORS_PERMISSIVE_PATTERNS =
[{/Cors::permissive\s*\(/, "Cors::permissive()"}, {/CorsLayer::permissive\s*\(/, "CorsLayer::permissive()"}, {/CorsLayer::very_permissive\s*\(/, "CorsLayer::very_permissive()"}, {/\.allow_any_origin\s*\(/, ".allow_any_origin()"}, {/\.send_wildcard\s*\(/, ".send_wildcard()"}, {/\.allow_origin\s*\(\s*Any\b/, ".allow_origin(Any)"}, {/\.allowed_origin\s*\(\s*"\*"/, "allowed_origin(\"*\")"}] -
--- CORS ----------------------------------------------------------- Permissive: any origin is accepted. The classic finding.
-
CORS_PRESENT_PATTERNS =
[{/Cors::default\s*\(/, "actix-cors"}, {/CorsLayer::new\s*\(/, "tower-http CorsLayer"}, {/\.allowed_origin\s*\(/, "actix-cors allow-list"}, {/\.allow_origin\s*\(/, "tower-http allow-list"}, {/\bCorsOptions\b/, "rocket-cors"}] -
Configured (restricted) CORS — present but not wide open.
-
RATE_LIMIT_PATTERNS =
[{/\.(?:wrap|layer|route_layer|attach)\s*\(\s*&?\s*[\w:]*Governor\b/, "governor"}, {/\bGovernorLayer\b/, "tower_governor"}, {/\bRateLimitLayer\b/, "tower RateLimitLayer"}, {/\.(?:wrap|layer)\s*\(\s*&?\s*[\w:]*RateLimiter\b/, "rate limiter"}, {/\bactix_limitation\b/, "actix-limitation"}] -
--- Rate limiting -------------------------------------------------- Match the application of a limiter (
.wrap/.layer) or a Layer type that is only ever applied — never a bareGovernorConfigBuildervalue, which is config and would mis-map an app-wide tag onto every endpoint even when the limiter is wrapped onto one scope. -
SECURITY_HEADER_PATTERNS =
[{/"[Ss]trict-[Tt]ransport-[Ss]ecurity"|\bSTRICT_TRANSPORT_SECURITY\b/, "Strict-Transport-Security (HSTS)"}, {/"[Cc]ontent-[Ss]ecurity-[Pp]olicy"|\bCONTENT_SECURITY_POLICY\b/, "Content-Security-Policy"}, {/"[Xx]-[Ff]rame-[Oo]ptions"|\bX_FRAME_OPTIONS\b/, "X-Frame-Options"}, {/"[Xx]-[Cc]ontent-[Tt]ype-[Oo]ptions"|\bX_CONTENT_TYPE_OPTIONS\b/, "X-Content-Type-Options"}, {/"[Rr]eferrer-[Pp]olicy"|\bREFERRER_POLICY\b/, "Referrer-Policy"}, {/"[Pp]ermissions-[Pp]olicy"|\bPERMISSIONS_POLICY\b/, "Permissions-Policy"}] -
--- Security response headers -------------------------------------- The header name — as a quoted literal (
"X-Frame-Options") or thehttpcrate'sHeaderNameconstant (X_FRAME_OPTIONS) — is a strong signal the app sets it (request-side reads of these are rare). Framework-agnostic: works for ActixDefaultHeaders, tower-httpSetResponseHeaderLayer, and helmet-style crates alike.
Constructors
Class Method Summary
-
.target_techs : Array(String)
Kept in lock-step with
rust_auth(the guard-support invariant in techs_spec requires every framework-tagger target to be a guard-supported tech, which currently excludes Salvo/Poem).
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
Class Method Detail
Kept in lock-step with rust_auth (the guard-support invariant in
techs_spec requires every framework-tagger target to be a
guard-supported tech, which currently excludes Salvo/Poem).