Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nodejs] create new weblog for express 5 #3572

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/lint_code/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ runs:
node-version: 20
- name: 'Run nodejs lint'
shell: bash
working-directory: ./utils/build/docker/nodejs/express4
working-directory: ./utils/build/docker/nodejs/express
run: |
npm install
npm run lint
Expand Down
2 changes: 1 addition & 1 deletion docs/execute/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Build images used for system tests.
* For `golang`: `net-http` (default), `gin`, `echo`, `chi`
+ Specific to the `GRAPHQL_APPSEC` scenario: `gqlgen`, `graph-gophers`, `graphql-go`
* For `java`: `spring-boot` (default)
* For `nodejs`: `express4` (default), `express4-typescript`, `nextjs`
* For `nodejs`: `express4` (default), `express4-typescript`, `express5`, `nextjs`
* For `php`: `apache-mod-8.1`, `apache-mod-8.0` (default), `apache-mod-7.4`, `apache-mod-7.3`, `apache-mod-7.2`, `apache-mod-7.1`, `apache-mod-7.0`, `apache-mod-8.1-zts`, `apache-mod-8.0-zts`, `apache-mod-7.4-zts`, `apache-mod-7.3-zts`, `apache-mod-7.2-zts`, `apache-mod-7.1-zts`, `apache-mod-7.0-zts`, `php-fpm-8.1`, `php-fpm-8.0`, `php-fpm-7.4`, `php-fpm-7.3`, `php-fpm-7.2`, `php-fpm-7.1`, `php-fpm-7.0`
* For `python`: `flask-poc` (default), `fastapi`, `uwsgi-poc`, `django-poc`, `python3.12`
* For `ruby`: `rails70` (default), `rack`, `sinatra21`, and lot of other sinatra/rails versions
Expand Down
31 changes: 31 additions & 0 deletions manifests/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ refs:
- &ref_5_25_0 '>=5.25.0 || ^4.49.0'
- &ref_5_26_0 '>=5.26.0 || ^4.50.0'
- &ref_5_27_0 '>=5.27.0 || ^4.51.0'
- &ref_5_29_0 '>=5.29.0 || ^4.53.0'

