collective

Browse / github.com/storytold/artcraft-services / patch

security: triage operator tooling and dev-only findings (SonarCloud)

security: triage operator tooling and dev-only findings (SonarCloud) Second security batch for artcraft-services, after #177. - **pythonsecurity:S8702/S8705/S8707** `script/database/mysql_dump_table.py` — the table name is checked against `ALLOWED_TABLES` before any use, and `--directory` is the operator's own output folder. The findings are annotated at the four call sites with that reasoning. - **typescript:S2819** `generatePipeline.worker.ts` — a dedicated worker only receives messages from the page that created it, so `MessageEvent.origin` is always empty. - **shell:S6505** the remaining `npm install` sites need nx/esbuild/@swc/core lifecycle scripts; `--i

Status
open
Score
0.00
Adopters
0 other operators
Author
dylanmtaylor (imported from pull request #178, open)
Base
e57ee3d63ac478a24149384bf1473ef97aa067f8
Size
+26 −12 in 6 files
Review
pending
Shared
2026-10-28
Id
b8ced3d99795ae4e968100e6

How it went

No other operator has reported using it yet.

Diff

raw · frontend/build_modules.sh frontend/libs/components/pagedraw/src/lib/utilities/generatePipeline.worker.ts includes/container_includes/python_overrides/logger/__init__.py script/common/frontend_preflight.sh script/database/mysql_dump_table.py script/website/unix_frontend_webapp_dev.sh

diff --git a/frontend/build_modules.sh b/frontend/build_modules.sh--- a/frontend/build_modules.sh+++ b/frontend/build_modules.sh@@ -16,8 +16,9 @@ set -euxo pipefail  echo 'TEMPORARY HACK: Build shared frontend dependencies since nx is not finding them...' -# A 'clean' will remove nx-npm install+# A 'clean' will remove nx. nx, esbuild and @swc/core need their lifecycle scripts, so+# --ignore-scripts would leave an unusable tree.+npm install # NOSONAR  # TODO: Temp commented out nx build "@storyteller/api"diff --git a/frontend/libs/components/pagedraw/src/lib/utilities/generatePipeline.worker.ts b/frontend/libs/components/pagedraw/src/lib/utilities/generatePipeline.worker.ts--- a/frontend/libs/components/pagedraw/src/lib/utilities/generatePipeline.worker.ts+++ b/frontend/libs/components/pagedraw/src/lib/utilities/generatePipeline.worker.ts@@ -35,7 +35,9 @@ const post = (response: WorkerResponse, transfer: Transferable[] = []) => {   ); }; -self.addEventListener("message", async (event: MessageEvent<WorkerRequest>) => {+// A dedicated worker only receives messages from the page that created it; MessageEvent.origin is+// always empty here, so there is no origin to verify.+self.addEventListener("message", async (event: MessageEvent<WorkerRequest>) => { // NOSONAR   const req = event.data;   try {     if (req.type === "composite") {diff --git a/includes/container_includes/python_overrides/logger/__init__.py b/includes/container_includes/python_overrides/logger/__init__.py--- a/includes/container_includes/python_overrides/logger/__init__.py+++ b/includes/container_includes/python_overrides/logger/__init__.py@@ -1464,7 +1464,9 @@ class Manager(object):         """         return getFakeYouLogger() -        rv = None+        # Retained from the CPython logging.Manager this override replaces; the early return+        # above is the whole override.+        rv = None  # NOSONAR         if not isinstance(name, str):             raise TypeError('A logger name must be a string')         _acquireLock()@@ -2217,7 +2219,8 @@ def getLogger(name=None):     """     return getFakeYouLogger() -    if not name or isinstance(name, str) and name == root.name:+    # Retained from the CPython logging module this override replaces; see getFakeYouLogger().+    if not name or isinstance(name, str) and name == root.name:  # NOSONAR         return root     return Logger.manager.getLogger(name) diff --git a/script/common/frontend_preflight.sh b/script/common/frontend_preflight.sh--- a/script/common/frontend_preflight.sh+++ b/script/common/frontend_preflight.sh@@ -66,7 +66,9 @@ frontend_preflight() { # layout causing ENOTEMPTY rename errors), wipe node_modules and the nx cache # and retry once before giving up. frontend_npm_install() {-  if npm install; then+  # nx, esbuild and @swc/core need their lifecycle scripts, so --ignore-scripts would leave+  # an unusable tree.+  if npm install; then # NOSONAR     return 0   fi @@ -77,7 +79,7 @@ frontend_npm_install() {    rm -rf node_modules .nx -  if ! npm install; then+  if ! npm install; then # NOSONAR     echo ""     echo "ERROR: npm install failed again. See the npm output above and the"     echo "troubleshooting section in frontend/README.md."diff --git a/script/database/mysql_dump_table.py b/script/database/mysql_dump_table.py--- a/script/database/mysql_dump_table.py+++ b/script/database/mysql_dump_table.py@@ -98,7 +98,8 @@ def table_exists(conn, table_name):  def count_rows(conn, table_name):     with conn.cursor() as cursor:-        cursor.execute(f"SELECT COUNT(*) AS cnt FROM `{table_name}`")+        # table_name is checked against ALLOWED_TABLES in main() before this is reached.+        cursor.execute(f"SELECT COUNT(*) AS cnt FROM `{table_name}`")  # NOSONAR         result = cursor.fetchone()         return result["cnt"] @@ -137,7 +138,8 @@ def main():         conn.close()      # Build output path-    backup_dir.mkdir(parents=True, exist_ok=True)+    # The operator picks the output directory with --directory; this is a local backup tool.+    backup_dir.mkdir(parents=True, exist_ok=True)  # NOSONAR     timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")     output_file = backup_dir / f"{table_name}_{timestamp}.sql" @@ -170,8 +172,10 @@ def main():      print(f"\nRunning mysqldump for '{table_name}'...") -    with open(output_file, "w") as f:-        result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE, text=True)+    # output_file lives under the operator-chosen backup directory.+    with open(output_file, "w") as f:  # NOSONAR+        # argv, no shell; table_name is allowlisted and the rest comes from secrets.toml.+        result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE, text=True)  # NOSONAR      if result.returncode != 0:         print(f"Error: mysqldump failed (exit code {result.returncode})")diff --git a/script/website/unix_frontend_webapp_dev.sh b/script/website/unix_frontend_webapp_dev.sh--- a/script/website/unix_frontend_webapp_dev.sh+++ b/script/website/unix_frontend_webapp_dev.sh@@ -22,7 +22,9 @@ fi  cd "${frontend_path}" -npm install+# nx, esbuild and @swc/core need their lifecycle scripts, so --ignore-scripts would leave+# an unusable tree.+npm install # NOSONAR  export VITE_ENVIRONMENT_TYPE="production"