Skip to content

Commit 5fe261d

Browse files
authored
test(appsec): isolate filesystem and browser side effects (#19693)
## Description IAST and AppSec test runs could leave filesystem artifacts in the checkout and launch the host browser. - Run path-traversal rename, copy, and move destinations in automatically cleaned temporary directories. - Run Django AppSec tests against a worker-local temporary copy of the checked-in SQLite template. - Configure the default browser for the IAST Riot environment as the no-op `true` command. This keeps the checkout clean while preserving the sink calls exercised by IAST. ## Testing - `scripts/lint checks` - `scripts/lint riot` - Focused IAST path-traversal and browser tests: 34 passed - IAST webbrowser tests under the rebuilt Riot environment: 2 passed - Django automatic user-event tests: 72 passed - Verified `tests/appsec/contrib_appsec/db.sqlite3` still matches its `HEAD` blob after the ORM tests ## Risks Low. The changes are limited to test fixtures and test-environment configuration. ## Additional Notes No release note is needed because this is a test-only change. Co-authored-by: florentin.labelle <florentin.labelle@datadoghq.com>
1 parent a24b7b3 commit 5fe261d

3 files changed

Lines changed: 35 additions & 8 deletions

File tree

riotfile.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ def select_pys(min_version: str = MIN_PYTHON_VERSION, max_version: str = MAX_PYT
376376
"pip": "<25",
377377
},
378378
env={
379+
"BROWSER": "true", # Prevent webbrowser tests from launching the host browser.
379380
"_DD_IAST_PATCH_MODULES": "benchmarks.,tests.appsec.",
380381
"DD_IAST_REQUEST_SAMPLING": "100",
381382
"DD_IAST_DEDUPLICATION_ENABLED": "false",

tests/appsec/contrib_appsec/test_django.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import importlib
22
import os
3+
from pathlib import Path
4+
import shutil
35

46
import django
57
from django.conf import settings
@@ -15,6 +17,25 @@
1517

1618
_FLAT_URLCONF = "tests.appsec.contrib_appsec.django_app.urls"
1719
_SUBAPP_URLCONF = "tests.appsec.contrib_appsec.django_app.urls_subapps"
20+
_DATABASE_TEMPLATE = Path(__file__).with_name("db.sqlite3")
21+
22+
23+
@pytest.fixture(scope="module", autouse=True)
24+
def isolated_database(tmp_path_factory):
25+
"""Use a worker-local copy of the Django database template."""
26+
database_path = tmp_path_factory.mktemp("appsec-django") / "db.sqlite3"
27+
shutil.copyfile(_DATABASE_TEMPLATE, database_path)
28+
29+
os.environ["DJANGO_SETTINGS_MODULE"] = "tests.appsec.contrib_appsec.django_app.settings"
30+
original_database_name = settings.DATABASES["default"]["NAME"]
31+
settings.DATABASES["default"]["NAME"] = str(database_path)
32+
try:
33+
yield
34+
finally:
35+
from django.db import connections
36+
37+
connections.close_all()
38+
settings.DATABASES["default"]["NAME"] = original_database_name
1839

1940

2041
class _Test_Django_Base:

tests/appsec/iast/fixtures/taint_sinks/path_traversal.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pickle
99
import shutil
1010
import tarfile
11+
import tempfile
1112
from zipfile import ZipFile
1213

1314

@@ -58,8 +59,9 @@ def path_os_remove(origin_string):
5859

5960
def path_os_rename(origin_string):
6061
try:
61-
# label path_os_rename
62-
os.rename(origin_string, "test.txt")
62+
with tempfile.TemporaryDirectory() as tmp_dir:
63+
# label path_os_rename
64+
os.rename(origin_string, os.path.join(tmp_dir, "test.txt"))
6365
except Exception:
6466
pass
6567

@@ -90,24 +92,27 @@ def path_os_listdir(origin_string):
9092

9193
def path_shutil_copy(origin_string):
9294
try:
93-
# label path_shutil_copy
94-
shutil.copy(origin_string, "not_exists.txt2")
95+
with tempfile.TemporaryDirectory() as tmp_dir:
96+
# label path_shutil_copy
97+
shutil.copy(origin_string, os.path.join(tmp_dir, "copied.txt"))
9598
except Exception:
9699
pass
97100

98101

99102
def path_shutil_copytree(origin_string):
100103
try:
101-
# label path_shutil_copytree
102-
shutil.copytree(origin_string, "not_exists.txt2")
104+
with tempfile.TemporaryDirectory() as tmp_dir:
105+
# label path_shutil_copytree
106+
shutil.copytree(origin_string, os.path.join(tmp_dir, "copied"))
103107
except Exception:
104108
pass
105109

106110

107111
def path_shutil_move(origin_string):
108112
try:
109-
# label path_shutil_move
110-
shutil.move(origin_string, "not_exists.txt2")
113+
with tempfile.TemporaryDirectory() as tmp_dir:
114+
# label path_shutil_move
115+
shutil.move(origin_string, os.path.join(tmp_dir, "moved.txt"))
111116
except Exception:
112117
pass
113118

0 commit comments

Comments
 (0)