tests/:
apm_tracing_e2e/:
Expand All @@ -61,6 +62,7 @@ tests/:
Test_Schema_Request_FormUrlEncoded_Body:
express4: *ref_4_21_0
express4-typescript: *ref_4_21_0
express5: *ref_5_29_0
nextjs: *ref_5_3_0
Test_Schema_Request_Headers: *ref_4_21_0
Test_Schema_Request_Json_Body: *ref_4_21_0
Expand Down Expand Up @@ -155,6 +157,7 @@ tests/:
test_nosql_mongodb_injection.py:
TestNoSqlMongodbInjection:
'*': *ref_4_17_0
express5: missing_feature
nextjs: missing_feature
TestNoSqlMongodbInjection_StackTrace: missing_feature
test_path_traversal.py:
Expand Down Expand Up @@ -240,6 +243,7 @@ tests/:
test_graphql_resolver.py:
TestGraphqlResolverArgument:
'*': *ref_5_4_0
express5: missing_feature
nextjs: irrelevant # nextjs is not related with graphql
test_header_name.py:
TestHeaderName: missing_feature
Expand Down Expand Up @@ -377,6 +381,7 @@ tests/:
Test_FullGrpc: missing_feature
Test_GraphQL:
'*': *ref_4_22_0
express5: missing_feature
nextjs: irrelevant # nextjs is not related with graphql
Test_GrpcServerMethod: missing_feature
Test_Headers: v2.0.0
Expand Down Expand Up @@ -444,6 +449,7 @@ tests/:
test_blocking_addresses.py:
Test_BlockingGraphqlResolvers:
'*': *ref_4_22_0
express5: missing_feature
nextjs: irrelevant # nextjs is not related with graphql
Test_Blocking_client_ip: *ref_3_19_0
Test_Blocking_request_body:
Expand Down Expand Up @@ -558,84 +564,107 @@ tests/:
Test_Kafka:
'*': irrelevant
express4: v0.1 # real version not known
express5: *ref_5_29_0
test_kinesis.py:
Test_Kinesis_PROPAGATION_VIA_MESSAGE_ATTRIBUTES:
'*': irrelevant
express4: *ref_5_3_0
express5: *ref_5_29_0
test_rabbitmq.py:
Test_RabbitMQ_Trace_Context_Propagation:
'*': irrelevant
express4: v0.1 # real version not known
express5: *ref_5_29_0 # real version not known
test_sns_to_sqs.py:
Test_SNS_Propagation:
'*': irrelevant
express4: *ref_5_20_0
express5: *ref_5_20_0
test_sqs.py:
Test_SQS_PROPAGATION_VIA_AWS_XRAY_HEADERS:
'*': irrelevant
express4: v0.1 # real version not known
express5: *ref_5_29_0
Test_SQS_PROPAGATION_VIA_MESSAGE_ATTRIBUTES:
'*': irrelevant
express4: v0.1 # real version not known
express5: *ref_5_29_0
test_db_integrations_sql.py:
Test_MsSql:
'*': missing_feature
express4: v1.0.0
express5: *ref_5_29_0
Test_MySql:
'*': missing_feature
express4: v1.0.0
express5: *ref_5_29_0
Test_Postgres:
'*': missing_feature
express4: v1.0.0
express5: *ref_5_29_0
test_dbm.py:
Test_Dbm: missing_feature
Test_Dbm_Comment_NodeJS_mysql2:
'*': missing_feature (Missing on weblog)
express4: *ref_5_13_0
express5: *ref_5_29_0
uds-express4: *ref_5_13_0
Test_Dbm_Comment_NodeJS_pg:
'*': missing_feature (Missing on weblog)
express4: *ref_5_13_0
express5: *ref_5_29_0
uds-express4: *ref_5_13_0
test_dsm.py:
Test_DsmContext_Extraction_Base64:
'*': irrelevant
express4: *ref_5_6_0
express5: *ref_5_29_0
Test_DsmContext_Injection_Base64:
'*': irrelevant
express4: *ref_5_6_0
express5: *ref_5_29_0
Test_DsmHttp: missing_feature
Test_DsmKafka:
'*': *ref_5_25_0
express5: *ref_5_29_0
nextjs: missing_feature (missing endpoint)
Test_DsmKinesis:
'*': irrelevant
express4: *ref_5_2_0
express5: *ref_5_29_0
Test_DsmRabbitmq:
'*': irrelevant
express4: *ref_5_3_0
express5: *ref_5_29_0
Test_DsmRabbitmq_FanoutExchange:
'*': irrelevant
express4: missing_feature
express5: missing_feature
Test_DsmRabbitmq_TopicExchange:
'*': irrelevant
express4: missing_feature
express5: missing_feature
Test_DsmSNS:
'*': irrelevant
express4: *ref_5_20_0
express5: *ref_5_29_0
Test_DsmSQS:
'*': irrelevant
express4: *ref_5_2_0
express5: *ref_5_29_0
Test_Dsm_Manual_Checkpoint_Inter_Process:
'*': irrelevant
express4: *ref_5_20_0
express5: *ref_5_29_0
Test_Dsm_Manual_Checkpoint_Intra_Process:
'*': irrelevant
express4: *ref_5_20_0
express5: *ref_5_29_0
test_inferred_proxy.py:
Test_AWS_API_Gateway_Inferred_Span_Creation:
'*': irrelevant
express4: *ref_5_26_0
express5: *ref_5_29_0
test_otel_drop_in.py:
Test_Otel_Drop_In: missing_feature
k8s_lib_injection/:
Expand Down Expand Up @@ -728,10 +757,12 @@ tests/:
Test_Config_IntegrationEnabled_False:
'*': *ref_5_25_0
express4-typescript: irrelevant
express5: *ref_5_29_0
nextjs: irrelevant # nextjs is not related with kafka
Test_Config_IntegrationEnabled_True:
'*': *ref_5_25_0
express4-typescript: irrelevant
express5: *ref_5_29_0
nextjs: irrelevant # nextjs is not related with kafka
Test_Config_ObfuscationQueryStringRegexp_Configured: *ref_3_0_0
Test_Config_ObfuscationQueryStringRegexp_Empty: *ref_3_0_0
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_code_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class TestCodeInjection(BaseSinkTest):
secure_endpoint = "/iast/code_injection/test_secure"
data = {"code": "1+2"}
location_map = {
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"},
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"},
}

