mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-10-01 01:36:12 -04:00
* Only sanitize strings when generating RSS feeds and emails (fixes #4003) * clippy * fix test
This commit is contained in:
parent
6d7b38f4de
commit
291ff19718
@ -554,29 +554,3 @@ test("Report a post", async () => {
|
||||
expect(betaReport.original_post_body).toBe(alphaReport.original_post_body);
|
||||
expect(betaReport.reason).toBe(alphaReport.reason);
|
||||
});
|
||||
|
||||
test("Sanitize HTML", async () => {
|
||||
let betaCommunity = (await resolveBetaCommunity(beta)).community;
|
||||
if (!betaCommunity) {
|
||||
throw "Missing beta community";
|
||||
}
|
||||
|
||||
let name = randomString(5);
|
||||
let body = "<script>alert('xss');</script> hello &\"'";
|
||||
let form: CreatePost = {
|
||||
name,
|
||||
body,
|
||||
community_id: betaCommunity.community.id,
|
||||
};
|
||||
let post = await beta.createPost(form);
|
||||
// first escaping for the api
|
||||
expect(post.post_view.post.body).toBe(
|
||||
"<script>alert('xss');</script> hello &"'",
|
||||
);
|
||||
|
||||
let alphaPost = (await resolvePost(alpha, post.post_view.post)).post;
|
||||
// second escaping over federation, avoid double escape of &
|
||||
expect(alphaPost?.post.body).toBe(
|
||||
"<script>alert('xss');</script> hello &"'",
|
||||
);
|
||||
});
|
||||
|
@ -5,7 +5,7 @@ use lemmy_api_common::{
|
||||
comment::{CommentReportResponse, CreateCommentReport},
|
||||
context::LemmyContext,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{check_community_ban, sanitize_html_api, send_new_report_email_to_admins},
|
||||
utils::{check_community_ban, send_new_report_email_to_admins},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -26,7 +26,7 @@ pub async fn create_comment_report(
|
||||
) -> Result<Json<CommentReportResponse>, LemmyError> {
|
||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||
|
||||
let reason = sanitize_html_api(data.reason.trim());
|
||||
let reason = data.reason.trim().to_string();
|
||||
check_report_reason(&reason, &local_site)?;
|
||||
|
||||
let person_id = local_user_view.person.id;
|
||||
|
@ -4,7 +4,7 @@ use lemmy_api_common::{
|
||||
community::{BanFromCommunity, BanFromCommunityResponse},
|
||||
context::LemmyContext,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{is_mod_or_admin, remove_user_data_in_community, sanitize_html_api_opt},
|
||||
utils::{is_mod_or_admin, remove_user_data_in_community},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -81,7 +81,7 @@ pub async fn ban_from_community(
|
||||
mod_person_id: local_user_view.person.id,
|
||||
other_person_id: data.person_id,
|
||||
community_id: data.community_id,
|
||||
reason: sanitize_html_api_opt(&data.reason),
|
||||
reason: data.reason.clone(),
|
||||
banned: Some(data.ban),
|
||||
expires,
|
||||
};
|
||||
|
@ -5,7 +5,7 @@ use lemmy_api_common::{
|
||||
community::{CommunityResponse, HideCommunity},
|
||||
context::LemmyContext,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{is_admin, sanitize_html_api_opt},
|
||||
utils::is_admin,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -34,7 +34,7 @@ pub async fn hide_community(
|
||||
let mod_hide_community_form = ModHideCommunityForm {
|
||||
community_id: data.community_id,
|
||||
mod_person_id: local_user_view.person.id,
|
||||
reason: sanitize_html_api_opt(&data.reason),
|
||||
reason: data.reason.clone(),
|
||||
hidden: Some(data.hidden),
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@ use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
person::{BanPerson, BanPersonResponse},
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{is_admin, remove_user_data, sanitize_html_api_opt},
|
||||
utils::{is_admin, remove_user_data},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -61,7 +61,7 @@ pub async fn ban_from_site(
|
||||
let form = ModBanForm {
|
||||
mod_person_id: local_user_view.person.id,
|
||||
other_person_id: data.person_id,
|
||||
reason: sanitize_html_api_opt(&data.reason),
|
||||
reason: data.reason.clone(),
|
||||
banned: Some(data.ban),
|
||||
expires,
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ use actix_web::web::{Data, Json};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
person::SaveUserSettings,
|
||||
utils::{sanitize_html_api_opt, send_verification_email},
|
||||
utils::send_verification_email,
|
||||
SuccessResponse,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
@ -28,13 +28,10 @@ pub async fn save_user_settings(
|
||||
) -> Result<Json<SuccessResponse>, LemmyError> {
|
||||
let site_view = SiteView::read_local(&mut context.pool()).await?;
|
||||
|
||||
let bio = sanitize_html_api_opt(&data.bio);
|
||||
let display_name = sanitize_html_api_opt(&data.display_name);
|
||||
|
||||
let avatar = diesel_option_overwrite_to_url(&data.avatar)?;
|
||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||
let bio = diesel_option_overwrite(bio);
|
||||
let display_name = diesel_option_overwrite(display_name);
|
||||
let bio = diesel_option_overwrite(data.bio.clone());
|
||||
let display_name = diesel_option_overwrite(data.display_name.clone());
|
||||
let matrix_user_id = diesel_option_overwrite(data.matrix_user_id.clone());
|
||||
let email_deref = data.email.as_deref().map(str::to_lowercase);
|
||||
let email = diesel_option_overwrite(email_deref.clone());
|
||||
@ -82,7 +79,6 @@ pub async fn save_user_settings(
|
||||
let person_id = local_user_view.person.id;
|
||||
let default_listing_type = data.default_listing_type;
|
||||
let default_sort_type = data.default_sort_type;
|
||||
let theme = sanitize_html_api_opt(&data.theme);
|
||||
|
||||
let person_form = PersonUpdateForm {
|
||||
display_name,
|
||||
@ -114,7 +110,7 @@ pub async fn save_user_settings(
|
||||
show_scores: data.show_scores,
|
||||
default_sort_type,
|
||||
default_listing_type,
|
||||
theme,
|
||||
theme: data.theme.clone(),
|
||||
interface_language: data.interface_language.clone(),
|
||||
open_links_in_new_tab: data.open_links_in_new_tab,
|
||||
infinite_scroll_enabled: data.infinite_scroll_enabled,
|
||||
|
@ -5,7 +5,7 @@ use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
post::{CreatePostReport, PostReportResponse},
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{check_community_ban, sanitize_html_api, send_new_report_email_to_admins},
|
||||
utils::{check_community_ban, send_new_report_email_to_admins},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -26,7 +26,7 @@ pub async fn create_post_report(
|
||||
) -> Result<Json<PostReportResponse>, LemmyError> {
|
||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||
|
||||
let reason = sanitize_html_api(data.reason.trim());
|
||||
let reason = data.reason.trim().to_string();
|
||||
check_report_reason(&reason, &local_site)?;
|
||||
|
||||
let person_id = local_user_view.person.id;
|
||||
|
@ -3,7 +3,7 @@ use actix_web::web::{Data, Json};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
private_message::{CreatePrivateMessageReport, PrivateMessageReportResponse},
|
||||
utils::{sanitize_html_api, send_new_report_email_to_admins},
|
||||
utils::send_new_report_email_to_admins,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -24,7 +24,7 @@ pub async fn create_pm_report(
|
||||
) -> Result<Json<PrivateMessageReportResponse>, LemmyError> {
|
||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||
|
||||
let reason = sanitize_html_api(data.reason.trim());
|
||||
let reason = data.reason.trim().to_string();
|
||||
check_report_reason(&reason, &local_site)?;
|
||||
|
||||
let person_id = local_user_view.person.id;
|
||||
@ -35,7 +35,7 @@ pub async fn create_pm_report(
|
||||
creator_id: person_id,
|
||||
private_message_id,
|
||||
original_pm_text: private_message.content,
|
||||
reason: reason.clone(),
|
||||
reason,
|
||||
};
|
||||
|
||||
let report = PrivateMessageReport::report(&mut context.pool(), &report_form)
|
||||
|
@ -2,7 +2,7 @@ use actix_web::web::{Data, Json};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
site::{PurgeComment, PurgeItemResponse},
|
||||
utils::{is_admin, sanitize_html_api_opt},
|
||||
utils::is_admin,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -35,10 +35,9 @@ pub async fn purge_comment(
|
||||
Comment::delete(&mut context.pool(), comment_id).await?;
|
||||
|
||||
// Mod tables
|
||||
let reason = sanitize_html_api_opt(&data.reason);
|
||||
let form = AdminPurgeCommentForm {
|
||||
admin_person_id: local_user_view.person.id,
|
||||
reason,
|
||||
reason: data.reason.clone(),
|
||||
post_id,
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@ use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
request::purge_image_from_pictrs,
|
||||
site::{PurgeCommunity, PurgeItemResponse},
|
||||
utils::{is_admin, purge_image_posts_for_community, sanitize_html_api_opt},
|
||||
utils::{is_admin, purge_image_posts_for_community},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -42,10 +42,9 @@ pub async fn purge_community(
|
||||
Community::delete(&mut context.pool(), community_id).await?;
|
||||
|
||||
// Mod tables
|
||||
let reason = sanitize_html_api_opt(&data.reason);
|
||||
let form = AdminPurgeCommunityForm {
|
||||
admin_person_id: local_user_view.person.id,
|
||||
reason,
|
||||
reason: data.reason.clone(),
|
||||
};
|
||||
|
||||
AdminPurgeCommunity::create(&mut context.pool(), &form).await?;
|
||||
|
@ -3,7 +3,7 @@ use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
request::delete_image_from_pictrs,
|
||||
site::{PurgeItemResponse, PurgePerson},
|
||||
utils::{is_admin, sanitize_html_api_opt},
|
||||
utils::is_admin,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -41,10 +41,9 @@ pub async fn purge_person(
|
||||
Person::delete(&mut context.pool(), person_id).await?;
|
||||
|
||||
// Mod tables
|
||||
let reason = sanitize_html_api_opt(&data.reason);
|
||||
let form = AdminPurgePersonForm {
|
||||
admin_person_id: local_user_view.person.id,
|
||||
reason,
|
||||
reason: data.reason.clone(),
|
||||
};
|
||||
|
||||
AdminPurgePerson::create(&mut context.pool(), &form).await?;
|
||||
|
@ -3,7 +3,7 @@ use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
request::purge_image_from_pictrs,
|
||||
site::{PurgeItemResponse, PurgePost},
|
||||
utils::{is_admin, sanitize_html_api_opt},
|
||||
utils::is_admin,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -43,10 +43,9 @@ pub async fn purge_post(
|
||||
Post::delete(&mut context.pool(), post_id).await?;
|
||||
|
||||
// Mod tables
|
||||
let reason = sanitize_html_api_opt(&data.reason);
|
||||
let form = AdminPurgePostForm {
|
||||
admin_person_id: local_user_view.person.id,
|
||||
reason,
|
||||
reason: data.reason.clone(),
|
||||
community_id,
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,10 @@ use lemmy_db_schema::{
|
||||
};
|
||||
use lemmy_db_views::structs::{CommentView, LocalUserView, PostView};
|
||||
use lemmy_db_views_actor::structs::CommunityView;
|
||||
use lemmy_utils::{error::LemmyError, utils::mention::MentionData};
|
||||
use lemmy_utils::{
|
||||
error::LemmyError,
|
||||
utils::{markdown::markdown_to_html, mention::MentionData},
|
||||
};
|
||||
|
||||
pub async fn build_comment_response(
|
||||
context: &LemmyContext,
|
||||
@ -121,10 +124,11 @@ pub async fn send_local_notifs(
|
||||
// Send an email to those local users that have notifications on
|
||||
if do_send_email {
|
||||
let lang = get_interface_language(&mention_user_view);
|
||||
let content = markdown_to_html(&comment.content);
|
||||
send_email_to_user(
|
||||
&mention_user_view,
|
||||
&lang.notification_mentioned_by_subject(&person.name),
|
||||
&lang.notification_mentioned_by_body(&comment.content, &inbox_link, &person.name),
|
||||
&lang.notification_mentioned_by_body(&content, &inbox_link, &person.name),
|
||||
context.settings(),
|
||||
)
|
||||
.await
|
||||
@ -164,10 +168,11 @@ pub async fn send_local_notifs(
|
||||
|
||||
if do_send_email {
|
||||
let lang = get_interface_language(&parent_user_view);
|
||||
let content = markdown_to_html(&comment.content);
|
||||
send_email_to_user(
|
||||
&parent_user_view,
|
||||
&lang.notification_comment_reply_subject(&person.name),
|
||||
&lang.notification_comment_reply_body(&comment.content, &inbox_link, &person.name),
|
||||
&lang.notification_comment_reply_body(&content, &inbox_link, &person.name),
|
||||
context.settings(),
|
||||
)
|
||||
.await
|
||||
@ -201,10 +206,11 @@ pub async fn send_local_notifs(
|
||||
|
||||
if do_send_email {
|
||||
let lang = get_interface_language(&parent_user_view);
|
||||
let content = markdown_to_html(&comment.content);
|
||||
send_email_to_user(
|
||||
&parent_user_view,
|
||||
&lang.notification_post_reply_subject(&person.name),
|
||||
&lang.notification_post_reply_body(&comment.content, &inbox_link, &person.name),
|
||||
&lang.notification_post_reply_body(&content, &inbox_link, &person.name),
|
||||
context.settings(),
|
||||
)
|
||||
.await
|
||||
|
@ -723,37 +723,6 @@ pub fn generate_moderators_url(community_id: &DbUrl) -> Result<DbUrl, LemmyError
|
||||
Ok(Url::parse(&format!("{community_id}/moderators"))?.into())
|
||||
}
|
||||
|
||||
/// Replace special HTML characters in API parameters to prevent XSS attacks.
|
||||
///
|
||||
/// Taken from https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.md#output-encoding-for-html-contexts
|
||||
///
|
||||
/// `>` is left in place because it is interpreted as markdown quote.
|
||||
pub fn sanitize_html_api(data: &str) -> String {
|
||||
data
|
||||
.replace('&', "&")
|
||||
.replace('<', "<")
|
||||
.replace('\"', """)
|
||||
.replace('\'', "'")
|
||||
}
|
||||
|
||||
pub fn sanitize_html_api_opt(data: &Option<String>) -> Option<String> {
|
||||
data.as_ref().map(|d| sanitize_html_api(d))
|
||||
}
|
||||
|
||||
/// Replace special HTML characters in federation parameters to prevent XSS attacks.
|
||||
///
|
||||
/// Unlike [sanitize_html_api()] it leaves `&` in place to avoid double escaping.
|
||||
pub fn sanitize_html_federation(data: &str) -> String {
|
||||
data
|
||||
.replace('<', "<")
|
||||
.replace('\"', """)
|
||||
.replace('\'', "'")
|
||||
}
|
||||
|
||||
pub fn sanitize_html_federation_opt(data: &Option<String>) -> Option<String> {
|
||||
data.as_ref().map(|d| sanitize_html_federation(d))
|
||||
}
|
||||
|
||||
pub fn create_login_cookie(jwt: Sensitive<String>) -> Cookie<'static> {
|
||||
let mut cookie = Cookie::new(AUTH_COOKIE_NAME, jwt.into_inner());
|
||||
cookie.set_secure(true);
|
||||
|
@ -12,7 +12,6 @@ use lemmy_api_common::{
|
||||
generate_local_apub_endpoint,
|
||||
get_post,
|
||||
local_site_to_slur_regex,
|
||||
sanitize_html_api,
|
||||
EndpointType,
|
||||
},
|
||||
};
|
||||
@ -52,7 +51,6 @@ pub async fn create_comment(
|
||||
&local_site_to_slur_regex(&local_site),
|
||||
);
|
||||
is_valid_body_field(&Some(content.clone()), false)?;
|
||||
let content = sanitize_html_api(&content);
|
||||
|
||||
// Check for a community ban
|
||||
let post_id = data.post_id;
|
||||
|
@ -5,7 +5,7 @@ use lemmy_api_common::{
|
||||
comment::{CommentResponse, EditComment},
|
||||
context::LemmyContext,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{check_community_ban, local_site_to_slur_regex, sanitize_html_api_opt},
|
||||
utils::{check_community_ban, local_site_to_slur_regex},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -63,7 +63,6 @@ pub async fn update_comment(
|
||||
.as_ref()
|
||||
.map(|c| remove_slurs(c, &local_site_to_slur_regex(&local_site)));
|
||||
is_valid_body_field(&content, false)?;
|
||||
let content = sanitize_html_api_opt(&content);
|
||||
|
||||
let comment_id = data.comment_id;
|
||||
let form = CommentUpdateForm {
|
||||
|
@ -11,8 +11,6 @@ use lemmy_api_common::{
|
||||
generate_shared_inbox_url,
|
||||
is_admin,
|
||||
local_site_to_slur_regex,
|
||||
sanitize_html_api,
|
||||
sanitize_html_api_opt,
|
||||
EndpointType,
|
||||
},
|
||||
};
|
||||
@ -57,14 +55,10 @@ pub async fn create_community(
|
||||
let icon = diesel_option_overwrite_to_url_create(&data.icon)?;
|
||||
let banner = diesel_option_overwrite_to_url_create(&data.banner)?;
|
||||
|
||||
let name = sanitize_html_api(&data.name);
|
||||
let title = sanitize_html_api(&data.title);
|
||||
let description = sanitize_html_api_opt(&data.description);
|
||||
|
||||
let slur_regex = local_site_to_slur_regex(&local_site);
|
||||
check_slurs(&name, &slur_regex)?;
|
||||
check_slurs(&title, &slur_regex)?;
|
||||
check_slurs_opt(&description, &slur_regex)?;
|
||||
check_slurs(&data.name, &slur_regex)?;
|
||||
check_slurs(&data.title, &slur_regex)?;
|
||||
check_slurs_opt(&data.description, &slur_regex)?;
|
||||
|
||||
is_valid_actor_name(&data.name, local_site.actor_name_max_length as usize)?;
|
||||
is_valid_body_field(&data.description, false)?;
|
||||
@ -85,9 +79,9 @@ pub async fn create_community(
|
||||
let keypair = generate_actor_keypair()?;
|
||||
|
||||
let community_form = CommunityInsertForm::builder()
|
||||
.name(name)
|
||||
.title(title)
|
||||
.description(description)
|
||||
.name(data.name.clone())
|
||||
.title(data.title.clone())
|
||||
.description(data.description.clone())
|
||||
.icon(icon)
|
||||
.banner(banner)
|
||||
.nsfw(data.nsfw)
|
||||
|
@ -5,7 +5,7 @@ use lemmy_api_common::{
|
||||
community::{CommunityResponse, EditCommunity},
|
||||
context::LemmyContext,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{local_site_to_slur_regex, sanitize_html_api_opt},
|
||||
utils::local_site_to_slur_regex,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::PersonId,
|
||||
@ -37,12 +37,9 @@ pub async fn update_community(
|
||||
check_slurs_opt(&data.description, &slur_regex)?;
|
||||
is_valid_body_field(&data.description, false)?;
|
||||
|
||||
let title = sanitize_html_api_opt(&data.title);
|
||||
let description = sanitize_html_api_opt(&data.description);
|
||||
|
||||
let icon = diesel_option_overwrite_to_url(&data.icon)?;
|
||||
let banner = diesel_option_overwrite_to_url(&data.banner)?;
|
||||
let description = diesel_option_overwrite(description);
|
||||
let description = diesel_option_overwrite(data.description.clone());
|
||||
|
||||
// Verify its a mod (only mods can edit it)
|
||||
let community_id = data.community_id;
|
||||
@ -67,7 +64,7 @@ pub async fn update_community(
|
||||
}
|
||||
|
||||
let community_form = CommunityUpdateForm {
|
||||
title,
|
||||
title: data.title.clone(),
|
||||
description,
|
||||
icon,
|
||||
banner,
|
||||
|
@ -3,7 +3,7 @@ use actix_web::web::Json;
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
custom_emoji::{CreateCustomEmoji, CustomEmojiResponse},
|
||||
utils::{is_admin, sanitize_html_api},
|
||||
utils::is_admin,
|
||||
};
|
||||
use lemmy_db_schema::source::{
|
||||
custom_emoji::{CustomEmoji, CustomEmojiInsertForm},
|
||||
@ -23,15 +23,11 @@ pub async fn create_custom_emoji(
|
||||
// Make sure user is an admin
|
||||
is_admin(&local_user_view)?;
|
||||
|
||||
let shortcode = sanitize_html_api(data.shortcode.to_lowercase().trim());
|
||||
let alt_text = sanitize_html_api(&data.alt_text);
|
||||
let category = sanitize_html_api(&data.category);
|
||||
|
||||
let emoji_form = CustomEmojiInsertForm::builder()
|
||||
.local_site_id(local_site.id)
|
||||
.shortcode(shortcode)
|
||||
.alt_text(alt_text)
|
||||
.category(category)
|
||||
.shortcode(data.shortcode.to_lowercase().trim().to_string())
|
||||
.alt_text(data.alt_text.to_string())
|
||||
.category(data.category.to_string())
|
||||
.image_url(data.clone().image_url.into())
|
||||
.build();
|
||||
let emoji = CustomEmoji::create(&mut context.pool(), &emoji_form).await?;
|
||||
|
@ -3,7 +3,7 @@ use actix_web::web::Json;
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
custom_emoji::{CustomEmojiResponse, EditCustomEmoji},
|
||||
utils::{is_admin, sanitize_html_api},
|
||||
utils::is_admin,
|
||||
};
|
||||
use lemmy_db_schema::source::{
|
||||
custom_emoji::{CustomEmoji, CustomEmojiUpdateForm},
|
||||
@ -23,13 +23,10 @@ pub async fn update_custom_emoji(
|
||||
// Make sure user is an admin
|
||||
is_admin(&local_user_view)?;
|
||||
|
||||
let alt_text = sanitize_html_api(&data.alt_text);
|
||||
let category = sanitize_html_api(&data.category);
|
||||
|
||||
let emoji_form = CustomEmojiUpdateForm::builder()
|
||||
.local_site_id(local_site.id)
|
||||
.alt_text(alt_text)
|
||||
.category(category)
|
||||
.alt_text(data.alt_text.to_string())
|
||||
.category(data.category.to_string())
|
||||
.image_url(data.clone().image_url.into())
|
||||
.build();
|
||||
let emoji = CustomEmoji::update(&mut context.pool(), data.id, &emoji_form).await?;
|
||||
|
@ -13,8 +13,6 @@ use lemmy_api_common::{
|
||||
honeypot_check,
|
||||
local_site_to_slur_regex,
|
||||
mark_post_as_read,
|
||||
sanitize_html_api,
|
||||
sanitize_html_api_opt,
|
||||
EndpointType,
|
||||
},
|
||||
};
|
||||
@ -92,11 +90,6 @@ pub async fn create_post(
|
||||
.map(|u| (u.title, u.description, u.embed_video_url))
|
||||
.unwrap_or_default();
|
||||
|
||||
let name = sanitize_html_api(data.name.trim());
|
||||
let body = sanitize_html_api_opt(&data.body);
|
||||
let embed_title = sanitize_html_api_opt(&embed_title);
|
||||
let embed_description = sanitize_html_api_opt(&embed_description);
|
||||
|
||||
// Only need to check if language is allowed in case user set it explicitly. When using default
|
||||
// language, it already only returns allowed languages.
|
||||
CommunityLanguage::is_allowed_community_language(
|
||||
@ -120,9 +113,9 @@ pub async fn create_post(
|
||||
};
|
||||
|
||||
let post_form = PostInsertForm::builder()
|
||||
.name(name)
|
||||
.name(data.name.trim().to_string())
|
||||
.url(url)
|
||||
.body(body)
|
||||
.body(data.body.clone())
|
||||
.community_id(data.community_id)
|
||||
.creator_id(local_user_view.person.id)
|
||||
.nsfw(data.nsfw)
|
||||
|
@ -6,7 +6,7 @@ use lemmy_api_common::{
|
||||
post::{EditPost, PostResponse},
|
||||
request::fetch_site_data,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{check_community_ban, local_site_to_slur_regex, sanitize_html_api_opt},
|
||||
utils::{check_community_ban, local_site_to_slur_regex},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -75,12 +75,6 @@ pub async fn update_post(
|
||||
.map(|u| (Some(u.title), Some(u.description), Some(u.embed_video_url)))
|
||||
.unwrap_or_default();
|
||||
|
||||
let name = sanitize_html_api_opt(&data.name);
|
||||
let body = sanitize_html_api_opt(&data.body);
|
||||
let body = diesel_option_overwrite(body);
|
||||
let embed_title = embed_title.map(|e| sanitize_html_api_opt(&e));
|
||||
let embed_description = embed_description.map(|e| sanitize_html_api_opt(&e));
|
||||
|
||||
let language_id = data.language_id;
|
||||
CommunityLanguage::is_allowed_community_language(
|
||||
&mut context.pool(),
|
||||
@ -90,9 +84,9 @@ pub async fn update_post(
|
||||
.await?;
|
||||
|
||||
let post_form = PostUpdateForm {
|
||||
name,
|
||||
name: data.name.clone(),
|
||||
url,
|
||||
body,
|
||||
body: diesel_option_overwrite(data.body.clone()),
|
||||
nsfw: data.nsfw,
|
||||
embed_title,
|
||||
embed_description,
|
||||
|
@ -9,7 +9,6 @@ use lemmy_api_common::{
|
||||
generate_local_apub_endpoint,
|
||||
get_interface_language,
|
||||
local_site_to_slur_regex,
|
||||
sanitize_html_api,
|
||||
send_email_to_user,
|
||||
EndpointType,
|
||||
},
|
||||
@ -24,7 +23,7 @@ use lemmy_db_schema::{
|
||||
use lemmy_db_views::structs::{LocalUserView, PrivateMessageView};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyError, LemmyErrorExt, LemmyErrorType},
|
||||
utils::{slurs::remove_slurs, validation::is_valid_body_field},
|
||||
utils::{markdown::markdown_to_html, slurs::remove_slurs, validation::is_valid_body_field},
|
||||
};
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
@ -35,8 +34,7 @@ pub async fn create_private_message(
|
||||
) -> Result<Json<PrivateMessageResponse>, LemmyError> {
|
||||
let local_site = LocalSite::read(&mut context.pool()).await?;
|
||||
|
||||
let content = sanitize_html_api(&data.content);
|
||||
let content = remove_slurs(&content, &local_site_to_slur_regex(&local_site));
|
||||
let content = remove_slurs(&data.content, &local_site_to_slur_regex(&local_site));
|
||||
is_valid_body_field(&Some(content.clone()), false)?;
|
||||
|
||||
check_person_block(
|
||||
@ -83,6 +81,7 @@ pub async fn create_private_message(
|
||||
let lang = get_interface_language(&local_recipient);
|
||||
let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
|
||||
let sender_name = &local_user_view.person.name;
|
||||
let content = markdown_to_html(&content);
|
||||
send_email_to_user(
|
||||
&local_recipient,
|
||||
&lang.notification_private_message_subject(sender_name),
|
||||
|
@ -4,7 +4,7 @@ use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
private_message::{EditPrivateMessage, PrivateMessageResponse},
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{local_site_to_slur_regex, sanitize_html_api},
|
||||
utils::local_site_to_slur_regex,
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -36,8 +36,7 @@ pub async fn update_private_message(
|
||||
}
|
||||
|
||||
// Doing the update
|
||||
let content = sanitize_html_api(&data.content);
|
||||
let content = remove_slurs(&content, &local_site_to_slur_regex(&local_site));
|
||||
let content = remove_slurs(&data.content, &local_site_to_slur_regex(&local_site));
|
||||
is_valid_body_field(&Some(content.clone()), false)?;
|
||||
|
||||
let private_message_id = data.private_message_id;
|
||||
|
@ -4,13 +4,7 @@ use actix_web::web::{Data, Json};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
site::{CreateSite, SiteResponse},
|
||||
utils::{
|
||||
generate_site_inbox_url,
|
||||
is_admin,
|
||||
local_site_rate_limit_to_rate_limit_config,
|
||||
sanitize_html_api,
|
||||
sanitize_html_api_opt,
|
||||
},
|
||||
utils::{generate_site_inbox_url, is_admin, local_site_rate_limit_to_rate_limit_config},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::DbUrl,
|
||||
@ -55,14 +49,11 @@ pub async fn create_site(
|
||||
let actor_id: DbUrl = Url::parse(&context.settings().get_protocol_and_hostname())?.into();
|
||||
let inbox_url = Some(generate_site_inbox_url(&actor_id)?);
|
||||
let keypair = generate_actor_keypair()?;
|
||||
let name = sanitize_html_api(&data.name);
|
||||
let sidebar = sanitize_html_api_opt(&data.sidebar);
|
||||
let description = sanitize_html_api_opt(&data.description);
|
||||
|
||||
let site_form = SiteUpdateForm {
|
||||
name: Some(name),
|
||||
sidebar: diesel_option_overwrite(sidebar),
|
||||
description: diesel_option_overwrite(description),
|
||||
name: Some(data.name.clone()),
|
||||
sidebar: diesel_option_overwrite(data.sidebar.clone()),
|
||||
description: diesel_option_overwrite(data.description.clone()),
|
||||
icon: diesel_option_overwrite_to_url(&data.icon)?,
|
||||
banner: diesel_option_overwrite_to_url(&data.banner)?,
|
||||
actor_id: Some(actor_id),
|
||||
@ -77,10 +68,6 @@ pub async fn create_site(
|
||||
|
||||
Site::update(&mut context.pool(), site_id, &site_form).await?;
|
||||
|
||||
let application_question = sanitize_html_api_opt(&data.application_question);
|
||||
let default_theme = sanitize_html_api_opt(&data.default_theme);
|
||||
let legal_information = sanitize_html_api_opt(&data.legal_information);
|
||||
|
||||
let local_site_form = LocalSiteUpdateForm {
|
||||
// Set the site setup to true
|
||||
site_setup: Some(true),
|
||||
@ -89,11 +76,11 @@ pub async fn create_site(
|
||||
enable_nsfw: data.enable_nsfw,
|
||||
community_creation_admin_only: data.community_creation_admin_only,
|
||||
require_email_verification: data.require_email_verification,
|
||||
application_question: diesel_option_overwrite(application_question),
|
||||
application_question: diesel_option_overwrite(data.application_question.clone()),
|
||||
private_instance: data.private_instance,
|
||||
default_theme,
|
||||
default_theme: data.default_theme.clone(),
|
||||
default_post_listing_type: data.default_post_listing_type,
|
||||
legal_information: diesel_option_overwrite(legal_information),
|
||||
legal_information: diesel_option_overwrite(data.legal_information.clone()),
|
||||
application_email_admins: data.application_email_admins,
|
||||
hide_modlog_mod_names: data.hide_modlog_mod_names,
|
||||
updated: Some(Some(naive_now())),
|
||||
|
@ -3,7 +3,7 @@ use actix_web::web::{Data, Json};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
site::{EditSite, SiteResponse},
|
||||
utils::{is_admin, local_site_rate_limit_to_rate_limit_config, sanitize_html_api_opt},
|
||||
utils::{is_admin, local_site_rate_limit_to_rate_limit_config},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -54,14 +54,10 @@ pub async fn update_site(
|
||||
SiteLanguage::update(&mut context.pool(), discussion_languages.clone(), &site).await?;
|
||||
}
|
||||
|
||||
let name = sanitize_html_api_opt(&data.name);
|
||||
let sidebar = sanitize_html_api_opt(&data.sidebar);
|
||||
let description = sanitize_html_api_opt(&data.description);
|
||||
|
||||
let site_form = SiteUpdateForm {
|
||||
name,
|
||||
sidebar: diesel_option_overwrite(sidebar),
|
||||
description: diesel_option_overwrite(description),
|
||||
name: data.name.clone(),
|
||||
sidebar: diesel_option_overwrite(data.sidebar.clone()),
|
||||
description: diesel_option_overwrite(data.description.clone()),
|
||||
icon: diesel_option_overwrite_to_url(&data.icon)?,
|
||||
banner: diesel_option_overwrite_to_url(&data.banner)?,
|
||||
updated: Some(Some(naive_now())),
|
||||
@ -74,21 +70,17 @@ pub async fn update_site(
|
||||
// Diesel will throw an error for empty update forms
|
||||
.ok();
|
||||
|
||||
let application_question = sanitize_html_api_opt(&data.application_question);
|
||||
let default_theme = sanitize_html_api_opt(&data.default_theme);
|
||||
let legal_information = sanitize_html_api_opt(&data.legal_information);
|
||||
|
||||
let local_site_form = LocalSiteUpdateForm {
|
||||
enable_downvotes: data.enable_downvotes,
|
||||
registration_mode: data.registration_mode,
|
||||
enable_nsfw: data.enable_nsfw,
|
||||
community_creation_admin_only: data.community_creation_admin_only,
|
||||
require_email_verification: data.require_email_verification,
|
||||
application_question: diesel_option_overwrite(application_question),
|
||||
application_question: diesel_option_overwrite(data.application_question.clone()),
|
||||
private_instance: data.private_instance,
|
||||
default_theme,
|
||||
default_theme: data.default_theme.clone(),
|
||||
default_post_listing_type: data.default_post_listing_type,
|
||||
legal_information: diesel_option_overwrite(legal_information),
|
||||
legal_information: diesel_option_overwrite(data.legal_information.clone()),
|
||||
application_email_admins: data.application_email_admins,
|
||||
hide_modlog_mod_names: data.hide_modlog_mod_names,
|
||||
updated: Some(Some(naive_now())),
|
||||
|
@ -12,8 +12,6 @@ use lemmy_api_common::{
|
||||
honeypot_check,
|
||||
local_site_to_slur_regex,
|
||||
password_length_check,
|
||||
sanitize_html_api,
|
||||
sanitize_html_api_opt,
|
||||
send_new_applicant_email_to_admins,
|
||||
send_verification_email,
|
||||
EndpointType,
|
||||
@ -93,12 +91,6 @@ pub async fn register(
|
||||
check_slurs(&data.username, &slur_regex)?;
|
||||
check_slurs_opt(&data.answer, &slur_regex)?;
|
||||
|
||||
if sanitize_html_api(&data.username) != data.username {
|
||||
Err(LemmyErrorType::InvalidName)?;
|
||||
}
|
||||
|
||||
let answer = sanitize_html_api_opt(&data.answer);
|
||||
|
||||
let actor_keypair = generate_actor_keypair()?;
|
||||
is_valid_actor_name(&data.username, local_site.actor_name_max_length as usize)?;
|
||||
let actor_id = generate_local_apub_endpoint(
|
||||
@ -154,7 +146,7 @@ pub async fn register(
|
||||
let form = RegistrationApplicationInsertForm {
|
||||
local_user_id: inserted_local_user.id,
|
||||
// We already made sure answer was not null above
|
||||
answer: answer.expect("must have an answer"),
|
||||
answer: data.answer.clone().expect("must have an answer"),
|
||||
};
|
||||
|
||||
RegistrationApplication::create(&mut context.pool(), &form).await?;
|
||||
|
@ -23,7 +23,7 @@ use anyhow::anyhow;
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
utils::{remove_user_data, remove_user_data_in_community, sanitize_html_federation_opt},
|
||||
utils::{remove_user_data, remove_user_data_in_community},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -173,7 +173,7 @@ impl ActivityHandler for BlockUser {
|
||||
let form = ModBanForm {
|
||||
mod_person_id: mod_person.id,
|
||||
other_person_id: blocked_person.id,
|
||||
reason: sanitize_html_federation_opt(&self.summary),
|
||||
reason: self.summary,
|
||||
banned: Some(true),
|
||||
expires,
|
||||
};
|
||||
@ -207,7 +207,7 @@ impl ActivityHandler for BlockUser {
|
||||
mod_person_id: mod_person.id,
|
||||
other_person_id: blocked_person.id,
|
||||
community_id: community.id,
|
||||
reason: sanitize_html_federation_opt(&self.summary),
|
||||
reason: self.summary,
|
||||
banned: Some(true),
|
||||
expires,
|
||||
};
|
||||
|
@ -17,7 +17,7 @@ use activitypub_federation::{
|
||||
protocol::verification::verify_domains_match,
|
||||
traits::{ActivityHandler, Actor},
|
||||
};
|
||||
use lemmy_api_common::{context::LemmyContext, utils::sanitize_html_federation_opt};
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
activity::ActivitySendTargets,
|
||||
@ -118,7 +118,7 @@ impl ActivityHandler for UndoBlockUser {
|
||||
let form = ModBanForm {
|
||||
mod_person_id: mod_person.id,
|
||||
other_person_id: blocked_person.id,
|
||||
reason: sanitize_html_federation_opt(&self.object.summary),
|
||||
reason: self.object.summary,
|
||||
banned: Some(false),
|
||||
expires,
|
||||
};
|
||||
@ -137,7 +137,7 @@ impl ActivityHandler for UndoBlockUser {
|
||||
mod_person_id: mod_person.id,
|
||||
other_person_id: blocked_person.id,
|
||||
community_id: community.id,
|
||||
reason: sanitize_html_federation_opt(&self.object.summary),
|
||||
reason: self.object.summary,
|
||||
banned: Some(false),
|
||||
expires,
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ use activitypub_federation::{
|
||||
kinds::activity::FlagType,
|
||||
traits::{ActivityHandler, Actor},
|
||||
};
|
||||
use lemmy_api_common::{context::LemmyContext, utils::sanitize_html_federation};
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
activity::ActivitySendTargets,
|
||||
@ -90,7 +90,7 @@ impl ActivityHandler for Report {
|
||||
post_id: post.id,
|
||||
original_post_name: post.name.clone(),
|
||||
original_post_url: post.url.clone(),
|
||||
reason: sanitize_html_federation(&self.summary),
|
||||
reason: self.summary.clone(),
|
||||
original_post_body: post.body.clone(),
|
||||
};
|
||||
PostReport::report(&mut context.pool(), &report_form).await?;
|
||||
@ -100,7 +100,7 @@ impl ActivityHandler for Report {
|
||||
creator_id: actor.id,
|
||||
comment_id: comment.id,
|
||||
original_comment_text: comment.content.clone(),
|
||||
reason: sanitize_html_federation(&self.summary),
|
||||
reason: self.summary.clone(),
|
||||
};
|
||||
CommentReport::report(&mut context.pool(), &report_form).await?;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
protocol::{activities::deletion::delete::Delete, IdOrNestedObject},
|
||||
};
|
||||
use activitypub_federation::{config::Data, kinds::activity::DeleteType, traits::ActivityHandler};
|
||||
use lemmy_api_common::{context::LemmyContext, utils::sanitize_html_federation_opt};
|
||||
use lemmy_api_common::context::LemmyContext;
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
comment::{Comment, CommentUpdateForm},
|
||||
@ -105,8 +105,6 @@ pub(in crate::activities) async fn receive_remove_action(
|
||||
reason: Option<String>,
|
||||
context: &Data<LemmyContext>,
|
||||
) -> Result<(), LemmyError> {
|
||||
let reason = sanitize_html_federation_opt(&reason);
|
||||
|
||||
match DeletableObjects::read_from_db(object, context).await? {
|
||||
DeletableObjects::Community(community) => {
|
||||
if community.local {
|
||||
|
@ -16,10 +16,7 @@ use activitypub_federation::{
|
||||
traits::Object,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
utils::{local_site_opt_to_slur_regex, sanitize_html_federation},
|
||||
};
|
||||
use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
comment::{Comment, CommentInsertForm, CommentUpdateForm},
|
||||
@ -162,7 +159,6 @@ impl Object for ApubComment {
|
||||
let local_site = LocalSite::read(&mut context.pool()).await.ok();
|
||||
let slur_regex = &local_site_opt_to_slur_regex(&local_site);
|
||||
let content = remove_slurs(&content, slur_regex);
|
||||
let content = sanitize_html_federation(&content);
|
||||
let language_id =
|
||||
LanguageTag::to_language_id_single(note.language, &mut context.pool()).await?;
|
||||
|
||||
|
@ -17,10 +17,7 @@ use activitypub_federation::{
|
||||
traits::{Actor, Object},
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
utils::{local_site_opt_to_slur_regex, sanitize_html_federation_opt},
|
||||
};
|
||||
use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::InstanceId,
|
||||
source::{
|
||||
@ -135,8 +132,6 @@ impl Object for ApubSite {
|
||||
let instance = DbInstance::read_or_create(&mut data.pool(), domain.to_string()).await?;
|
||||
|
||||
let sidebar = read_from_string_or_source_opt(&apub.content, &None, &apub.source);
|
||||
let sidebar = sanitize_html_federation_opt(&sidebar);
|
||||
let description = sanitize_html_federation_opt(&apub.summary);
|
||||
|
||||
let site_form = SiteInsertForm {
|
||||
name: apub.name.clone(),
|
||||
@ -144,7 +139,7 @@ impl Object for ApubSite {
|
||||
updated: apub.updated,
|
||||
icon: apub.icon.clone().map(|i| i.url.into()),
|
||||
banner: apub.image.clone().map(|i| i.url.into()),
|
||||
description,
|
||||
description: apub.summary,
|
||||
actor_id: Some(apub.id.clone().into()),
|
||||
last_refreshed_at: Some(naive_now()),
|
||||
inbox_url: Some(apub.inbox.clone().into()),
|
||||
|
@ -20,12 +20,7 @@ use activitypub_federation::{
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
utils::{
|
||||
generate_outbox_url,
|
||||
local_site_opt_to_slur_regex,
|
||||
sanitize_html_federation,
|
||||
sanitize_html_federation_opt,
|
||||
},
|
||||
utils::{generate_outbox_url, local_site_opt_to_slur_regex},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
@ -150,17 +145,14 @@ impl Object for ApubPerson {
|
||||
) -> Result<ApubPerson, LemmyError> {
|
||||
let instance_id = fetch_instance_actor_for_object(&person.id, context).await?;
|
||||
|
||||
let name = sanitize_html_federation(&person.preferred_username);
|
||||
let display_name = sanitize_html_federation_opt(&person.name);
|
||||
let bio = read_from_string_or_source_opt(&person.summary, &None, &person.source);
|
||||
let bio = sanitize_html_federation_opt(&bio);
|
||||
|
||||
// Some Mastodon users have `name: ""` (empty string), need to convert that to `None`
|
||||
// https://github.com/mastodon/mastodon/issues/25233
|
||||
let display_name = display_name.filter(|n| !n.is_empty());
|
||||
let display_name = person.name.filter(|n| !n.is_empty());
|
||||
|
||||
let person_form = PersonInsertForm {
|
||||
name,
|
||||
name: person.preferred_username,
|
||||
display_name,
|
||||
banned: None,
|
||||
ban_expires: None,
|
||||
@ -275,7 +267,7 @@ pub(crate) mod tests {
|
||||
assert_eq!(person.name, "lanodan");
|
||||
assert!(!person.local);
|
||||
assert_eq!(context.request_count(), 0);
|
||||
assert_eq!(person.bio.as_ref().unwrap().len(), 878);
|
||||
assert_eq!(person.bio.as_ref().unwrap().len(), 873);
|
||||
|
||||
cleanup((person, site), &context).await;
|
||||
}
|
||||
|
@ -25,13 +25,7 @@ use html2md::parse_html;
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
request::fetch_site_data,
|
||||
utils::{
|
||||
is_mod_or_admin,
|
||||
local_site_opt_to_sensitive,
|
||||
local_site_opt_to_slur_regex,
|
||||
sanitize_html_federation,
|
||||
sanitize_html_federation_opt,
|
||||
},
|
||||
utils::{is_mod_or_admin, local_site_opt_to_sensitive, local_site_opt_to_slur_regex},
|
||||
};
|
||||
use lemmy_db_schema::{
|
||||
self,
|
||||
@ -231,17 +225,11 @@ impl Object for ApubPost {
|
||||
.unwrap_or_default();
|
||||
let slur_regex = &local_site_opt_to_slur_regex(&local_site);
|
||||
|
||||
let body_slurs_removed =
|
||||
read_from_string_or_source_opt(&page.content, &page.media_type, &page.source)
|
||||
.map(|s| remove_slurs(&s, slur_regex));
|
||||
let body = read_from_string_or_source_opt(&page.content, &page.media_type, &page.source)
|
||||
.map(|s| remove_slurs(&s, slur_regex));
|
||||
let language_id =
|
||||
LanguageTag::to_language_id_single(page.language, &mut context.pool()).await?;
|
||||
|
||||
let name = sanitize_html_federation(&name);
|
||||
let body = sanitize_html_federation_opt(&body_slurs_removed);
|
||||
let embed_title = sanitize_html_federation_opt(&embed_title);
|
||||
let embed_description = sanitize_html_federation_opt(&embed_description);
|
||||
|
||||
PostInsertForm {
|
||||
name,
|
||||
url: url.map(Into::into),
|
||||
|
@ -12,10 +12,7 @@ use activitypub_federation::{
|
||||
traits::Object,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
utils::{check_person_block, sanitize_html_federation},
|
||||
};
|
||||
use lemmy_api_common::{context::LemmyContext, utils::check_person_block};
|
||||
use lemmy_db_schema::{
|
||||
source::{
|
||||
person::Person,
|
||||
@ -125,7 +122,6 @@ impl Object for ApubPrivateMessage {
|
||||
check_person_block(creator.id, recipient.id, &mut context.pool()).await?;
|
||||
|
||||
let content = read_from_string_or_source(¬e.content, &None, ¬e.source);
|
||||
let content = sanitize_html_federation(&content);
|
||||
|
||||
let form = PrivateMessageInsertForm {
|
||||
creator_id: creator.id,
|
||||
|
@ -23,10 +23,7 @@ use activitypub_federation::{
|
||||
},
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
utils::{local_site_opt_to_slur_regex, sanitize_html_federation, sanitize_html_federation_opt},
|
||||
};
|
||||
use lemmy_api_common::{context::LemmyContext, utils::local_site_opt_to_slur_regex};
|
||||
use lemmy_db_schema::{
|
||||
newtypes::InstanceId,
|
||||
source::community::{CommunityInsertForm, CommunityUpdateForm},
|
||||
@ -97,14 +94,11 @@ impl Group {
|
||||
}
|
||||
|
||||
pub(crate) fn into_insert_form(self, instance_id: InstanceId) -> CommunityInsertForm {
|
||||
let name = sanitize_html_federation(&self.preferred_username);
|
||||
let title = sanitize_html_federation(&self.name.unwrap_or(self.preferred_username));
|
||||
let description = read_from_string_or_source_opt(&self.summary, &None, &self.source);
|
||||
let description = sanitize_html_federation_opt(&description);
|
||||
|
||||
CommunityInsertForm {
|
||||
name,
|
||||
title,
|
||||
name: self.preferred_username.clone(),
|
||||
title: self.name.unwrap_or(self.preferred_username.clone()),
|
||||
description,
|
||||
removed: None,
|
||||
published: self.published,
|
||||
|
@ -22,7 +22,7 @@ use lemmy_db_views_actor::{
|
||||
use lemmy_utils::{
|
||||
cache_header::cache_1hour,
|
||||
error::LemmyError,
|
||||
utils::markdown::markdown_to_html,
|
||||
utils::markdown::{markdown_to_html, sanitize_html},
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use rss::{
|
||||
@ -289,7 +289,7 @@ async fn get_feed_community(
|
||||
.items(items);
|
||||
|
||||
if let Some(community_desc) = community.description {
|
||||
channel_builder.description(&community_desc);
|
||||
channel_builder.description(markdown_to_html(&community_desc));
|
||||
}
|
||||
|
||||
Ok(channel_builder)
|
||||
@ -328,7 +328,7 @@ async fn get_feed_front(
|
||||
.items(items);
|
||||
|
||||
if let Some(site_desc) = site_view.site.description {
|
||||
channel_builder.description(&site_desc);
|
||||
channel_builder.description(markdown_to_html(&site_desc));
|
||||
}
|
||||
|
||||
Ok(channel_builder)
|
||||
@ -457,7 +457,7 @@ fn create_post_items(
|
||||
let mut i = ItemBuilder::default();
|
||||
let mut dc_extension = DublinCoreExtensionBuilder::default();
|
||||
|
||||
i.title(p.post.name);
|
||||
i.title(sanitize_html(&p.post.name));
|
||||
|
||||
dc_extension.creators(vec![p.creator.actor_id.to_string()]);
|
||||
|
||||
@ -472,14 +472,18 @@ fn create_post_items(
|
||||
.build();
|
||||
i.guid(guid);
|
||||
|
||||
let community_url = format!("{}/c/{}", protocol_and_hostname, p.community.name);
|
||||
let community_url = format!(
|
||||
"{}/c/{}",
|
||||
protocol_and_hostname,
|
||||
sanitize_html(&p.community.name)
|
||||
);
|
||||
|
||||
// TODO add images
|
||||
let mut description = format!("submitted by <a href=\"{}\">{}</a> to <a href=\"{}\">{}</a><br>{} points | <a href=\"{}\">{} comments</a>",
|
||||
p.creator.actor_id,
|
||||
p.creator.name,
|
||||
sanitize_html(&p.creator.name),
|
||||
community_url,
|
||||
p.community.name,
|
||||
sanitize_html(&p.community.name),
|
||||
p.counts.score,
|
||||
post_url,
|
||||
p.counts.comments);
|
||||
|
@ -12,6 +12,20 @@ static MARKDOWN_PARSER: Lazy<MarkdownIt> = Lazy::new(|| {
|
||||
parser
|
||||
});
|
||||
|
||||
/// Replace special HTML characters in API parameters to prevent XSS attacks.
|
||||
///
|
||||
/// Taken from https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.md#output-encoding-for-html-contexts
|
||||
///
|
||||
/// `>` is left in place because it is interpreted as markdown quote.
|
||||
pub fn sanitize_html(text: &str) -> String {
|
||||
text
|
||||
.replace('&', "&")
|
||||
.replace('<', "<")
|
||||
.replace('\"', """)
|
||||
.replace('\'', "'")
|
||||
}
|
||||
|
||||
/// Converts text from markdown to HTML, while escaping special characters.
|
||||
pub fn markdown_to_html(text: &str) -> String {
|
||||
MARKDOWN_PARSER.parse(text).xrender()
|
||||
}
|
||||
@ -21,7 +35,7 @@ mod tests {
|
||||
#![allow(clippy::unwrap_used)]
|
||||
#![allow(clippy::indexing_slicing)]
|
||||
|
||||
use crate::utils::markdown::markdown_to_html;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_basic_markdown() {
|
||||
@ -71,6 +85,11 @@ mod tests {
|
||||
"::: spoiler click to see more\nhow spicy!\n:::\n",
|
||||
"<details><summary>click to see more</summary><p>how spicy!\n</p></details>\n"
|
||||
),
|
||||
(
|
||||
"escape html special chars",
|
||||
"<script>alert('xss');</script> hello &\"",
|
||||
"<p><script>alert(‘xss’);</script> hello &"</p>\n"
|
||||
)
|
||||
];
|
||||
|
||||
tests.iter().for_each(|&(msg, input, expected)| {
|
||||
@ -83,4 +102,11 @@ mod tests {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanitize_html() {
|
||||
let sanitized = sanitize_html("<script>alert('xss');</script> hello &\"'");
|
||||
let expected = "<script>alert('xss');</script> hello &"'";
|
||||
assert_eq!(expected, sanitized)
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 18da10858d8c63750beb06247947f25d91944741
|
||||
Subproject commit e943f97fe481dc425acdebc8872bf1fdcabaf875
|
Loading…
Reference in New Issue
Block a user