diff --git a/ChangeLog b/ChangeLog index e0938b9c..546b1634 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24124,3 +24124,7 @@ 2023-05-17 Fred Gleason * Fixed a regression in the WebAPI that caused imports to bypass the maximum file size limitation set the 'System Settings' in rdadmin(1). +2023-05-17 Fred Gleason + * Fixed a vulnerabilities in 'RDFormPost' that could allow maximum + post length restrictions to be bypassed by use of a maliciously + crafted HTTP transaction. diff --git a/lib/rdformpost.cpp b/lib/rdformpost.cpp index a3cd7097..197c2323 100644 --- a/lib/rdformpost.cpp +++ b/lib/rdformpost.cpp @@ -2,7 +2,7 @@ // // Handle data from an HTML form. // -// (C) Copyright 2009-2021 Fred Gleason +// (C) Copyright 2009-2023 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -43,6 +43,7 @@ RDFormPost::RDFormPost(RDFormPost::Encoding encoding,int64_t maxsize, post_auto_delete=auto_delete; post_data=NULL; post_tempdir=NULL; + post_bytes_downloaded=0; // // Client Info @@ -101,7 +102,13 @@ RDFormPost::RDFormPost(RDFormPost::Encoding encoding,int64_t maxsize, // (Perhaps) autodetect the encoding type // char first[2]; - RDCheckExitCode("RDFormPost::RDFormPost read",read(0,first,1)); + ssize_t s; + + if((s=read(0,first,1))<=0) { + post_error=RDFormPost::ErrorMalformedData; + return; + } + post_bytes_downloaded+=1; if(post_encoding==RDFormPost::AutoEncoded) { if(first[0]=='-') { post_encoding=RDFormPost::MultipartEncoded; @@ -138,9 +145,11 @@ RDFormPost::~RDFormPost() if(post_tempdir!=NULL) { delete post_tempdir; } + /* if(post_data!=NULL) { delete post_data; } + */ } } @@ -563,12 +572,13 @@ void RDFormPost::LoadUrlEncoding(char first) post_error=RDFormPost::ErrorMalformedData; return; } + post_bytes_downloaded+=n; total_read+=n; } - // post_data[post_content_length]=0; post_data[total_read]=0; lines=QString(post_data).split("&"); + for(int i=0;itrimmed(); } @@ -721,13 +757,18 @@ bool RDFormPost::GetMimePart(QString *name,QString *value,bool *is_file) } -QByteArray RDFormPost::GetLine() const +QByteArray RDFormPost::GetLine(bool *ok) { char *data=NULL; size_t n=0; - n=getline(&data,&n,post_stream); + if((n=getline(&data,&n,post_stream))<0) { + *ok=false; + } + post_bytes_downloaded+=n; QByteArray ret(data,n); free(data); + *ok=true; + return ret; } diff --git a/lib/rdformpost.h b/lib/rdformpost.h index 8d50ac4f..bef0f8a3 100644 --- a/lib/rdformpost.h +++ b/lib/rdformpost.h @@ -2,7 +2,7 @@ // // Handle POST data from an HTML form. // -// (C) Copyright 2009-2020 Fred Gleason +// (C) Copyright 2009-2023 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -67,8 +67,8 @@ class RDFormPost private: void LoadUrlEncoding(char first); void LoadMultipartEncoding(char first); - bool GetMimePart(QString *name,QString *value,bool *is_file); - QByteArray GetLine() const; + bool GetMimePart(QString *name,QString *value,bool *is_file,bool *ok); + QByteArray GetLine(bool *ok); QHostAddress post_client_address; RDFormPost::Encoding post_encoding; RDFormPost::Error post_error; @@ -79,6 +79,7 @@ class RDFormPost int64_t post_content_length; QString post_content_type; char *post_data; + int64_t post_bytes_downloaded; QString post_separator; FILE *post_stream; };