Skip to content

Commit

Permalink
Format
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoEchevarria committed Nov 21, 2024
1 parent d2c66bd commit 89c9a4c
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 143 deletions.
2 changes: 1 addition & 1 deletion tests/appsec/rasp/test_libddwaf.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ class Test_Libddwaf_Version_CmdI:

def test_min_version(self):
"""Checks data in waf.init metric to verify waf version for first condition"""
min_version = [1, 20, 1]
min_version = [1, 21, 0]
check_min_version(min_version)
128 changes: 32 additions & 96 deletions tests/appsec/rasp/test_shi.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,14 @@
)


@rfc(
"https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx"
)
@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx")
@features.rasp_shell_injection
@scenarios.appsec_rasp
class Test_Shi_UrlQuery:
"""Shell Injection through query parameters"""

def setup_shi_get(self):
self.r = weblog.get(
"/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}
)
self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"})

def test_shi_get(self):
assert self.r.status_code == 403
Expand All @@ -34,30 +30,20 @@ def test_shi_get(self):
self.r,
"rasp-932-100",
{
"resource": {
"address": "server.sys.shell.cmd",
"value": "ls $(cat /etc/passwd 1>&2 ; echo .)",
},
"params": {
"address": "server.request.query",
"value": "$(cat /etc/passwd 1>&2 ; echo .)",
},
"resource": {"address": "server.sys.shell.cmd", "value": "ls $(cat /etc/passwd 1>&2 ; echo .)",},
"params": {"address": "server.request.query", "value": "$(cat /etc/passwd 1>&2 ; echo .)",},
},
)


@rfc(
"https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx"
)
@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx")
@features.rasp_shell_injection
@scenarios.appsec_rasp
class Test_Shi_BodyUrlEncoded:
"""Shell Injection through a url-encoded body parameter"""

def setup_shi_post_urlencoded(self):
self.r = weblog.post(
"/rasp/shi", data={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}
)
self.r = weblog.post("/rasp/shi", data={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"})

def test_shi_post_urlencoded(self):
assert self.r.status_code == 403
Expand All @@ -66,31 +52,21 @@ def test_shi_post_urlencoded(self):
self.r,
"rasp-932-100",
{
"resource": {
"address": "server.sys.shell.cmd",
"value": "ls $(cat /etc/passwd 1>&2 ; echo .)",
},
"params": {
"address": "server.request.body",
"value": "$(cat /etc/passwd 1>&2 ; echo .)",
},
"resource": {"address": "server.sys.shell.cmd", "value": "ls $(cat /etc/passwd 1>&2 ; echo .)",},
"params": {"address": "server.request.body", "value": "$(cat /etc/passwd 1>&2 ; echo .)",},
},
)


@rfc(
"https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx"
)
@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx")
@features.rasp_shell_injection
@scenarios.appsec_rasp
class Test_Shi_BodyXml:
"""Shell Injection through an xml body parameter"""

def setup_shi_post_xml(self):
data = "<?xml version='1.0' encoding='utf-8'?><list_dir>$(cat /etc/passwd 1>&amp;2 ; echo .)</list_dir>"
self.r = weblog.post(
"/rasp/shi", data=data, headers={"Content-Type": "application/xml"}
)
self.r = weblog.post("/rasp/shi", data=data, headers={"Content-Type": "application/xml"})

def test_shi_post_xml(self):
assert self.r.status_code == 403
Expand All @@ -99,31 +75,21 @@ def test_shi_post_xml(self):
self.r,
"rasp-932-100",
{
"resource": {
"address": "server.sys.shell.cmd",
"value": "ls $(cat /etc/passwd 1>&2 ; echo .)",
},
"params": {
"address": "server.request.body",
"value": "$(cat /etc/passwd 1>&2 ; echo .)",
},
"resource": {"address": "server.sys.shell.cmd", "value": "ls $(cat /etc/passwd 1>&2 ; echo .)",},
"params": {"address": "server.request.body", "value": "$(cat /etc/passwd 1>&2 ; echo .)",},
},
)


@rfc(
"https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx"
)
@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx")
@features.rasp_shell_injection
@scenarios.appsec_rasp
class Test_Shi_BodyJson:
"""Shell Injection through a json body parameter"""

