Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions net/http/inc/THttpServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ class THttpServer : public TNamed {

void SetReadOnly(Bool_t readonly = kTRUE);

Bool_t IsAllowPostObject() const;

void SetAllowPostObject(Bool_t allow_post_obj);

Bool_t IsWSOnly() const;

void SetWSOnly(Bool_t on = kTRUE);
Expand Down
7 changes: 7 additions & 0 deletions net/http/inc/TRootSniffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class TRootSniffer : public TNamed {
protected:
TString fObjectsPath; ///<! default path for registered objects
Bool_t fReadOnly{kTRUE}; ///<! indicate if sniffer allowed to change ROOT structures - like read objects from file
Bool_t fAllowPostObject{kFALSE}; ///<! when true allow to deserialize objects received via POST requests
Bool_t fScanGlobalDir{kTRUE}; ///<! when enabled (default), scan gROOT for histograms, canvases, open files
std::unique_ptr<TFolder> fTopFolder; ///<! own top TFolder object, used for registering objects
THttpCallArg *fCurrentArg{nullptr}; ///<! current http arguments (if any)
Expand Down Expand Up @@ -192,6 +193,12 @@ class TRootSniffer : public TNamed {
/** Returns readonly mode */
Bool_t IsReadOnly() const { return fReadOnly; }

/** Allow to deserialize object in POST requests, default off */
void SetAllowPostObject(Bool_t allow_post_obj) { fAllowPostObject = allow_post_obj; }

/** Is allowed to deserialize object in POST requests, default off */
Bool_t IsAllowPostObject() const { return fAllowPostObject; }

void Restrict(const char *path, const char *options);

Bool_t HasRestriction(const char *item_name);
Expand Down
25 changes: 25 additions & 0 deletions net/http/src/THttpServer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,31 @@ void THttpServer::SetReadOnly(Bool_t readonly)
fSniffer->SetReadOnly(readonly);
}

////////////////////////////////////////////////////////////////////////////////
/// Returns true if server accept object content in POST reequests

Bool_t THttpServer::IsAllowPostObject() const
{
return fSniffer ? fSniffer->IsAllowPostObject() : kFALSE;
}

////////////////////////////////////////////////////////////////////////////////
/// Set flag to allow receive and desereilize objects in POST requests
///
/// When object methods are executed via exe.json request,
/// one can supply object as binary/json/xml in the body of POST request
/// To allow creation of such object, one need to enable this flag
/// Use of exe.json only possible in not-readonly mode
///
/// CAUTION! This is sensitive functionality and therefore should be
/// used only when server not exposed to publicaly-accessed netowork.

void THttpServer::SetAllowPostObject(Bool_t allow_post_obj)
{
if (fSniffer)
fSniffer->SetAllowPostObject(allow_post_obj);
}

////////////////////////////////////////////////////////////////////////////////
/// returns true if only websockets are handled by the server
///
Expand Down
6 changes: 3 additions & 3 deletions net/httpsniff/src/TRootSnifferFull.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
val = sval.Data();
} else if ((val != nullptr) && (fCurrentArg != nullptr) && (fCurrentArg->GetPostData() != nullptr)) {
// process several arguments which are specific for post requests
if (strcmp(val, "_post_object_xml_") == 0) {
if (fAllowPostObject && strcmp(val, "_post_object_xml_") == 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you try to post but fAllowPostObject == false? It would be useful to have a test for this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I check that no I/O performed directly with POST data.
Data will be ignored.

// post data has extra 0 at the end and can be used as null-terminated string
post_obj = TBufferXML::ConvertFromXML((const char *)fCurrentArg->GetPostData());
if (!post_obj) {
Expand All @@ -655,7 +655,7 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
garbage.Add(post_obj);
}
val = sval.Data();
} else if (strcmp(val, "_post_object_json_") == 0) {
} else if (fAllowPostObject && strcmp(val, "_post_object_json_") == 0) {
// post data has extra 0 at the end and can be used as null-terminated string
post_obj = TBufferJSON::ConvertFromJSON((const char *)fCurrentArg->GetPostData());
if (!post_obj) {
Expand All @@ -666,7 +666,7 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
garbage.Add(post_obj);
}
val = sval.Data();
} else if ((strcmp(val, "_post_object_") == 0) && url.HasOption("_post_class_")) {
} else if (fAllowPostObject && (strcmp(val, "_post_object_") == 0) && url.HasOption("_post_class_")) {
TString clname = url.GetValueFromOptions("_post_class_");
TClass *arg_cl = gROOT->GetClass(clname, kTRUE, kTRUE);
if ((arg_cl != nullptr) && (arg_cl->GetBaseClassOffset(TObject::Class()) == 0) && (post_obj == nullptr)) {
Expand Down
Loading