@missing_feature(library="nodejs", reason="Instrumented metric not implemented")
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_command_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class TestCommandInjection(BaseSinkTest):
data = {"cmd": "ls"}
location_map = {
"java": "com.datadoghq.system_tests.iast.utils.CmdExamples",
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"},
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"},
"python": {"flask-poc": "app.py", "django-poc": "app/urls.py"},
}

Expand Down
7 changes: 6 additions & 1 deletion tests/appsec/iast/sink/test_hardcoded_passwords.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ class Test_HardcodedPasswords:
"""Test Hardcoded passwords detection."""

location_map = {
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "uds-express4": "iast/index.js"},
"nodejs": {
"express4": "iast/index.js",
"express4-typescript": "iast.ts",
"express5": "iast/index.js",
"uds-express4": "iast/index.js",
},
}

insecure_request = None
Expand Down
14 changes: 12 additions & 2 deletions tests/appsec/iast/sink/test_hardcoded_secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ class Test_HardcodedSecrets:

location_map = {
"java": "com.datadoghq.system_tests.springboot.AppSecIast",
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "uds-express4": "iast/index.js"},
"nodejs": {
"express4": "iast/index.js",
"express4-typescript": "iast.ts",
"express5": "iast/index.js",
"uds-express4": "iast/index.js",
},
}

insecure_request = None
Expand All @@ -62,7 +67,12 @@ class Test_HardcodedSecretsExtended:
"""Test Hardcoded secrets extended detection."""

location_map = {
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "uds-express4": "iast/index.js"},
"nodejs": {
"express4": "iast/index.js",
"express4-typescript": "iast.ts",
"express5": "iast/index.js",
"uds-express4": "iast/index.js",
},
}

def setup_hardcoded_secrets_extended_exec(self):
Expand Down
4 changes: 3 additions & 1 deletion tests/appsec/iast/sink/test_header_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ class TestHeaderInjection(BaseSinkTest):
insecure_endpoint = "/iast/header_injection/test_insecure"
secure_endpoint = "/iast/header_injection/test_secure"
data = {"test": "dummyvalue"}
location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}}
location_map = {
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}
}

@missing_feature(context.library < "[email protected]", reason="Metrics not implemented")
@missing_feature(library="dotnet", reason="Not implemented yet")
Expand Down
4 changes: 3 additions & 1 deletion tests/appsec/iast/sink/test_insecure_cookie.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class TestInsecureCookie(BaseSinkTest):
insecure_endpoint = "/iast/insecure-cookie/test_insecure"
secure_endpoint = "/iast/insecure-cookie/test_secure"
data = {}
location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}}
location_map = {
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}
}

@bug(context.library < "[email protected]", reason="APMRP-360")
def test_secure(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_ldap_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class TestLDAPInjection(BaseSinkTest):
data = {"username": "ssam", "password": "sammy"}
location_map = {
"java": "com.datadoghq.system_tests.iast.utils.LDAPExamples",
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"},
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"},
}

@missing_feature(context.library < "[email protected]", reason="Metrics not implemented")
Expand Down
4 changes: 3 additions & 1 deletion tests/appsec/iast/sink/test_no_httponly_cookie.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class TestNoHttponlyCookie(BaseSinkTest):
insecure_endpoint = "/iast/no-httponly-cookie/test_insecure"
secure_endpoint = "/iast/no-httponly-cookie/test_secure"
data = {}
location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}}
location_map = {
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}
}

@bug(context.library < "[email protected]", reason="APMRP-360")
def test_secure(self):
Expand Down
4 changes: 3 additions & 1 deletion tests/appsec/iast/sink/test_no_samesite_cookie.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class TestNoSamesiteCookie(BaseSinkTest):
insecure_endpoint = "/iast/no-samesite-cookie/test_insecure"
secure_endpoint = "/iast/no-samesite-cookie/test_secure"
data = {}
location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}}
location_map = {
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}
}

@bug(context.library < "[email protected]", reason="APMRP-360")
def test_secure(self):
Expand Down
4 changes: 3 additions & 1 deletion tests/appsec/iast/sink/test_nosql_mongodb_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ class TestNoSqlMongodbInjection(BaseSinkTest):
insecure_endpoint = "/iast/mongodb-nosql-injection/test_insecure"
secure_endpoint = "/iast/mongodb-nosql-injection/test_secure"
data = {"key": "somevalue"}
location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}}
location_map = {
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}
}

