Skip to content

Commit

Permalink
smtp/mime: Restrict file name lengths
Browse files Browse the repository at this point in the history
This commit places restrictions on the length of the file name specified
in attachments (`name=` or `filename=`) to `NAME_MAX`. Names exceeding
these limits will be truncated and processing will continue with the
truncated name.
  • Loading branch information
jlucovsky authored and victorjulien committed Mar 3, 2020
1 parent 072c421 commit d0d20bd
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/suricata-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,5 +501,9 @@ extern int g_ut_covered;

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))

#ifndef NAME_MAX
#define NAME_MAX 255
#endif

#endif /* __SURICATA_COMMON_H__ */

53 changes: 43 additions & 10 deletions src/util-decode-mime.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* Copyright (C) 2012 BAE Systems
* Copyright (C) 2020 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
Expand Down Expand Up @@ -1830,30 +1831,62 @@ static int FindMimeHeader(const uint8_t *buf, uint32_t blen,
* \param search_start The start of the search (ie. boundary=\")
* \param search_end The end of the search (ie. \")
* \param tlen The output length of the token (if found)
* \param max_len The maximum offset in which to search
*
* \return A pointer to the token if found, otherwise NULL if not found
*/
static uint8_t * FindMimeHeaderToken(MimeDecField *field, const char *search_start,
const char *search_end, uint32_t *tlen)
static uint8_t * FindMimeHeaderTokenRestrict(MimeDecField *field, const char *search_start,
const char *search_end, uint32_t *tlen, uint32_t max_len, bool *toolong)
{
uint8_t *fptr, *tptr = NULL, *tok = NULL;

if (toolong)
*toolong = false;

SCLogDebug("Looking for token: %s", search_start);

/* Check for token definition */
fptr = FindBuffer(field->value, field->value_len, (const uint8_t *)search_start, strlen(search_start));
size_t ss_len = strlen(search_start);
fptr = FindBuffer(field->value, field->value_len, (const uint8_t *)search_start, ss_len);
if (fptr != NULL) {
fptr += strlen(search_start); /* Start at end of start string */
tok = GetToken(fptr, field->value_len - (fptr - field->value), search_end,
&tptr, tlen);
if (tok != NULL) {
SCLogDebug("Found mime token");
fptr += ss_len; /* Start at end of start string */
uint32_t offset = fptr - field->value;
if (offset > field->value_len) {
return tok;
}
tok = GetToken(fptr, field->value_len - offset, search_end, &tptr, tlen);
if (tok == NULL) {
return tok;
}
SCLogDebug("Found mime token");

/* Compare the actual token length against the maximum */
if (toolong && max_len && *tlen > max_len) {
SCLogDebug("Token length %d exceeds length restriction %d; truncating", *tlen, max_len);
*toolong = true;
*tlen = max_len;
}
}

return tok;
}

/**
* \brief Finds a mime header token within the specified field
*
* \param field The current field
* \param search_start The start of the search (ie. boundary=\")
* \param search_end The end of the search (ie. \")
* \param tlen The output length of the token (if found)
*
* \return A pointer to the token if found, otherwise NULL if not found
*/
static uint8_t * FindMimeHeaderToken(MimeDecField *field, const char *search_start,
const char *search_end, uint32_t *tlen)
{
return FindMimeHeaderTokenRestrict(field, search_start, search_end, tlen, 0);
}

/**
* \brief Processes the current line for mime headers and also does post-processing
* when all headers found
Expand Down Expand Up @@ -1899,7 +1932,7 @@ static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len,
/* Check for file attachment in content disposition */
field = MimeDecFindField(entity, CTNT_DISP_STR);
if (field != NULL) {
bptr = FindMimeHeaderToken(field, "filename=", TOK_END_STR, &blen);
bptr = FindMimeHeaderTokenRestrict(field, "filename=", TOK_END_STR, &blen, NAME_MAX);
if (bptr != NULL) {
SCLogDebug("File attachment found in disposition");
entity->ctnt_flags |= CTNT_IS_ATTACHMENT;
Expand Down Expand Up @@ -1941,7 +1974,7 @@ static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len,

/* Look for file name (if not already found) */
if (!(entity->ctnt_flags & CTNT_IS_ATTACHMENT)) {
bptr = FindMimeHeaderToken(field, "name=", TOK_END_STR, &blen);
bptr = FindMimeHeaderTokenRestrict(field, "name=", TOK_END_STR, &blen, NAME_MAX);
if (bptr != NULL) {
SCLogDebug("File attachment found");
entity->ctnt_flags |= CTNT_IS_ATTACHMENT;
Expand Down

0 comments on commit d0d20bd

Please sign in to comment.