def setup_shi_post_json(self):
"""AppSec detects attacks in JSON body values"""
self.r = weblog.post(
"/rasp/shi", json={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}
)
self.r = weblog.post("/rasp/shi", json={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"})

def test_shi_post_json(self):
assert self.r.status_code == 403
Expand All @@ -132,108 +98,80 @@ def test_shi_post_json(self):
self.r,
"rasp-932-100",
{
"resource": {
"address": "server.sys.shell.cmd",
"value": "ls $(cat /etc/passwd 1>&2 ; echo .)",
},
"params": {
"address": "server.request.body",
"value": "$(cat /etc/passwd 1>&2 ; echo .)",
},
"resource": {"address": "server.sys.shell.cmd", "value": "ls $(cat /etc/passwd 1>&2 ; echo .)",},
"params": {"address": "server.request.body", "value": "$(cat /etc/passwd 1>&2 ; echo .)",},
},
)


@rfc(
"https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y"
)
@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y")
@features.rasp_span_tags
@features.rasp_shell_injection
@scenarios.appsec_rasp
class Test_Shi_Mandatory_SpanTags:
"""Validate span tag generation on exploit attempts"""

def setup_shi_span_tags(self):
self.r = weblog.get(
"/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}
)
self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"})

def test_shi_span_tags(self):
validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration"])


@rfc(
"https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y"
)
@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y")
@features.rasp_span_tags
@features.rasp_shell_injection
@scenarios.appsec_rasp
class Test_Shi_Optional_SpanTags:
"""Validate span tag generation on exploit attempts"""

def setup_shi_span_tags(self):
self.r = weblog.get(
"/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}
)
self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"})

def test_shi_span_tags(self):
validate_span_tags(
self.r,
expected_metrics=[
"_dd.appsec.rasp.duration_ext",
"_dd.appsec.rasp.rule.eval",
],
self.r, expected_metrics=["_dd.appsec.rasp.duration_ext", "_dd.appsec.rasp.rule.eval",],
)


@rfc(
"https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.enmf90juqidf"
)
@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.enmf90juqidf")
@features.rasp_stack_trace
@features.rasp_shell_injection
@scenarios.appsec_rasp
class Test_Shi_StackTrace:
"""Validate stack trace generation on exploit attempts"""

def setup_shi_stack_trace(self):
self.r = weblog.get(
"/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}
)
self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"})

def test_shi_stack_trace(self):
assert self.r.status_code == 403
validate_stack_traces(self.r)


@rfc(
"https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y"
)
@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y")
@features.rasp_shell_injection
@scenarios.appsec_rasp
class Test_Shi_Telemetry:
"""Validate Telemetry data on exploit attempts"""

def setup_shi_telemetry(self):
self.r = weblog.get(
"/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}
)
self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"})

def test_shi_telemetry(self):
assert self.r.status_code == 403

series_eval = find_series(True, "appsec", "rasp.rule.eval")
assert series_eval
assert any(
validate_metric("rasp.rule.eval", "command_injection", s)
for s in series_eval
), [s.get("tags") for s in series_eval]
assert any(validate_metric("rasp.rule.eval", "command_injection", s) for s in series_eval), [
s.get("tags") for s in series_eval
]

series_match = find_series(True, "appsec", "rasp.rule.match")
assert series_match
assert any(
validate_metric("rasp.rule.match", "command_injection", s)
for s in series_match
), [s.get("tags") for s in series_match]
assert any(validate_metric("rasp.rule.match", "command_injection", s) for s in series_match), [
s.get("tags") for s in series_match
]


@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw")
Expand Down Expand Up @@ -265,9 +203,7 @@ def test_shi_telemetry(self):
), [s.get("tags") for s in series_match]


@rfc(
"https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx"
)
@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx")
@features.rasp_shell_injection
@scenarios.remote_config_mocked_backend_asm_dd
class Test_Shi_Capability:
Expand Down
41 changes: 7 additions & 34 deletions tests/appsec/rasp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,8 @@ def validate_stack_traces(request):
assert len(stack_ids) > 0, "no 'stack_id's present in 'triggers'"