@missing_feature(context.library < "[email protected]", reason="Not implemented yet")
@missing_feature(library="python", reason="Not implemented yet")
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_path_traversal.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class TestPathTraversal(BaseSinkTest):
data = {"path": "/var/log"}
location_map = {
"java": "com.datadoghq.system_tests.iast.utils.PathExamples",
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"},
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"},
"python": {"flask-poc": "app.py", "django-poc": "app/urls.py"},
}

Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_sql_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class TestSqlInjection(BaseSinkTest):
data = {"username": "shaquille_oatmeal", "password": "123456"}
location_map = {
"java": "com.datadoghq.system_tests.iast.utils.SqlExamples",
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"},
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"},
"python": {"flask-poc": "app.py", "django-poc": "app/urls.py"},
}

Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_ssrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class TestSSRF(BaseSinkTest):
data = {"url": "https://www.datadoghq.com"}
location_map = {
"java": "com.datadoghq.system_tests.iast.utils.SsrfExamples",
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"},
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"},
"python": {"flask-poc": "app.py", "django-poc": "app/urls.py"},
}

Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_unvalidated_redirect.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def _expected_location():
if context.weblog_variant == "vertx4":
return "com.datadoghq.vertx4.iast.routes.IastSinkRouteProvider"
if context.library.library == "nodejs":
if context.weblog_variant == "express4":
if context.weblog_variant in ("express4", "express5"):
return "iast/index.js"
if context.weblog_variant == "express4-typescript":
return "iast.ts"
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_weak_cipher.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class TestWeakCipher(BaseSinkTest):
data = None
location_map = {
"java": "com.datadoghq.system_tests.iast.utils.CryptoExamples",
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"},
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"},
}
evidence_map = {"nodejs": "des-ede-cbc", "java": "Blowfish"}

Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_weak_hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def _expected_location():
return "com.datadoghq.system_tests.iast.utils.CryptoExamples"

if context.library.library == "nodejs":
if context.weblog_variant == "express4":
if context.weblog_variant in ("express4", "express5"):
return "iast/index.js"
if context.weblog_variant == "express4-typescript":
return "iast.ts"
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/iast/sink/test_weak_randomness.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class TestWeakRandomness(BaseSinkTestWithoutTelemetry):
location_map = {
"java": "com.datadoghq.system_tests.iast.utils.WeakRandomnessExamples",
"python": {"flask-poc": "app.py", "django-poc": "app/urls.py"},
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"},
"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"},
}


Expand Down
10 changes: 8 additions & 2 deletions tests/appsec/iast/source/test_parameter_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class TestParameterName(BaseSourceTest):

setup_source_post_reported = BaseSourceTest.setup_source_reported

@missing_feature(weblog_variant="express4", reason="Tainted as request body")
@missing_feature(
context.library == "nodejs" and context.weblog_variant in ["express4", "express5"],
reason="Tainted as request body",
)
@bug(weblog_variant="resteasy-netty3", reason="APPSEC-55687")
@bug(library="python", reason="APPSEC-55689")
@missing_feature(library="dotnet", reason="Tainted as request body")
Expand All @@ -37,7 +40,10 @@ def test_source_get_reported(self):
""" for use case where only one is reported, we want to keep a test on the one reported """
self.validate_request_reported(self.requests["GET"])

@missing_feature(weblog_variant="express4", reason="Tainted as request body")
@missing_feature(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is surprising, it goes from weblog_variant == "express4" to weblog_variant not in ["express4" ...). Is it intended ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks I will fix this, the feature is currently marked as missing in nodejs.yml
The failing test in nodejs prod is expected as my PR hasn't been merged yet.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, passing the PR as draft to unstress my noti stack. You can set it back to normal once it's ready to be merged.

context.library == "nodejs" and context.weblog_variant in ["express4", "express5"],
reason="Tainted as request body",
)
@bug(context.library < "[email protected]" and context.weblog_variant == "jersey-grizzly2", reason="APPSEC-55387")
@bug(weblog_variant="resteasy-netty3", reason="APPSEC-55687")
@bug(library="python", reason="APPSEC-55689")
Expand Down
Loading
Loading