Block POST requests from unknown origins
This commit is contained in:
@ -5,12 +5,14 @@ use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
||||
use actix_identity::RequestIdentity;
|
||||
use actix_web::{dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, Error, HttpResponse};
|
||||
use actix_web::{dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, Error, HttpResponse, web};
|
||||
use actix_web::body::EitherBody;
|
||||
use actix_web::http::{header, Method};
|
||||
use askama::Template;
|
||||
|
||||
use crate::constants::{ADMIN_ROUTES, AUTHENTICATED_ROUTES};
|
||||
use crate::controllers::base_controller::redirect_user_for_login;
|
||||
use crate::data::app_config::AppConfig;
|
||||
use crate::data::session_identity::{SessionIdentity, SessionIdentityData, SessionStatus};
|
||||
|
||||
// There are two steps in middleware processing.
|
||||
@ -83,6 +85,23 @@ impl<S, B> Service<ServiceRequest> for AuthInnerMiddleware<S>
|
||||
|
||||
// Forward request
|
||||
Box::pin(async move {
|
||||
let config: &web::Data<AppConfig> = req.app_data().expect("AppData undefined!");
|
||||
|
||||
// Check if POST request comes from another website (block invalid origins)
|
||||
let origin = req.headers().get(header::ORIGIN);
|
||||
if req.method() == Method::POST {
|
||||
if let Some(o) = origin {
|
||||
if !o.to_str().unwrap_or("bad").eq(&config.website_origin) {
|
||||
log::warn!("Blocked POST request from invalid origin! Origin given {:?}", o);
|
||||
return Ok(req.into_response(
|
||||
HttpResponse::Unauthorized()
|
||||
.body("POST request from invalid origin!")
|
||||
.map_into_right_body()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if req.path().starts_with("/.git") {
|
||||
return Ok(req.into_response(
|
||||
HttpResponse::Unauthorized()
|
||||
@ -91,14 +110,14 @@ impl<S, B> Service<ServiceRequest> for AuthInnerMiddleware<S>
|
||||
));
|
||||
}
|
||||
|
||||
let identity = match SessionIdentity::deserialize_session_data(req.get_identity()) {
|
||||
let session = match SessionIdentity::deserialize_session_data(req.get_identity()) {
|
||||
Some(SessionIdentityData { status: SessionStatus::SignedIn, is_admin: true, .. }) => ConnStatus::Admin,
|
||||
Some(SessionIdentityData { status: SessionStatus::SignedIn, .. }) => ConnStatus::RegularUser,
|
||||
_ => ConnStatus::SignedOut,
|
||||
};
|
||||
|
||||
// Redirect user to login page
|
||||
if !identity.is_auth() && (req.path().starts_with(ADMIN_ROUTES) ||
|
||||
if !session.is_auth() && (req.path().starts_with(ADMIN_ROUTES) ||
|
||||
req.path().starts_with(AUTHENTICATED_ROUTES)) {
|
||||
let path = req.path().to_string();
|
||||
return Ok(req.into_response(redirect_user_for_login(path))
|
||||
@ -106,7 +125,7 @@ impl<S, B> Service<ServiceRequest> for AuthInnerMiddleware<S>
|
||||
}
|
||||
|
||||
// Restrict access to admin pages
|
||||
if !identity.is_admin() && req.path().starts_with(ADMIN_ROUTES) {
|
||||
if !session.is_admin() && req.path().starts_with(ADMIN_ROUTES) {
|
||||
return Ok(req.into_response(HttpResponse::Unauthorized()
|
||||
.body(AccessDeniedTemplate {}.render().unwrap()))
|
||||
.map_into_right_body());
|
||||
|
Reference in New Issue
Block a user