110 lines
3.7 KiB
Python
110 lines
3.7 KiB
Python
# Copyright 2016 Rackspace
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
from oslo_config import cfg
|
|
|
|
import syntribos.signal
|
|
|
|
CONF = cfg.CONF
|
|
|
|
|
|
def percentage_difference(test):
|
|
"""Validates length of two responses
|
|
|
|
Compares the length of a fuzzed response with a response to the
|
|
baseline request. If the response is longer than expected, returns
|
|
a `LengthPercentageDiffSignal`
|
|
|
|
:returns: SynSignal or None
|
|
"""
|
|
check_name = "LENGTH_DIFF"
|
|
data = {
|
|
"req1": test.init_req,
|
|
"req2": test.test_req,
|
|
"resp1": test.init_resp,
|
|
"resp2": test.test_resp,
|
|
"req1_len": len(test.init_req.body or ""),
|
|
"req2_len": len(test.test_req.body or ""),
|
|
"resp1_len": len(test.init_resp.content or ""),
|
|
"resp2_len": len(test.test_resp.content or ""),
|
|
}
|
|
data["req_diff"] = data["req2_len"] - data["req1_len"]
|
|
data["resp_diff"] = data["resp2_len"] - data["resp1_len"]
|
|
data["percent_diff"] = abs(
|
|
float(data["resp_diff"]) / (data["resp1_len"] + 1)) * 100
|
|
data["dir"] = "UNDER" if data["resp1_len"] > data["resp2_len"] else "OVER"
|
|
|
|
if data["resp1_len"] == data["resp2_len"]:
|
|
# No difference in response lengths
|
|
return None
|
|
elif data["req_diff"] == data["resp_diff"]:
|
|
# Response difference accounted for by difference in request lengths
|
|
return None
|
|
elif data["percent_diff"] < CONF.test.length_diff_percent:
|
|
# Difference not larger than configured percentage
|
|
return None
|
|
|
|
text = (
|
|
"Validate Length:\n"
|
|
"\tRequest 1 length: {0}\n"
|
|
"\tResponse 1 length: {1}\n"
|
|
"\tRequest 2 length: {2}\n"
|
|
"\tResponse 2 length: {3}\n"
|
|
"\tRequest difference: {4}\n"
|
|
"\tResponse difference: {5}\n"
|
|
"\tPercent difference: {6}%\n"
|
|
"\tDifference direction: {7}"
|
|
"\tConfig percent: {8}\n").format(
|
|
data["req1_len"], data["resp1_len"], data["req2_len"],
|
|
data["resp2_len"], data["req_diff"], data["resp_diff"],
|
|
data["percent_diff"], data["dir"], CONF.test.length_diff_percent)
|
|
|
|
slug = "LENGTH_DIFF_{dir}".format(dir=data["dir"])
|
|
|
|
return syntribos.signal.SynSignal(
|
|
text=text, slug=slug, strength=1.0, data=data, check_name=check_name)
|
|
|
|
|
|
def max_body_length(test):
|
|
"""Checks if the response body length is more than max size in the config.
|
|
|
|
Checks the response body to see if the length is more than the given length
|
|
in the config. If it is, returns a Signal.
|
|
|
|
:returns: SynSignal or None
|
|
"""
|
|
check_name = "MAX_LENGTH"
|
|
if test.init_signals.ran_check(check_name):
|
|
resp = test.init_resp
|
|
else:
|
|
resp = test.test_resp
|
|
data = {
|
|
"req": resp.request,
|
|
"resp": resp,
|
|
"req_len": len(resp.request.body or ""),
|
|
"resp_len": len(resp.content or ""),
|
|
}
|
|
text = ("Length:\n"
|
|
"\tRequest length: {0}\n"
|
|
"\tResponse length: {1}\n".format(data["req_len"],
|
|
data["resp_len"]))
|
|
slug = "OVER_MAX_LENGTH"
|
|
|
|
if data["resp_len"] > CONF.test.max_length:
|
|
return syntribos.signal.SynSignal(
|
|
text=text,
|
|
slug=slug,
|
|
strength=1.0,
|
|
data=data,
|
|
check_name=check_name)
|