Skip to content

Commit 83b7d75

Browse files
committed
[http] strictly check arguments in ProduceExe
Remove all special characters, check quotes, escape quotes inside If expecting numeric value - just alphanumeric, comma, +, -, allowed
1 parent 0d368ed commit 83b7d75

2 files changed

Lines changed: 52 additions & 9 deletions

File tree

net/httpsniff/inc/TRootSnifferFull.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <string>
1717

1818
class TMemFile;
19+
class TMethodArg;
1920

2021
class TRootSnifferFull : public TRootSniffer {
2122
protected:
@@ -30,6 +31,8 @@ class TRootSnifferFull : public TRootSniffer {
3031

3132
void CreateMemFile();
3233

34+
static TString SanitizeArgument(Bool_t isstr, const char *value, Bool_t onlyquotes = kFALSE);
35+
3336
Bool_t CanDrawClass(TClass *cl) override { return IsDrawableClass(cl); }
3437

3538
Bool_t HasStreamerInfo() const override { return kTRUE; }

net/httpsniff/src/TRootSnifferFull.cxx

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,42 @@ Bool_t TRootSnifferFull::ProduceXml(const std::string &path, const std::string &
511511
return !res.empty();
512512
}
513513

514+
////////////////////////////////////////////////////////////////////////////////
515+
/// Verify argument value
516+
/// Remove special symbols, escape quotes
517+
/// If not string - only digits, literals, "+", "-", "." are allowed
518+
519+
TString TRootSnifferFull::SanitizeArgument(Bool_t isstr, const char *value, Bool_t onlyquotes)
520+
{
521+
Int_t beg = 0, end = strlen(value);
522+
if (end > 0 && isstr && value[beg] == '\"')
523+
beg++;
524+
if (end > 0 && isstr && value[end-1] == '\"')
525+
end--;
526+
TString sanitized;
527+
if (isstr)
528+
sanitized.Append("\""); // string start with quotes
529+
for(Int_t n = beg; n < end; ++n) {
530+
Char_t c = value[n];
531+
if (!isstr && !onlyquotes) {
532+
// for numeric types make very strict check
533+
if (std::isalnum(c) || std::strchr(".:+-", c))
534+
sanitized.Append(c);
535+
} else if ((c == '\"') || (c == '\\')) {
536+
// escape quotes inside string
537+
sanitized.Append('\\');
538+
sanitized.Append(c);
539+
} else if (!std::iscntrl(c)) {
540+
// exclude special chars
541+
sanitized.Append(c);
542+
}
543+
}
544+
if (isstr)
545+
sanitized.Append('\"'); // string end with quotes
546+
return sanitized;
547+
}
548+
549+
514550
////////////////////////////////////////////////////////////////////////////////
515551
/// Execute command for specified object
516552
///
@@ -636,6 +672,10 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
636672
val = sval.Data();
637673
}
638674

675+
// only value provided from outside should be sanitized
676+
// default argument value or internal pointer will not
677+
Bool_t sanitize = kFALSE;
678+
639679
if ((val != nullptr) && (strcmp(val, "_this_") == 0)) {
640680
// special case - object itself is used as argument
641681
sval.Form("(%s*)0x%zx", obj_cl->GetName(), (size_t)obj_ptr);
@@ -690,7 +730,11 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
690730
} else if (strcmp(val, "_post_length_") == 0) {
691731
sval.Form("%ld", (long)fCurrentArg->GetPostDataLength());
692732
val = sval.Data();
733+
} else {
734+
sanitize = kTRUE;
693735
}
736+
} else {
737+
sanitize = val != nullptr;
694738
}
695739

696740
if (!val)
@@ -706,15 +750,11 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
706750
if (call_args.Length() > 0)
707751
call_args += ", ";
708752

709-
if ((strcmp(arg->GetFullTypeName(), "const char*") == 0) || (strcmp(arg->GetFullTypeName(), "Option_t*") == 0)) {
710-
int len = strlen(val);
711-
if ((strlen(val) < 2) || (*val != '\"') || (val[len - 1] != '\"'))
712-
call_args.Append(TString::Format("\"%s\"", val));
713-
else
714-
call_args.Append(val);
715-
} else {
716-
call_args.Append(val);
717-
}
753+
Bool_t isstr = (strcmp(arg->GetFullTypeName(), "const char*") == 0) ||
754+
(strcmp(arg->GetFullTypeName(), "Option_t*") == 0) ||
755+
(strcmp(arg->GetFullTypeName(), "string") == 0);
756+
757+
call_args.Append(SanitizeArgument(isstr, val, !sanitize));
718758
}
719759

720760
TMethodCall *call = nullptr;

0 commit comments

Comments
 (0)