Skip to content

Commit

Permalink
Update nodejs tests (#1112)
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-id authored May 25, 2023
1 parent 425c1f4 commit 86e92d6
Show file tree
Hide file tree
Showing 18 changed files with 252 additions and 830 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ reportJunit.xml
# Visual Studio
.vs/
.config/dotnet-tools.json

# Node.js
node_modules/
2 changes: 1 addition & 1 deletion docs/architecture/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The tests then wait on the results, which are available as the logs are collecte

## What are system-tests bad for?

- Combinatorial-style tests (Permutations of frameowrk runtimes, 3rd libraries versions, operating systems)
- Combinatorial-style tests (Permutations of framework runtimes, 3rd libraries versions, operating systems)
- Cloud deployments, kubernetes, distributed deployments
- Immediately knowing the reason a feature fails
- Problems or features which are not shared across tracers
Expand Down
22 changes: 14 additions & 8 deletions tests/appsec/test_blocking_addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
dotnet="2.27.0",
php_appsec="0.7.0",
python={"django-poc": "1.10", "flask-poc": "1.10", "*": "?"},
nodejs="?",
nodejs="3.19.0",
golang="1.51.0",
ruby="1.0.0",
)
Expand Down Expand Up @@ -55,6 +55,7 @@ def setup_path_params(self):
self.pp_req = weblog.get("/params/AiKfOeRcvG45")

@missing_feature(library="java", reason="When supported, path parameter detection happens on subsequent WAF run")
@missing_feature(library="nodejs", reason="Not supported yet")
@irrelevant(context.library == "ruby" and context.weblog_variant == "rack")
@irrelevant(context.library == "golang" and context.weblog_variant == "net-http")
def test_path_params(self):
Expand All @@ -75,6 +76,7 @@ def test_request_query(self):
def setup_cookies(self):
self.c_req = weblog.get("/", headers={"Cookie": "mycookie=jdfoSDGFkivRG_234"})

@missing_feature(library="nodejs", reason="Not supported yet")
def test_cookies(self):
"""can block on server.request.cookies"""

Expand All @@ -98,6 +100,7 @@ def setup_request_body_multipart(self):
@missing_feature(context.library == "dotnet", reason="Don't support multipart yet")
@missing_feature(context.library == "php", reason="Don't support multipart yet")
@missing_feature(context.library == "java", reason="Happens on a subsequent WAF run")
@missing_feature(library="nodejs", reason="Not supported yet")
@bug(context.library == "python" and context.weblog_variant == "django-poc", reason="Django bug in multipart body")
@irrelevant(context.library == "golang", reason="Body blocking happens through SDK")
def test_request_body_multipart(self):
Expand All @@ -113,6 +116,7 @@ def setup_response_status(self):
@missing_feature(context.library == "java", reason="Happens on a subsequent WAF run")
@missing_feature(context.library == "golang", reason="No blocking on server.response.*")
@missing_feature(context.library < "[email protected]")
@missing_feature(library="nodejs", reason="Not supported yet")
def test_response_status(self):
"""can block on server.response.status"""

Expand All @@ -124,6 +128,7 @@ def setup_not_found(self):