assert "meta_struct" in span, "'meta_struct' not found in span"
assert (
"_dd.stack" in span["meta_struct"]
), "'_dd.stack' not found in 'meta_struct'"
assert (
"exploit" in span["meta_struct"]["_dd.stack"]
), "'exploit' not found in '_dd.stack'"
assert "_dd.stack" in span["meta_struct"], "'_dd.stack' not found in 'meta_struct'"
assert "exploit" in span["meta_struct"]["_dd.stack"], "'exploit' not found in '_dd.stack'"

stack_traces = span["meta_struct"]["_dd.stack"]["exploit"]
assert stack_traces, "No stack traces to validate"
Expand All @@ -65,14 +61,10 @@ def validate_stack_traces(request):

# Ensure the stack ID corresponds to an appsec event
assert "id" in stack, "'id' not found in stack trace"
assert (
stack["id"] in stack_ids
), "'id' doesn't correspond to an appsec event"
assert stack["id"] in stack_ids, "'id' doesn't correspond to an appsec event"

assert "frames" in stack, "'frames' not found in stack trace"
assert (
len(stack["frames"]) <= 32
), "stack trace above size limit (32 frames)"
assert len(stack["frames"]) <= 32, "stack trace above size limit (32 frames)"


def find_series(is_metrics: bool, namespace, metric):
Expand Down Expand Up @@ -133,28 +125,12 @@ class RC_CONSTANTS:
)
BLOCK_405 = (
"datadog/2/ASM/actions/config",
{
"actions": [
{
"id": "block",
"parameters": {"status_code": 405, "type": "json"},
"type": "block_request",
}
]
},
{"actions": [{"id": "block", "parameters": {"status_code": 405, "type": "json"}, "type": "block_request",}]},
)

BLOCK_505 = (
"datadog/2/ASM/actions/config",
{
"actions": [
{
"id": "block",
"parameters": {"status_code": 505, "type": "html"},
"type": "block_request",
}
]
},
{"actions": [{"id": "block", "parameters": {"status_code": 505, "type": "html"}, "type": "block_request",}]},
)

BLOCK_REDIRECT = (
Expand Down Expand Up @@ -187,7 +163,4 @@ def test_min_version(self):
min_version_array = list(map(int, self.min_version.split(".")))
series = find_series(True, "appsec", "waf.init")
assert series
assert any(
validate_metric_tag_version("event_rules_version", min_version_array, s)
for s in series
)
assert any(validate_metric_tag_version("event_rules_version", min_version_array, s) for s in series)
16 changes: 4 additions & 12 deletions utils/_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -1918,9 +1918,7 @@ def semantic_core_validations(test_object):
return test_object

@staticmethod
def aws_sqs_span_creationcontext_propagation_via_xray_header_with_dd_trace(
test_object,
):
def aws_sqs_span_creationcontext_propagation_via_xray_header_with_dd_trace(test_object):
"""
[AWS-SQS][Span Creation][Context Propagation][AWS X-Ray] with dd-trace
Expand All @@ -1930,9 +1928,7 @@ def aws_sqs_span_creationcontext_propagation_via_xray_header_with_dd_trace(
return test_object

@staticmethod
def aws_sqs_span_creationcontext_propagation_via_message_attributes_with_dd_trace(
test_object,
):
def aws_sqs_span_creationcontext_propagation_via_message_attributes_with_dd_trace(test_object):
"""
[AWS-SQS][Span Creation][Context Propagation][AWS Message Attributes] with dd-trace
Expand Down Expand Up @@ -2002,9 +1998,7 @@ def rabbitmq_span_creationcontext_propagation_with_dd_trace(test_object):
return test_object

@staticmethod
def aws_sns_span_creationcontext_propagation_via_message_attributes_with_dd_trace(
test_object,
):
def aws_sns_span_creationcontext_propagation_via_message_attributes_with_dd_trace(test_object):
"""
[AWS-SNS][Span Creation][Context Propagation] with dd-trace
Expand Down Expand Up @@ -2064,9 +2058,7 @@ def host_user_managed_block_list(test_object):
return test_object

@staticmethod
def aws_kinesis_span_creationcontext_propagation_via_message_attributes_with_dd_trace(
test_object,
):
def aws_kinesis_span_creationcontext_propagation_via_message_attributes_with_dd_trace(test_object):
"""
[AWS-Kinesis][Span Creation][Context Propagation] with dd-trace
Expand Down

0 comments on commit 89c9a4c

Please sign in to comment.