Skip to content

Commit

Permalink
fix(server): prevent serving an already expired file
Browse files Browse the repository at this point in the history
  • Loading branch information
orhun committed Nov 6, 2021
1 parent 3eee294 commit f078a9a
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 13 deletions.
24 changes: 24 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ url = "2.2.2"
mime = "0.3.16"
regex = "1.5.4"
serde_regex = "1.1.0"
lazy-regex = "2.2.1"
humantime = "2.1.0"
glob = "0.3.0"
ring = "0.16.20"
Expand Down
7 changes: 4 additions & 3 deletions src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ impl<'a> TryFrom<&'a Path> for Directory {
impl Directory {
/// Returns the file that matches the given checksum.
pub fn get_file<S: AsRef<str>>(self, sha256sum: S) -> Option<File> {
self.files
.into_iter()
.find(|file| file.sha256sum == sha256sum.as_ref())
self.files.into_iter().find(|file| {
file.sha256sum == sha256sum.as_ref()
&& !util::TIMESTAMP_EXTENSION_REGEX.is_match(&file.path.to_string_lossy())
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/paste.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl Paste {
let bytes = response.body().limit(payload_limit).await?.to_vec();
let bytes_checksum = util::sha256_digest(&*bytes)?;
self.data = bytes;
if !config.paste.duplicate_files.unwrap_or(true) {
if !config.paste.duplicate_files.unwrap_or(true) && expiry_date.is_none() {
if let Some(file) =
Directory::try_from(config.server.upload_path.as_path())?.get_file(bytes_checksum)
{
Expand Down
1 change: 1 addition & 0 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ async fn upload(
}
if paste_type != PasteType::Oneshot
&& paste_type != PasteType::RemoteFile
&& expiry_date.is_none()
&& !config.paste.duplicate_files.unwrap_or(true)
{
let bytes_checksum = util::sha256_digest(&*bytes)?;
Expand Down
27 changes: 18 additions & 9 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use actix_web::{error, Error as ActixError};
use glob::glob;
use lazy_regex::{lazy_regex, Lazy, Regex};
use ring::digest::{Context, SHA256};
use std::io::{BufReader, Read};
use std::path::PathBuf;
use std::time::Duration;
use std::time::{SystemTime, UNIX_EPOCH};

/// Regex for matching the timestamp extension of a path.
pub static TIMESTAMP_EXTENSION_REGEX: Lazy<Regex> = lazy_regex!(r#"\.[0-9]{10,}$"#);

/// Returns the system time as [`Duration`](Duration).
pub fn get_system_time() -> Result<Duration, ActixError> {
SystemTime::now()
Expand All @@ -17,15 +21,20 @@ pub fn get_system_time() -> Result<Duration, ActixError> {
///
/// The file extension is accepted as a timestamp that points to the expiry date.
pub fn glob_match_file(mut path: PathBuf) -> Result<PathBuf, ActixError> {
if let Some(glob_path) = glob(&format!(
"{}.[0-9]*",
path.to_str()
.ok_or_else(|| error::ErrorInternalServerError(
"file name contains invalid characters"
))?,
))
.map_err(error::ErrorInternalServerError)?
.next()
path = PathBuf::from(
TIMESTAMP_EXTENSION_REGEX
.replacen(
path.to_str().ok_or_else(|| {
error::ErrorInternalServerError("path contains invalid characters")
})?,
1,
"",
)
.to_string(),
);
if let Some(glob_path) = glob(&format!("{}.[0-9]*", path.to_string_lossy()))
.map_err(error::ErrorInternalServerError)?
.next()
{
let glob_path = glob_path.map_err(error::ErrorInternalServerError)?;
if let Some(extension) = glob_path
Expand Down

0 comments on commit f078a9a

Please sign in to comment.