119:34
-HTTP connection has more than 100 simultaneous pipelined requests that have not been answered.
+HTTP connection has more than maximum_pipelined_requests simultaneous pipelined requests that have
+not been answered.
119:102
http_inspect generates 119:20 when the number of headers exceeds
maximum_headers = N {0 : 65535} (default 200).
+===== maximum_pipelined_requests
+
+http_inspect generates 119:34 when the number of pipelined requests exceeds
+maximum_pipelined_requests = N {0 : 99} (default 99). This number does
+not include the first request in a sequence of requests. Setting
+maximum_pipelined_requests = 0, will not trigger an alert in the case
+of an alternating sequence of requests and responses. It will trigger the
+alert once the client issue a request before getting the response to a
+previous request.
+
===== URI processing
Normalization and inspection of the URI in the HTTP request message is a
INF_GZIP_FEXTRA = 135,
INF_METHOD_NOT_ON_ALLOWED_LIST = 136,
INF_METHOD_ON_DISALLOWED_LIST = 137,
+ INF_PIPELINE_MAX = 138,
INF__MAX_VALUE
};
uint64_t HttpFlowData::instance_count = 0;
#endif
-HttpFlowData::HttpFlowData(Flow* flow) : FlowData(inspector_id)
+HttpFlowData::HttpFlowData(Flow* flow, const HttpParaList* params_) :
+ FlowData(inspector_id), params(params_)
{
static HttpFlowStreamIntf h1_stream;
#ifdef REG_TEST
return true;
}
+int HttpFlowData::pipeline_length()
+{
+ int size = pipeline_back - pipeline_front;
+ if (size < 0)
+ size += MAX_PIPELINE;
+ return size;
+}
+
HttpTransaction* HttpFlowData::take_from_pipeline()
{
assert(!pipeline_underflow);
class HttpFlowData : public snort::FlowData
{
public:
- HttpFlowData(snort::Flow* flow);
+ HttpFlowData(snort::Flow* flow, const HttpParaList* params_);
~HttpFlowData() override;
static unsigned inspector_id;
static void init() { inspector_id = snort::FlowData::create_flow_data_id(); }
bool is_for_httpx() const { return for_httpx; }
private:
+ const HttpParaList* const params;
+
// Convenience routines
void half_reset(HttpCommon::SourceId source_id);
void trailer_prep(HttpCommon::SourceId source_id);
bool pipeline_overflow = false;
bool pipeline_underflow = false;
bool add_to_pipeline(HttpTransaction* latest);
+ int pipeline_length();
HttpTransaction* take_from_pipeline();
void delete_pipeline();
{ "maximum_headers", Parameter::PT_INT, "0:65535", "200",
"alert when the number of headers in a message exceeds this value" },
+ { "maximum_pipelined_requests", Parameter::PT_INT, "0:99", "99",
+ "alert when the number of pipelined requests exceeds this value" },
+
{ "normalize_utf", Parameter::PT_BOOL, nullptr, "true",
"normalize charset utf encodings in response bodies" },
{
params->maximum_headers = val.get_uint16();
}
+ else if (val.is("maximum_pipelined_requests"))
+ {
+ params->maximum_pipelined_requests = val.get_uint16();
+ }
else if (val.is("decompress_pdf"))
{
params->decompress_pdf = val.get_bool();
int64_t maximum_chunk_length = 0xFFFFFFFF;
uint16_t maximum_header_length = 4096;
uint16_t maximum_headers = 200;
+ uint16_t maximum_pipelined_requests = 99;
bool decompress_pdf = false;
bool decompress_swf = false;
bool decompress_zip = false;
if (session_data == nullptr)
{
- HttpInspect::http_set_flow_data(flow, session_data = new HttpFlowData(flow));
+ HttpInspect::http_set_flow_data(flow, session_data = new HttpFlowData(flow, my_inspector->params));
HttpModule::increment_peg_counts(PEG_FLOW);
}
{ EVENT_UNKNOWN_METHOD, "HTTP request method is not known to Snort" },
{ EVENT_SIMPLE_REQUEST, "HTTP request uses primitive HTTP format known as HTTP/0.9" },
{ EVENT_UNESCAPED_SPACE_URI, "HTTP request URI has space character that is not percent-encoded" },
- { EVENT_PIPELINE_MAX, "HTTP connection has more than 100 simultaneous pipelined "
- "requests that have not been answered" },
+ { EVENT_PIPELINE_MAX, "HTTP connection has more than maximum_pipelined_requests simultaneous "
+ "pipelined requests that have not been answered" },
{ EVENT_INVALID_STATCODE, "invalid status code in HTTP response" },
{ EVENT_UTF_NORM_FAIL, "HTTP response has UTF character set that failed to normalize" },
{ EVENT_UTF7, "HTTP response has UTF-7 character set" },
// now on. We just throw things away when we are done with them.
delete_transaction(session_data->transaction[SRC_CLIENT], session_data);
}
- else if (!session_data->add_to_pipeline(session_data->transaction[SRC_CLIENT]))
+ else
{
- // The pipeline is full and just overflowed.
- *session_data->infractions[source_id] += INF_PIPELINE_OVERFLOW;
- session_data->events[source_id]->create_event(EVENT_PIPELINE_MAX);
- delete_transaction(session_data->transaction[SRC_CLIENT], session_data);
+ if (!session_data->add_to_pipeline(session_data->transaction[SRC_CLIENT]))
+ {
+ // The pipeline is full and just overflowed.
+ *session_data->infractions[source_id] += INF_PIPELINE_OVERFLOW;
+ delete_transaction(session_data->transaction[SRC_CLIENT], session_data);
+ // When overflow occurs the length of the pipeline is unchanged
+ // next code ensures that the alert is still raised
+ *session_data->infractions[source_id] += INF_PIPELINE_MAX;
+ session_data->events[source_id]->create_event(EVENT_PIPELINE_MAX);
+ }
+ if (session_data->pipeline_length() > session_data->params->maximum_pipelined_requests)
+ {
+ *session_data->infractions[source_id] += INF_PIPELINE_MAX;
+ session_data->events[source_id]->create_event(EVENT_PIPELINE_MAX);
+ }
}
}
session_data->transaction[SRC_CLIENT] = new HttpTransaction(session_data);
Flow::~Flow() = default;
}
+HttpParaList::UriParam::UriParam() {}
+HttpParaList::JsNormParam::~JsNormParam() {}
+HttpParaList::~HttpParaList() {}
+
unsigned Http2FlowData::inspector_id = 0;
uint32_t Http2FlowData::get_processing_stream_id() const { return 0; }
TEST_GROUP(http_transaction_test)
{
Flow* const flow = new Flow();
- HttpFlowData* const flow_data = new HttpFlowData(flow);
+ HttpParaList params;
+ HttpFlowData* flow_data = new HttpFlowData(flow, ¶ms);
SectionType* const section_type = HttpUnitTestSetup::get_section_type(flow_data);
SectionType* const type_expected = HttpUnitTestSetup::get_type_expected(flow_data);
#define s_name "sip_method"
#define s_help \
- "detection option for sip stat code"
+ "detection option for sip method"
typedef std::unordered_map<std::string, bool> MethodMap; //Method Name => Negated