@missing_feature(context.library == "java", reason="Happens on a subsequent WAF run")
@missing_feature(context.library == "ruby", reason="Not working")
@missing_feature(library="nodejs", reason="Not supported yet")
@missing_feature(context.library == "golang", reason="No blocking on server.response.*")
def test_not_found(self):
"""can block on server.response.status"""
Expand All @@ -138,6 +143,7 @@ def setup_response_header(self):
@missing_feature(context.library == "ruby")
@missing_feature(context.library == "php", reason="Headers already sent at this stage")
@missing_feature(context.library == "dotnet", reason="Address not supported yet")
@missing_feature(library="nodejs", reason="Not supported yet")
@missing_feature(context.library == "golang", reason="No blocking on server.response.*")
def test_response_header(self):
"""can block on server.response.headers.no_cookies"""
Expand Down Expand Up @@ -178,7 +184,7 @@ def wrapper(span):
dotnet="2.29.0",
golang="1.51.0",
java="?",
nodejs="?",
nodejs="3.19.0",
php_appsec="0.7.0",
python={"django-poc": "1.10", "flask-poc": "1.10", "*": "?"},
ruby="?",
Expand Down Expand Up @@ -226,7 +232,7 @@ def test_blocking_before(self):
dotnet="?",
golang="1.51.0",
java="?",
nodejs="?",
nodejs="3.19.0",
php_appsec="0.7.0",
python={"django-poc": "1.10", "flask-poc": "1.10", "*": "?"},
ruby="?",
Expand Down Expand Up @@ -328,7 +334,7 @@ def test_blocking_before(self):
dotnet="2.29.0",
golang="1.51.0",
java="?",
nodejs="?",
nodejs="3.19.0",
php_appsec="0.7.0",
python={"django-poc": "1.10", "flask-poc": "1.10", "*": "?"},
ruby="?",
Expand Down Expand Up @@ -382,7 +388,7 @@ def test_blocking_before(self):
dotnet="2.29.0",
golang="1.51.0",
java="?",
nodejs="?",
nodejs="3.19.0",
php_appsec="0.7.0",
python={"django-poc": "1.10", "flask-poc": "1.10", "*": "?"},
ruby="?",
Expand Down Expand Up @@ -490,7 +496,7 @@ def test_blocking_before(self):
dotnet="2.29.0",
golang="?",
java="?",
nodejs="?",
nodejs="3.19.0",
php_appsec="0.7.0",
python={"django-poc": "1.10", "flask-poc": "1.10", "*": "?"},
ruby="?",
Expand Down Expand Up @@ -525,7 +531,7 @@ def test_non_blocking(self):

def setup_blocking_before(self):
self.set_req1 = weblog.post("/tag_value/clean_value_3882/200", data="None")
self.block_req2 = weblog.post("/tag_value/tainted_value_body/200", data={"value5": "bsldhkuqwgervf"},)
self.block_req2 = weblog.post("/tag_value/tainted_value_body/200", data={"value5": "bsldhkuqwgervf"})

def test_blocking_before(self):
"""Test that blocked requests are blocked before being processed"""
Expand Down Expand Up @@ -613,7 +619,7 @@ def test_non_blocking(self):

@rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking")
@coverage.not_implemented
@released(cpp="?", dotnet="2.29.0", php_appsec="0.7.0", python="?", nodejs="?", golang="?", ruby="?")
@released(cpp="?", dotnet="2.29.0", php_appsec="0.7.0", python="?", nodejs="3.19.0", golang="?", ruby="?")
class Test_Suspicious_Request_Blocking:
"""Test if blocking on multiple addresses with multiple rules is supported"""

Expand Down
12 changes: 9 additions & 3 deletions tests/appsec/test_event_tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
_is_spring_native_weblog = re.fullmatch(r"spring-.+native", context.weblog_variant) is not None


@released(dotnet="2.27.0", golang="1.47.0", java="1.8.0", nodejs="?", php_appsec="0.6.0", python="1.9.0", ruby="1.9.0")
@released(
dotnet="2.27.0", golang="1.47.0", java="1.8.0", nodejs="3.13.0", php_appsec="0.6.0", python="1.9.0", ruby="1.9.0"
)
@irrelevant(_is_spring_native_weblog, reason="GraalVM. Tracing support only")
@coverage.basic
class Test_UserLoginSuccessEvent:
Expand Down Expand Up @@ -50,7 +52,9 @@ def validate_user_login_success_tags(span):
interfaces.library.validate_spans(self.r, validate_user_login_success_tags)


