Remove ability to upload non-images using /api/v1/media endpoint

This commit is contained in:
silverpill 2023-01-06 01:50:30 +00:00
parent 68e464c813
commit 7539533b69
4 changed files with 33 additions and 11 deletions

View file

@ -17,6 +17,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Updated installation instructions, default mitra config and recommended nginx config.
- Limited the number of requests made during the processing of a thread.
### Removed
- Removed ability to upload non-images using `/api/v1/media` endpoint.
### Fixed
- Fixed post and profile page redirections.

View file

@ -19,16 +19,17 @@ async fn create_attachment_view(
) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?;
let current_user = get_current_user(db_client, auth.token()).await?;
let (file_name, maybe_media_type) = save_b64_file(
let (file_name, media_type) = save_b64_file(
&attachment_data.file,
attachment_data.media_type.clone(),
&config.media_dir(),
Some("image/"),
)?;
let db_attachment = create_attachment(
db_client,
&current_user.id,
file_name,
maybe_media_type,
Some(media_type),
).await?;
let attachment = Attachment::from_db(
db_attachment,

View file

@ -1,7 +1,11 @@
use std::path::Path;
use crate::errors::HttpError;
use crate::utils::files::{save_file, sniff_media_type};
use crate::utils::files::{
save_file,
sniff_media_type,
SUPPORTED_MEDIA_TYPES,
};
pub const UPLOAD_MAX_SIZE: usize = 1024 * 1024 * 5;
@ -33,25 +37,31 @@ impl From<UploadError> for HttpError {
pub fn save_b64_file(
b64data: &str,
mut maybe_media_type: Option<String>,
maybe_media_type: Option<String>,
output_dir: &Path,
) -> Result<(String, Option<String>), UploadError> {
maybe_expected_prefix: Option<&str>,
) -> Result<(String, String), UploadError> {
let data = base64::decode(b64data)?;
if data.len() > UPLOAD_MAX_SIZE {
return Err(UploadError::TooLarge);
};
// Sniff media type if not provided
maybe_media_type = maybe_media_type.or(sniff_media_type(&data));
if maybe_media_type.as_deref() == Some("image/svg+xml") {
// Don't treat SVG files as images
maybe_media_type = None;
let media_type = maybe_media_type.or(sniff_media_type(&data))
.ok_or(UploadError::InvalidMediaType)?;
if !SUPPORTED_MEDIA_TYPES.contains(&media_type.as_str()) {
return Err(UploadError::InvalidMediaType);
};
if let Some(expected_prefix) = maybe_expected_prefix {
if !media_type.starts_with(expected_prefix) {
return Err(UploadError::InvalidMediaType);
};
};
let file_name = save_file(
data,
output_dir,
maybe_media_type.as_deref(),
Some(&media_type),
)?;
Ok((file_name, maybe_media_type))
Ok((file_name, media_type))
}
pub fn save_validated_b64_file(

View file

@ -13,6 +13,13 @@ use mime_guess::get_mime_extensions_str;
use mime_sniffer::MimeTypeSniffer;
use sha2::{Digest, Sha256};
pub const SUPPORTED_MEDIA_TYPES: [&str; 4] = [
"image/jpeg",
"image/png",
"image/gif",
"video/mp4",
];
pub fn sniff_media_type(data: &[u8]) -> Option<String> {
data.sniff_mime_type().map(|val| val.to_string())
}