mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-21 02:00:33 +01:00
fix a potential DoS (through memory exhaustion) by restricting HTML form field name and value sizes
This commit is contained in:
parent
11845334dc
commit
3eda8f40bb
@ -184,11 +184,19 @@ public:
|
|||||||
/// Specify 0 for unlimited (not recommended).
|
/// Specify 0 for unlimited (not recommended).
|
||||||
///
|
///
|
||||||
/// The default limit is 100.
|
/// The default limit is 100.
|
||||||
|
|
||||||
|
void setValueLengthLimit(int limit);
|
||||||
|
/// Sets the maximum size for form field values
|
||||||
|
/// stored as strings.
|
||||||
|
|
||||||
|
int getValueLengthLimit() const;
|
||||||
|
/// Returns the maximum size for form field values
|
||||||
|
/// stored as strings.
|
||||||
|
|
||||||
static const std::string ENCODING_URL; /// "application/x-www-form-urlencoded"
|
static const std::string ENCODING_URL; /// "application/x-www-form-urlencoded"
|
||||||
static const std::string ENCODING_MULTIPART; /// "multipart/form-data"
|
static const std::string ENCODING_MULTIPART; /// "multipart/form-data"
|
||||||
|
|
||||||
static const int UNKNOWN_CONTENT_LENGTH;
|
static const int UNKNOWN_CONTENT_LENGTH;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void readUrl(std::istream& istr);
|
void readUrl(std::istream& istr);
|
||||||
void readMultipart(std::istream& istr, PartHandler& handler);
|
void readMultipart(std::istream& istr, PartHandler& handler);
|
||||||
@ -201,7 +209,9 @@ private:
|
|||||||
|
|
||||||
enum Limits
|
enum Limits
|
||||||
{
|
{
|
||||||
DFL_FIELD_LIMIT = 100
|
DFL_FIELD_LIMIT = 100,
|
||||||
|
MAX_NAME_LENGTH = 1024,
|
||||||
|
DFL_MAX_VALUE_LENGTH = 256*1024
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Part
|
struct Part
|
||||||
@ -213,6 +223,7 @@ private:
|
|||||||
typedef std::vector<Part> PartVec;
|
typedef std::vector<Part> PartVec;
|
||||||
|
|
||||||
int _fieldLimit;
|
int _fieldLimit;
|
||||||
|
int _valueLengthLimit;
|
||||||
std::string _encoding;
|
std::string _encoding;
|
||||||
std::string _boundary;
|
std::string _boundary;
|
||||||
PartVec _parts;
|
PartVec _parts;
|
||||||
@ -240,6 +251,12 @@ inline int HTMLForm::getFieldLimit() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int HTMLForm::getValueLengthLimit() const
|
||||||
|
{
|
||||||
|
return _valueLengthLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Net
|
} } // namespace Poco::Net
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ private:
|
|||||||
|
|
||||||
HTMLForm::HTMLForm():
|
HTMLForm::HTMLForm():
|
||||||
_fieldLimit(DFL_FIELD_LIMIT),
|
_fieldLimit(DFL_FIELD_LIMIT),
|
||||||
|
_valueLengthLimit(DFL_MAX_VALUE_LENGTH),
|
||||||
_encoding(ENCODING_URL)
|
_encoding(ENCODING_URL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -80,27 +81,31 @@ HTMLForm::HTMLForm():
|
|||||||
|
|
||||||
HTMLForm::HTMLForm(const std::string& encoding):
|
HTMLForm::HTMLForm(const std::string& encoding):
|
||||||
_fieldLimit(DFL_FIELD_LIMIT),
|
_fieldLimit(DFL_FIELD_LIMIT),
|
||||||
|
_valueLengthLimit(DFL_MAX_VALUE_LENGTH),
|
||||||
_encoding(encoding)
|
_encoding(encoding)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HTMLForm::HTMLForm(const HTTPRequest& request, std::istream& requestBody, PartHandler& handler):
|
HTMLForm::HTMLForm(const HTTPRequest& request, std::istream& requestBody, PartHandler& handler):
|
||||||
_fieldLimit(DFL_FIELD_LIMIT)
|
_fieldLimit(DFL_FIELD_LIMIT),
|
||||||
|
_valueLengthLimit(DFL_MAX_VALUE_LENGTH)
|
||||||
{
|
{
|
||||||
load(request, requestBody, handler);
|
load(request, requestBody, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HTMLForm::HTMLForm(const HTTPRequest& request, std::istream& requestBody):
|
HTMLForm::HTMLForm(const HTTPRequest& request, std::istream& requestBody):
|
||||||
_fieldLimit(DFL_FIELD_LIMIT)
|
_fieldLimit(DFL_FIELD_LIMIT),
|
||||||
|
_valueLengthLimit(DFL_MAX_VALUE_LENGTH)
|
||||||
{
|
{
|
||||||
load(request, requestBody);
|
load(request, requestBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HTMLForm::HTMLForm(const HTTPRequest& request):
|
HTMLForm::HTMLForm(const HTTPRequest& request):
|
||||||
_fieldLimit(DFL_FIELD_LIMIT)
|
_fieldLimit(DFL_FIELD_LIMIT),
|
||||||
|
_valueLengthLimit(DFL_MAX_VALUE_LENGTH)
|
||||||
{
|
{
|
||||||
load(request);
|
load(request);
|
||||||
}
|
}
|
||||||
@ -300,7 +305,10 @@ void HTMLForm::readUrl(std::istream& istr)
|
|||||||
while (ch != eof && ch != '=' && ch != '&')
|
while (ch != eof && ch != '=' && ch != '&')
|
||||||
{
|
{
|
||||||
if (ch == '+') ch = ' ';
|
if (ch == '+') ch = ' ';
|
||||||
name += (char) ch;
|
if (name.size() < MAX_NAME_LENGTH)
|
||||||
|
name += (char) ch;
|
||||||
|
else
|
||||||
|
throw HTMLFormException("Field name too long");
|
||||||
ch = istr.get();
|
ch = istr.get();
|
||||||
}
|
}
|
||||||
if (ch == '=')
|
if (ch == '=')
|
||||||
@ -309,7 +317,10 @@ void HTMLForm::readUrl(std::istream& istr)
|
|||||||
while (ch != eof && ch != '&')
|
while (ch != eof && ch != '&')
|
||||||
{
|
{
|
||||||
if (ch == '+') ch = ' ';
|
if (ch == '+') ch = ' ';
|
||||||
value += (char) ch;
|
if (value.size() < _valueLengthLimit)
|
||||||
|
value += (char) ch;
|
||||||
|
else
|
||||||
|
throw HTMLFormException("Field value too long");
|
||||||
ch = istr.get();
|
ch = istr.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,7 +374,10 @@ void HTMLForm::readMultipart(std::istream& istr, PartHandler& handler)
|
|||||||
int ch = istr.get();
|
int ch = istr.get();
|
||||||
while (ch != eof)
|
while (ch != eof)
|
||||||
{
|
{
|
||||||
value += (char) ch;
|
if (value.size() < _valueLengthLimit)
|
||||||
|
value += (char) ch;
|
||||||
|
else
|
||||||
|
throw HTMLFormException("Field value too long");
|
||||||
ch = istr.get();
|
ch = istr.get();
|
||||||
}
|
}
|
||||||
add(name, value);
|
add(name, value);
|
||||||
@ -445,4 +459,12 @@ void HTMLForm::setFieldLimit(int limit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HTMLForm::setValueLengthLimit(int limit)
|
||||||
|
{
|
||||||
|
poco_assert (limit >= 0);
|
||||||
|
|
||||||
|
_valueLengthLimit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Net
|
} } // namespace Poco::Net
|
||||||
|
Loading…
x
Reference in New Issue
Block a user