@released(dotnet="2.27.0", golang="1.47.0", java="1.8.0", nodejs="?", php_appsec="0.6.0", python="1.9.0", ruby="1.9.0")
@released(
dotnet="2.27.0", golang="1.47.0", java="1.8.0", nodejs="3.13.0", php_appsec="0.6.0", python="1.9.0", ruby="1.9.0"
)
@irrelevant(_is_spring_native_weblog, reason="GraalVM. Tracing support only")
@coverage.basic
class Test_UserLoginFailureEvent:
Expand Down Expand Up @@ -87,7 +91,9 @@ def validate_user_login_failure_tags(span):
interfaces.library.validate_spans(self.r, validate_user_login_failure_tags)


@released(dotnet="2.27.0", golang="1.47.0", java="1.8.0", nodejs="?", php_appsec="0.6.0", python="1.10.0", ruby="1.9.0")
@released(
dotnet="2.27.0", golang="1.47.0", java="1.8.0", nodejs="3.13.0", php_appsec="0.6.0", python="1.10.0", ruby="1.9.0"
)
@irrelevant(_is_spring_native_weblog, reason="GraalVM. Tracing support only")
@coverage.basic
class Test_CustomEvent:
Expand Down
3 changes: 2 additions & 1 deletion tests/appsec/test_ip_blocking.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


