pub struct CsrfOrigin { /* private fields */ }Expand description
Rejects cross-site state-changing requests by checking their origin.
Browsers attach cookies to requests a hostile page triggers, so a route
that authenticates with cookies (or HTTP Basic) needs this check. For
every method except GET, HEAD, OPTIONS and TRACE:
Sec-Fetch-Site: cross-siteis rejected, even whenOriginwould match;Sec-Fetch-Site: same-originis accepted.- Otherwise
Originmust equal one of the configured origins. WhenOriginis absent the origin ofRefereris used instead. Origin: null, a missingOriginandReferer, repeated headers and any other origin are rejected.
A rejection is one generic 403 problem that does not say which check
failed. The allowed origins are configuration only: they are never
derived from Host or X-Forwarded-*, which a client can choose.
use siderite_core::middleware::CsrfOrigin;
let csrf = CsrfOrigin::new(["https://app.example.com"])?
.exempt("/webhooks/");Implementations§
Source§impl CsrfOrigin
impl CsrfOrigin
Sourcepub fn new<I, S>(origins: I) -> Result<Self, CsrfOriginError>
pub fn new<I, S>(origins: I) -> Result<Self, CsrfOriginError>
Allow the given exact origins.
Each origin is scheme://host[:port] with an http or https
scheme and no path, query, fragment or user info. It is lowercased
and a default port (80 for http, 443 for https) is removed, so
HTTPS://App.Example.com:443 equals https://app.example.com.
§Errors
CsrfOriginError for the first origin that does not parse.
Sourcepub fn exempt(self, prefix: impl Into<String>) -> Self
pub fn exempt(self, prefix: impl Into<String>) -> Self
Skip the check for paths under prefix, for example a webhook.
The prefix matches whole path segments: /hooks covers /hooks
and /hooks/x but not /hooksy. A prefix not starting with /
never matches, and paths with . or .. segments are never
exempt. Exempt routes must authenticate callers some other way, for
example by verifying a signature.
Check only requests that carry ambient credentials (default off).
When on, a request with no Cookie header and no
Authorization: Basic is not checked. That suits APIs that accept
both bearer tokens and cookies. The trade-off: a request that
arrives without credentials is passed to the handler, so every
route behind this setting must reject anonymous state changes
itself, and any other credential a browser sends by itself would
bypass the check.
Trait Implementations§
Source§impl Clone for CsrfOrigin
impl Clone for CsrfOrigin
Source§fn clone(&self) -> CsrfOrigin
fn clone(&self) -> CsrfOrigin
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for CsrfOrigin
impl Debug for CsrfOrigin
Source§impl Layer<BoxCloneSyncService<Request<Body>, Response<Body>, Infallible>> for CsrfOrigin
impl Layer<BoxCloneSyncService<Request<Body>, Response<Body>, Infallible>> for CsrfOrigin
Source§type Service = BoxCloneSyncService<Request<Body>, Response<Body>, Infallible>
type Service = BoxCloneSyncService<Request<Body>, Response<Body>, Infallible>
Source§fn layer(&self, inner: BoxService) -> Self::Service
fn layer(&self, inner: BoxService) -> Self::Service
Auto Trait Implementations§
impl Freeze for CsrfOrigin
impl RefUnwindSafe for CsrfOrigin
impl Send for CsrfOrigin
impl Sync for CsrfOrigin
impl Unpin for CsrfOrigin
impl UnsafeUnpin for CsrfOrigin
impl UnwindSafe for CsrfOrigin
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
§impl<T> ServiceExt for T
impl<T> ServiceExt for T
§fn compression(self) -> Compression<Self>where
Self: Sized,
fn compression(self) -> Compression<Self>where
Self: Sized,
§fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
§fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
§fn override_request_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
fn override_request_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
§fn append_request_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
fn append_request_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
§fn insert_request_header_if_not_present<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
fn insert_request_header_if_not_present<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
§fn override_response_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
fn override_response_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
§fn append_response_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
fn append_response_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
§fn insert_response_header_if_not_present<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
fn insert_response_header_if_not_present<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
§fn set_request_id<M>(
self,
header_name: HeaderName,
make_request_id: M,
) -> SetRequestId<Self, M>where
Self: Sized,
M: MakeRequestId,
fn set_request_id<M>(
self,
header_name: HeaderName,
make_request_id: M,
) -> SetRequestId<Self, M>where
Self: Sized,
M: MakeRequestId,
§fn set_x_request_id<M>(self, make_request_id: M) -> SetRequestId<Self, M>where
Self: Sized,
M: MakeRequestId,
fn set_x_request_id<M>(self, make_request_id: M) -> SetRequestId<Self, M>where
Self: Sized,
M: MakeRequestId,
x-request-id as the header name. Read more§fn propagate_request_id(
self,
header_name: HeaderName,
) -> PropagateRequestId<Self>where
Self: Sized,
fn propagate_request_id(
self,
header_name: HeaderName,
) -> PropagateRequestId<Self>where
Self: Sized,
§fn propagate_x_request_id(self) -> PropagateRequestId<Self>where
Self: Sized,
fn propagate_x_request_id(self) -> PropagateRequestId<Self>where
Self: Sized,
x-request-id as the header name. Read more§fn request_body_limit(self, limit: usize) -> RequestBodyLimit<Self>where
Self: Sized,
fn request_body_limit(self, limit: usize) -> RequestBodyLimit<Self>where
Self: Sized,
413 Payload Too Large responses. Read more