Add csrf protection

This commit is contained in:
Trinity Pointard
2018-06-24 18:58:57 +02:00
parent 3bc90e71d4
commit 30e9620d0a
10 changed files with 135 additions and 13 deletions
+13 -1
View File
@@ -12,6 +12,7 @@ extern crate plume_common;
extern crate plume_models;
extern crate rocket;
extern crate rocket_contrib;
extern crate rocket_csrf;
extern crate rocket_i18n;
extern crate rpassword;
#[macro_use]
@@ -19,6 +20,7 @@ extern crate serde_json;
extern crate webfinger;
use rocket_contrib::Template;
use rocket_csrf::CsrfFairingBuilder;
mod inbox;
mod setup;
@@ -84,7 +86,9 @@ fn main() {
routes::well_known::host_meta,
routes::well_known::nodeinfo,
routes::well_known::webfinger
routes::well_known::webfinger,
routes::errors::csrf_violation
])
.catch(catchers![
routes::errors::not_found,
@@ -95,5 +99,13 @@ fn main() {
rocket_i18n::tera(&mut engines.tera);
}))
.attach(rocket_i18n::I18n::new("plume"))
.attach(CsrfFairingBuilder::new()
.set_default_target("/csrf-violation?target=<uri>".to_owned(), rocket::http::Method::Post)
.add_exceptions(vec![
("/inbox".to_owned(), "/inbox".to_owned(), rocket::http::Method::Post),
("/@/<name>/inbox".to_owned(), "/@/<name>/inbox".to_owned(), rocket::http::Method::Post),
])
.finalize().unwrap())
.launch();
}
+2 -2
View File
@@ -1,6 +1,6 @@
use activitypub::collection::OrderedCollection;
use rocket::{
request::Form,
request::LenientForm,
response::{Redirect, Flash}
};
use rocket_contrib::Template;
@@ -55,7 +55,7 @@ struct NewBlogForm {
}
#[post("/blogs/new", data = "<data>")]
fn create(conn: DbConn, data: Form<NewBlogForm>, user: User) -> Redirect {
fn create(conn: DbConn, data: LenientForm<NewBlogForm>, user: User) -> Redirect {
let form = data.get();
let slug = utils::make_actor_id(form.title.to_string());
+3 -3
View File
@@ -1,5 +1,5 @@
use rocket::{
request::Form,
request::LenientForm,
response::Redirect
};
use serde_json;
@@ -27,12 +27,12 @@ struct NewCommentForm {
// See: https://github.com/SergioBenitez/Rocket/pull/454
#[post("/~/<blog_name>/<slug>/comment", data = "<data>")]
fn create(blog_name: String, slug: String, data: Form<NewCommentForm>, user: User, conn: DbConn) -> Redirect {
fn create(blog_name: String, slug: String, data: LenientForm<NewCommentForm>, user: User, conn: DbConn) -> Redirect {
create_response(blog_name, slug, None, data, user, conn)
}
#[post("/~/<blog_name>/<slug>/comment?<query>", data = "<data>")]
fn create_response(blog_name: String, slug: String, query: Option<CommentQuery>, data: Form<NewCommentForm>, user: User, conn: DbConn) -> Redirect {
fn create_response(blog_name: String, slug: String, query: Option<CommentQuery>, data: LenientForm<NewCommentForm>, user: User, conn: DbConn) -> Redirect {
let blog = Blog::find_by_fqn(&*conn, blog_name.clone()).unwrap();
let post = Post::find_by_slug(&*conn, slug.clone(), blog.id).unwrap();
let form = data.get();
+15
View File
@@ -20,3 +20,18 @@ fn server_error(req: &Request) -> Template {
"account": user
}))
}
#[derive(FromForm)]
pub struct Uri {
target: String,
}
#[post("/csrf-violation?<uri>")]
fn csrf_violation(uri: Option<Uri>) -> Template {
if let Some(uri) = uri {
eprintln!("Csrf violation while acceding \"{}\"", uri.target)
}
Template::render("errors/csrf", json!({
"error_message":""
}))
}
+2 -2
View File
@@ -1,6 +1,6 @@
use activitypub::object::Article;
use heck::KebabCase;
use rocket::request::Form;
use rocket::request::LenientForm;
use rocket::response::{Redirect, Flash};
use rocket_contrib::Template;
use serde_json;
@@ -85,7 +85,7 @@ struct NewPostForm {
}
#[post("/~/<blog_name>/new", data = "<data>")]
fn create(blog_name: String, data: Form<NewPostForm>, user: User, conn: DbConn) -> Redirect {
fn create(blog_name: String, data: LenientForm<NewPostForm>, user: User, conn: DbConn) -> Redirect {
let blog = Blog::find_by_fqn(&*conn, blog_name.to_string()).unwrap();
let form = data.get();
let slug = form.title.to_string().to_kebab_case();
+2 -2
View File
@@ -2,7 +2,7 @@ use gettextrs::gettext;
use rocket::{
http::{Cookie, Cookies, uri::Uri},
response::{Redirect, status::NotFound},
request::{Form,FlashMessage}
request::{LenientForm,FlashMessage}
};
use rocket_contrib::Template;
@@ -39,7 +39,7 @@ struct LoginForm {
}
#[post("/login", data = "<data>")]
fn create(conn: DbConn, data: Form<LoginForm>, flash: Option<FlashMessage>, mut cookies: Cookies) -> Result<Redirect, NotFound<String>> {
fn create(conn: DbConn, data: LenientForm<LoginForm>, flash: Option<FlashMessage>, mut cookies: Cookies) -> Result<Redirect, NotFound<String>> {
let form = data.get();
let user = match User::find_by_email(&*conn, form.email_or_name.to_string()) {
Some(usr) => Ok(usr),
+3 -3
View File
@@ -2,7 +2,7 @@ use activitypub::{
activity::Follow,
collection::OrderedCollection
};
use rocket::{request::Form,
use rocket::{request::LenientForm,
response::{Redirect, Flash}
};
use rocket_contrib::Template;
@@ -148,7 +148,7 @@ struct UpdateUserForm {
}
#[put("/@/<_name>/edit", data = "<data>")]
fn update(_name: String, conn: DbConn, user: User, data: Form<UpdateUserForm>) -> Redirect {
fn update(_name: String, conn: DbConn, user: User, data: LenientForm<UpdateUserForm>) -> Redirect {
user.update(&*conn,
data.get().display_name.clone().unwrap_or(user.display_name.to_string()).to_string(),
data.get().email.clone().unwrap_or(user.email.clone().unwrap()).to_string(),
@@ -166,7 +166,7 @@ struct NewUserForm {
}
#[post("/users/new", data = "<data>")]
fn create(conn: DbConn, data: Form<NewUserForm>) -> Result<Redirect, String> {
fn create(conn: DbConn, data: LenientForm<NewUserForm>) -> Result<Redirect, String> {
let form = data.get();
if form.username.clone().len() < 1 {