@rfc("https://docs.google.com/document/d/1GUd8p7HBp9gP0a6PZmDY26dpGrS1Ztef9OYdbK3Vq3M/edit")
@released(cpp="?", dotnet="2.16.0", php_appsec="0.7.0", python="1.10.0", ruby="?", nodejs="?", golang="1.47.0")
@released(cpp="?", dotnet="2.16.0", php_appsec="0.7.0", python="1.10.0", ruby="?", nodejs="3.11.0", golang="1.47.0")
@released(
java={
"spring-boot": "0.110.0",
Expand All @@ -32,6 +32,7 @@
context.appsec_rules_file is not None, reason="No Remote Config sub with custom rules file",
)
@bug(context.weblog_variant == "uds-echo")
@bug("[email protected]" < context.library < "[email protected]", reason="bugged on that version range")
@coverage.basic
@scenarios.appsec_ip_blocking
class Test_AppSecIPBlocking:
Expand Down
4 changes: 2 additions & 2 deletions tests/appsec/test_ip_blocking_maxed.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


@rfc("https://docs.google.com/document/d/1GUd8p7HBp9gP0a6PZmDY26dpGrS1Ztef9OYdbK3Vq3M/edit")
@released(cpp="?", dotnet="2.16.0", php_appsec="0.7.0", python="1.10.0", ruby="?", nodejs="3.11", golang="1.47.0")
@released(cpp="?", dotnet="2.16.0", php_appsec="0.7.0", python="1.10.0", ruby="?", nodejs="3.11.0", golang="1.47.0")
@released(
java={
"spring-boot": "0.110.0",
Expand All @@ -30,7 +30,7 @@
context.appsec_rules_file is not None, reason="No Remote Config sub with custom rules file",
)
@bug(context.weblog_variant == "uds-echo")
@bug(context.library > "nodejs@3.16.0", reason="Under investigation")
@bug("[email protected]" < context.library < "nodejs@3.18.0", reason="bugged on that version range")
@coverage.basic
@scenarios.appsec_ip_blocking_maxed
class Test_AppSecIPBlockingMaxed:
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/test_request_blocking.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
EXPECTED_REQUESTS = json.load(f)


@released(cpp="?", dotnet="2.25.0", php_appsec="0.7.0", python="1.10.0", ruby="?", nodejs="?")
@released(cpp="?", dotnet="2.25.0", php_appsec="0.7.0", python="1.10.0", ruby="?", nodejs="3.19.0")
@released(
java={
"spring-boot": "1.9.0",
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/test_user_blocking.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
dotnet="2.30.0",
golang="1.48.0",
java="?",
nodejs="?",
nodejs="3.15.0",
php="0.85.0",
php_appsec="0.7.0",
python={"django-poc": "1.10", "flask-poc": "1.10", "*": "?"},
Expand Down
15 changes: 9 additions & 6 deletions tests/appsec/waf/test_blocking.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
# No trailing new line in dotnet
BLOCK_TEMPLATE_JSON_V1.rstrip(),
BLOCK_TEMPLATE_JSON_MIN_V1,
BLOCK_TEMPLATE_JSON_MIN_V1.rstrip(),
}

HTML_CONTENT_TYPES = {"text/html", "text/html; charset=utf-8", "text/html;charset=utf-8"}
Expand All @@ -52,7 +53,7 @@

@released(
dotnet="2.27.0",
nodejs="?",
nodejs="3.19.0",
php_appsec="0.7.0",
python={"django-poc": "1.10", "flask-poc": "1.10", "*": "?"},
ruby="?",
Expand Down Expand Up @@ -97,7 +98,7 @@ def setup_blocking_appsec_blocked_tag(self):
self.r_abt = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1", "Accept": "*/*"})

def test_blocking_appsec_blocked_tag(self):
"""Tag ddappsec.blocked is set when blocking"""
"""Tag appsec.blocked is set when blocking"""
assert self.r_abt.status_code == 403

interfaces.library.assert_waf_attack(
Expand Down Expand Up @@ -149,6 +150,7 @@ def setup_accept_partial_html(self):
@missing_feature(context.library == "php", reason="Support for partial html not implemented")
@missing_feature(context.library == "dotnet", reason="Support for partial html not implemented")
@missing_feature(context.library == "golang", reason="Support for partial html not implemented")
@missing_feature(context.library == "nodejs", reason="Support for partial html not implemented")
@missing_feature(context.library == "python", reason="Support for partial html not implemented")
def test_accept_partial_html(self):
"""Blocking with Accept: text/*"""
Expand Down Expand Up @@ -183,6 +185,7 @@ def setup_accept_full_html(self):

@missing_feature(context.library == "php", reason="Support for quality not implemented")
@missing_feature(context.library == "dotnet", reason="Support for quality not implemented")
@missing_feature(context.library == "nodejs", reason="Support for quality not implemented")
@bug(context.weblog_variant == "gin", reason="Block message is prepended")
def test_accept_full_html(self):
"""Blocking with Accept: text/html"""
Expand All @@ -193,19 +196,19 @@ def test_accept_full_html(self):
def setup_json_template_v1(self):
self.r_json_v1 = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1", "Accept": "application/json",},)

@released(java="1.14.0", dotnet="?", golang="?", nodejs="?", php_appsec="?", python="?", ruby="?")
@released(java="1.14.0", dotnet="?", golang="?", nodejs="4.1.0", php_appsec="?", python="?", ruby="?")
def test_json_template_v1(self):
"""HTML block template is v1 minified"""
assert self.r_json_v1.status_code == 403
assert self.r_json_v1.headers.get("content-type", "") in JSON_CONTENT_TYPES
assert self.r_json_v1.text == BLOCK_TEMPLATE_JSON_MIN_V1
assert self.r_json_v1.text.rstrip() == BLOCK_TEMPLATE_JSON_MIN_V1.rstrip()

def setup_html_template_v2(self):
self.r_html_v2 = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1", "Accept": "text/html",},)

@released(java="1.14.0", dotnet="?", golang="?", nodejs="?", php_appsec="?", python="?", ruby="?")
@released(java="1.14.0", dotnet="?", golang="?", nodejs="4.1.0", php_appsec="?", python="?", ruby="?")
def test_html_template_v2(self):
"""HTML block template is v1 minified"""
"""HTML block template is v2 minified"""
assert self.r_html_v2.status_code == 403
assert self.r_html_v2.headers.get("content-type", "") in HTML_CONTENT_TYPES
assert self.r_html_v2.text == BLOCK_TEMPLATE_HTML_MIN_V2
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/waf/test_custom_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
java="?",
dotnet="2.30.0",
golang="1.51.0",
nodejs="?",
nodejs="4.1.0",
php_appsec="0.8.1",
python={"django-poc": "1.12", "flask-poc": "1.12", "*": "?"},
ruby="?",
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/waf/test_exclusions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
java="1.6.0",
dotnet="2.26.0",
golang="?",
nodejs="?",
nodejs="3.19.0",
php_appsec="0.7.0",
python={"django-poc": "1.12", "flask-poc": "1.12", "*": "?"},
ruby="?",
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/waf/test_miscs.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def test_same_location(self):

@released(golang={"gin": "1.37.0", "echo": "1.36.0", "chi": "1.36.0", "*": "1.34.0"})
@released(dotnet="1.28.6", java="0.87.0", php_appsec="0.1.0", python="1.1.0")
@bug(library="nodejs", reason="current releases are buggy")
@bug(context.library < "nodejs@3.19.0", reason="fixed in a waf update")
@missing_feature(context.weblog_variant == "spring-boot-native", reason="GraalVM. Tracing support only")
@missing_feature(context.weblog_variant == "spring-boot-3-native", reason="GraalVM. Tracing support only")
@coverage.good
Expand Down
6 changes: 4 additions & 2 deletions tests/remote_config/test_remote_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
class Test_Agent:
""" misc test on agent/remote config features"""

@missing_feature(library="nodejs", reason="nodejs tracer does not call /info")
@irrelevant(library="nodejs", reason="nodejs tracer does not call /info")
@missing_feature(library="ruby", reason="ruby tracer does not call /info")
@irrelevant(library="cpp")
@scenarios.remote_config_mocked_backend_asm_dd
Expand Down Expand Up @@ -311,7 +311,7 @@ def validate(data):


@rfc("https://docs.google.com/document/d/1u_G7TOr8wJX0dOM_zUDKuRJgxoJU_hVTd5SeaMucQUs/edit#heading=h.octuyiil30ph")
@released(cpp="?", dotnet="2.15.0", java="1.4.0", php_appsec="0.7.0", python="?", ruby="?", nodejs="?")
@released(cpp="?", dotnet="2.15.0", java="1.4.0", php_appsec="0.7.0", python="?", ruby="?", nodejs="3.19.0")
@released(golang="?")
@coverage.basic
@scenarios.remote_config_mocked_backend_asm_dd
Expand Down Expand Up @@ -384,6 +384,7 @@ def validate(data):

@rfc("https://docs.google.com/document/d/1u_G7TOr8wJX0dOM_zUDKuRJgxoJU_hVTd5SeaMucQUs/edit#heading=h.octuyiil30ph")
@released(cpp="?", dotnet="2.15.0", golang="?", java="?", php="?", python="?", ruby="?", nodejs="?")
@irrelevant(library="nodejs", reason="cache is implemented")
@irrelevant(library="dotnet", reason="cache is implemented")
@coverage.basic
@scenarios.remote_config_mocked_backend_live_debugging_nocache
Expand Down Expand Up @@ -413,6 +414,7 @@ def validate(data):

@rfc("https://docs.google.com/document/d/1u_G7TOr8wJX0dOM_zUDKuRJgxoJU_hVTd5SeaMucQUs/edit#heading=h.octuyiil30ph")
@released(cpp="?", dotnet="2.15.0", java="?", php_appsec="0.7.0", python="?", ruby="?", nodejs="?")
@irrelevant(library="nodejs", reason="cache is implemented")
@irrelevant(library="dotnet", reason="cache is implemented")
@irrelevant(library="php", reason="cache is implemented")
@irrelevant(library="golang", reason="cache is implemented")
Expand Down
Loading

0 comments on commit 86e92d6

Please sign in to comment.