Skip to content

fix coverity and codeql high severity issues#245

Open
guptagunjan wants to merge 1 commit into
TNG:devfrom
guptagunjan:gg/fix-cov
Open

fix coverity and codeql high severity issues#245
guptagunjan wants to merge 1 commit into
TNG:devfrom
guptagunjan:gg/fix-cov

Conversation

@guptagunjan

@guptagunjan guptagunjan commented Jun 23, 2026

Copy link
Copy Markdown

Description:

Please provide a brief description of the changes made in this pull request.

Related Issue:

If this pull request is related to any existing issue, please mention the issue number here.

Changes Made:

Please list down the specific changes made in this pull request.

Testing Done:

Please describe the testing that has been done to ensure the changes made in this pull request are functioning as expected.

Screenshots:

If applicable, please provide screenshots or GIFs or videos to visually demonstrate the changes made.

Checklist:

  • I have tested the changes locally.
  • I have self-reviewed the code changes.
  • I have updated the documentation, if necessary.

Summary by CodeRabbit

  • Security

    • Enhanced XSS protection in Markdown and dialog components via DOMPurify sanitization and plain-text rendering
    • Added path traversal validation in file downloads
    • Improved log sanitization to prevent injection attacks
    • Enhanced cookie security settings for authentication
  • Bug Fixes

    • Improved error handling and resilience in Electron launcher initialization and ZIP validation
    • Fixed variable scope issues in history page rendering
    • Strengthened subprocess execution for folder operations and git commands
  • Improvements

    • Upgraded embedding cache hashing from MD5 to SHA-256
    • Enhanced logging with parameterized messages and sanitization

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR applies security hardening across the frontend, Electron main process, and Python services: Vue components replace v-html with plain text interpolation and add DOMPurify to the markdown renderer; Electron IPC handlers switch from shell-invoking exec to spawn/execFile; Python log statements sanitize CRLF characters; the model downloader gains a path-traversal containment check; and langchain hashing upgrades from MD5 to SHA-256.

Changes

Security Hardening

Layer / File(s) Summary
Frontend v-html removal and DOMPurify addition
WebUI/src/components/LoadingBar.vue, WebUI/src/components/WarningDialog.vue, WebUI/src/components/AddLLMDialog.vue, WebUI/src/components/ProgressBar.vue, WebUI/src/components/MarkdownRenderer.vue
LoadingBar, WarningDialog, AddLLMDialog, and ProgressBar switch from v-html bindings to plain text interpolation; MarkdownRenderer wraps its existing sanitization with an additional DOMPurify.sanitize(...) call.
Electron subprocess shell injection prevention
WebUI/electron/main.ts, WebUI/electron/subprocesses/comfyuiTools.ts
Explorer IPC handlers replace exec command strings with spawn('explorer.exe', [...], {shell:false, detached:true}); git operations replace execAsync shell strings with execFileAsync argument arrays for clone, checkout, and rev-parse.
MD5 to SHA-256 upgrade
WebUI/electron/subprocesses/langchain.ts
Both the embedding cache namespace hash and the file hash computation switch from createHash('md5') to createHash('sha256').
Python CRLF log injection sanitization and auth cookie hardening
service/web_api.py, service/utils.py, comfyui-deps/custom_nodes/aipg-auth/middleware.py
Log messages in web_api.py and utils.py sanitize \n/\r from request fields and switch to parameterized logging; previously silent pass blocks emit logging.warning. Middleware sanitizes Host, method, and path in rejection logs; the /aipg/launch cookie gains secure=False and max_age=86400.
Path traversal containment in model downloader
service/model_downloader.py
build_queue sanitizes each file's relpath, resolves the absolute destination, verifies it remains within save_path_tmp, and skips entries that escape the boundary with a warning log.
Build script resilience
WebUI/build/scripts/after-pack.cjs, WebUI/build/scripts/ensure-electron.mjs
after-pack.cjs wraps Linux launcher-baking in try/catch with a prefixed rethrow message; ensure-electron.mjs removes the existsSync guard from looksLikeZip and converts the cache-ZIP cleanup to a try/catch with force:true deletion.
Template literals, let scoping, and pass annotations
WebUI/src/assets/js/store/comfyUiPresets.ts, service/static/assets/history.js, comfyui-deps/custom_nodes/OpenVINOImageUpscale/nodes.py
extractCustomNodeInfo errors interpolate workflowNodeInfoString via template literals; history.js introduces block-scoped let for pos and filename; OpenVINO pass statements gain inline comments.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 No more raw HTML in sight,
The shell strings banished overnight.
MD5 retired, SHA-256 glows,
Log injectors stubbed by carriage-return foes.
Path traversal? Caught before it grows!
The warren is safe — and the diff history shows.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is entirely a blank template with no actual content filled in—all required sections lack substantive information about the changes, testing, or related issues. Complete all template sections with specific details: describe the vulnerabilities fixed, list concrete changes per file, explain testing performed, and reference related issues.
Docstring Coverage ⚠️ Warning Docstring coverage is 41.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main objective of the PR: fixing high-severity security and code quality issues from Coverity and CodeQL.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Warning

⚠️ This pull request shows signs of AI-generated slop (description_diff_mismatch, ai_padded_prose). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
WebUI/src/components/MarkdownRenderer.vue (1)

37-48: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Sanitize the fallback before assigning to v-html.

The normal path now uses DOMPurify, but the catch path still writes raw content into renderedHtml; Line 82 renders that with v-html, so any input that trips the catch bypasses the new sanitizer.

Proposed fix
   } catch (error) {
     console.error('Failed to process markdown:', error)
-    renderedHtml.value = content.replace(/\n/g, '<br>')
+    renderedHtml.value = DOMPurify.sanitize(content.replace(/\n/g, '<br>'), {
+      ALLOWED_TAGS: ['br'],
+      ALLOWED_ATTR: [],
+    })
   } finally {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@WebUI/src/components/MarkdownRenderer.vue` around lines 37 - 48, The catch
block's fallback HTML assignment to renderedHtml.value is missing sanitization,
creating a security vulnerability since this value is rendered with v-html. In
the catch block where you assign the fallback content with
content.replace(/\n/g, '<br>'), wrap that assignment with DOMPurify.sanitize()
to match the sanitization applied in the normal code path, ensuring all HTML
rendered to the DOM is properly sanitized regardless of error conditions.
🧹 Nitpick comments (3)
WebUI/electron/subprocesses/langchain.ts (1)

142-145: 🗄️ Data Integrity & Integration | 🔵 Trivial

Rename function to match implementation: use generateFileSha256Hash instead of generateFileMD5Hash.

The function at line 142 computes SHA-256 but is named generateFileMD5Hash, creating a misleading API. While RagFileItem.md5: string exists in type definitions, it appears to be unused; the active data structure is IndexedDocument.hash in textInference.ts, which treats the hash as an opaque string for deduplication and state management—SHA-256's 64-character format doesn't break equality checks or downstream logic. However, the naming mismatch is a code clarity issue that should be resolved.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@WebUI/electron/subprocesses/langchain.ts` around lines 142 - 145, Rename the
function `generateFileMD5Hash` to `generateFileSha256Hash` to accurately reflect
the actual implementation. The function computes SHA-256 hashes (as seen in the
`createHash('sha256')` call) rather than MD5, so the function name should be
updated to match the algorithm being used. This improves code clarity and
prevents confusion for developers using this function.
service/model_downloader.py (1)

180-182: 📐 Maintainability & Code Quality | 🔵 Trivial

Redundant safe_relpath ternary; consider a clearer containment check.

The conditional on line 180 collapses to a no-op: when path.dirname(file.relpath) == '', the file has no directory component, so path.basename(file.relpath) returns the same value as file.relpath. Both branches yield the same result, reducing the logic to just path.normpath(file.relpath).

The containment check itself is sound: absolute paths, path traversal attempts with ../, and join-discard cases all resolve outside save_path_tmp and get correctly rejected. The startswith(... + os.sep) pattern works, but Path.is_relative_to or os.path.commonpath expresses the intent more idiomatically and avoids the long line.

The unsanitized file.relpath passed downstream to HFDownloadItem is safe—it's stored as the item's name but never used for filesystem operations; all file I/O in init_download uses the sanitized save_filename.

Since the project targets Python 3.12, Path.is_relative_to (available since 3.9) is viable.

♻️ Suggested simplification
-            # Prevent path traversal: verify resolved path stays within save_path_tmp
-            safe_relpath = path.normpath(path.basename(file.relpath) if path.dirname(file.relpath) == '' else file.relpath)
-            save_filename = path.abspath(path.join(self.save_path_tmp, safe_relpath))
-            if not save_filename.startswith(path.abspath(self.save_path_tmp) + os.sep):
-                logging.warning(f'Skipping file with path traversal attempt: {file.relpath}')
-                continue
+            # Prevent path traversal: verify resolved path stays within save_path_tmp
+            base_tmp = Path(self.save_path_tmp).resolve()
+            save_path = (base_tmp / path.normpath(file.relpath)).resolve()
+            if not save_path.is_relative_to(base_tmp):
+                logging.warning(f'Skipping file with path traversal attempt: {file.relpath}')
+                continue
+            save_filename = str(save_path)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@service/model_downloader.py` around lines 180 - 182, Simplify the ternary
operator on line 180 that assigns to safe_relpath, as both branches of the
condition yield the same result—just use path.normpath(file.relpath) directly.
Additionally, replace the containment check pattern on line 182 that uses
startswith with os.sep concatenation; instead, convert save_filename and the
save_path_tmp directory to Path objects and use the is_relative_to method, which
is idiomatic for Python 3.9+ and available in the project's Python 3.12 target,
making the intent clearer and the code more readable.
WebUI/build/scripts/after-pack.cjs (1)

46-47: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Preserve the original error as cause when rethrowing.

Line 47 currently drops the original stack/context, which makes packaging failures harder to diagnose.

Suggested patch
-  } catch (error) {
-    throw new Error(`afterPack failed: ${error.message}`)
+  } catch (error) {
+    const message = error instanceof Error ? error.message : String(error)
+    throw new Error(`afterPack failed: ${message}`, {
+      cause: error instanceof Error ? error : undefined
+    })
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@WebUI/build/scripts/after-pack.cjs` around lines 46 - 47, The catch block in
the afterPack function is rethrowing an error with only the message, which drops
the original error's stack trace and context. When throwing the new Error on
line 47, add the original error as the cause by passing an options object as the
second parameter to the Error constructor with the caught error assigned to the
cause property. This preserves the full error chain for better debugging of
packaging failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@service/web_api.py`:
- Line 16: The logging module is referenced in the logging.warning() calls at
lines 16 and 50 but is not imported at the top of the file, which will cause a
NameError at runtime. Add `import logging` at the beginning of the
service/web_api.py file, before any code that uses logging.warning(), to resolve
the undefined name error.

In `@WebUI/build/scripts/ensure-electron.mjs`:
- Around line 111-117: The empty catch block in the try-catch statement around
the looksLikeZip and rmSync calls silently swallows filesystem errors without
logging them, making it difficult to debug Electron setup failures. Instead of
an empty catch block, capture the error parameter and log it using the log
function with descriptive context about what operation failed (e.g., cache
validation or removal), include the actual error details, and consider whether
setup should continue or fail based on the error type.

In `@WebUI/electron/subprocesses/comfyuiTools.ts`:
- Line 101: The Git clone and checkout commands are vulnerable to option
injection because Git interprets arguments starting with dashes as options
rather than values. In the execFileAsync call for the clone command at line 101,
add the `--` terminator after the clone subcommand to stop Git from treating
subsequent arguments as options. Similarly, apply the same fix to the checkout
command at line 129. Additionally, before the checkout operation, validate and
reject any git references (refs) that start with a leading dash to prevent them
from being interpreted as Git options, ensuring only safe ref names are passed
to the git checkout command.

In `@WebUI/src/components/LoadingBar.vue`:
- Line 3: The issue is that util.html2Escape() is being called on porps.text
before Vue interpolation, which causes double escaping since Vue's {{ ... }}
syntax already handles HTML escaping automatically. This will result in HTML
entities being displayed as visible text (like &lt; instead of <). Remove the
util.html2Escape() function wrapper and update the interpolation in the
LoadingBar component to use {{ porps.text }} directly without any additional
escaping.

---

Outside diff comments:
In `@WebUI/src/components/MarkdownRenderer.vue`:
- Around line 37-48: The catch block's fallback HTML assignment to
renderedHtml.value is missing sanitization, creating a security vulnerability
since this value is rendered with v-html. In the catch block where you assign
the fallback content with content.replace(/\n/g, '<br>'), wrap that assignment
with DOMPurify.sanitize() to match the sanitization applied in the normal code
path, ensuring all HTML rendered to the DOM is properly sanitized regardless of
error conditions.

---

Nitpick comments:
In `@service/model_downloader.py`:
- Around line 180-182: Simplify the ternary operator on line 180 that assigns to
safe_relpath, as both branches of the condition yield the same result—just use
path.normpath(file.relpath) directly. Additionally, replace the containment
check pattern on line 182 that uses startswith with os.sep concatenation;
instead, convert save_filename and the save_path_tmp directory to Path objects
and use the is_relative_to method, which is idiomatic for Python 3.9+ and
available in the project's Python 3.12 target, making the intent clearer and the
code more readable.

In `@WebUI/build/scripts/after-pack.cjs`:
- Around line 46-47: The catch block in the afterPack function is rethrowing an
error with only the message, which drops the original error's stack trace and
context. When throwing the new Error on line 47, add the original error as the
cause by passing an options object as the second parameter to the Error
constructor with the caught error assigned to the cause property. This preserves
the full error chain for better debugging of packaging failures.

In `@WebUI/electron/subprocesses/langchain.ts`:
- Around line 142-145: Rename the function `generateFileMD5Hash` to
`generateFileSha256Hash` to accurately reflect the actual implementation. The
function computes SHA-256 hashes (as seen in the `createHash('sha256')` call)
rather than MD5, so the function name should be updated to match the algorithm
being used. This improves code clarity and prevents confusion for developers
using this function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d47e7e17-6e3c-4295-8983-7cfbcfe25b05

📥 Commits

Reviewing files that changed from the base of the PR and between ad82e19 and 7e28003.

📒 Files selected for processing (17)
  • WebUI/build/scripts/after-pack.cjs
  • WebUI/build/scripts/ensure-electron.mjs
  • WebUI/electron/main.ts
  • WebUI/electron/subprocesses/comfyuiTools.ts
  • WebUI/electron/subprocesses/langchain.ts
  • WebUI/src/assets/js/store/comfyUiPresets.ts
  • WebUI/src/components/AddLLMDialog.vue
  • WebUI/src/components/LoadingBar.vue
  • WebUI/src/components/MarkdownRenderer.vue
  • WebUI/src/components/ProgressBar.vue
  • WebUI/src/components/WarningDialog.vue
  • comfyui-deps/custom_nodes/OpenVINOImageUpscale/nodes.py
  • comfyui-deps/custom_nodes/aipg-auth/middleware.py
  • service/model_downloader.py
  • service/static/assets/history.js
  • service/utils.py
  • service/web_api.py

Comment thread service/web_api.py
sys.addaudithook(auditor)
except Exception:
pass
logging.warning('Failed to install audit hook - optional feature')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Missing logging module import causes runtime NameError.

Lines 16 and 50 reference logging.warning() but the logging module is not imported. This will cause a NameError at runtime when the audit hook fails to install or when torchvision is unavailable. Ruff correctly flags this as F821 (undefined name).

Add import logging at the top of the file to resolve this critical issue.

Also applies to: 50-50

🧰 Tools
🪛 GitHub Actions: Ruff / 0_ruff.txt

[error] 16-16: Ruff: Undefined name logging (F821).

🪛 GitHub Actions: Ruff / ruff

[error] 16-16: Ruff (rule F821): Undefined name logging.

🪛 GitHub Check: ruff

[failure] 16-16: ruff (F821)
service/web_api.py:16:5: F821 Undefined name logging

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@service/web_api.py` at line 16, The logging module is referenced in the
logging.warning() calls at lines 16 and 50 but is not imported at the top of the
file, which will cause a NameError at runtime. Add `import logging` at the
beginning of the service/web_api.py file, before any code that uses
logging.warning(), to resolve the undefined name error.

Source: Linters/SAST tools

Comment on lines +111 to +117
try {
if (!looksLikeZip(cacheZip)) {
log('Cached Electron zip is invalid/partial — removing it.')
rmSync(cacheZip, { force: true })
}
} catch {
// If file doesn't exist or other error, rmSync with force: true will handle it

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Don’t silently swallow cache invalidation failures.

This catch {} masks real filesystem errors (e.g., permissions/EBUSY), making Electron setup failures non-actionable.

Suggested patch
 try {
   if (!looksLikeZip(cacheZip)) {
     log('Cached Electron zip is invalid/partial — removing it.')
     rmSync(cacheZip, { force: true })
   }
-} catch {
-  // If file doesn't exist or other error, rmSync with force: true will handle it
+} catch (error) {
+  const detail = error instanceof Error ? error.message : String(error)
+  log(`Cache zip validation/invalidation failed: ${detail}`)
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
if (!looksLikeZip(cacheZip)) {
log('Cached Electron zip is invalid/partial — removing it.')
rmSync(cacheZip, { force: true })
}
} catch {
// If file doesn't exist or other error, rmSync with force: true will handle it
try {
if (!looksLikeZip(cacheZip)) {
log('Cached Electron zip is invalid/partial — removing it.')
rmSync(cacheZip, { force: true })
}
} catch (error) {
const detail = error instanceof Error ? error.message : String(error)
log(`Cache zip validation/invalidation failed: ${detail}`)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@WebUI/build/scripts/ensure-electron.mjs` around lines 111 - 117, The empty
catch block in the try-catch statement around the looksLikeZip and rmSync calls
silently swallows filesystem errors without logging them, making it difficult to
debug Electron setup failures. Instead of an empty catch block, capture the
error parameter and log it using the log function with descriptive context about
what operation failed (e.g., cache validation or removal), include the actual
error details, and consider whether setup should continue or fail based on the
error type.

removeExistingResource(absoluteTargetDir)
const gitPath = getGitBinaryPath()
await execAsync(`"${gitPath}" clone ${gitRepoUrl} "${absoluteTargetDir}"`)
await execFileAsync(gitPath, ['clone', gitRepoUrl, absoluteTargetDir])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Inspect Git subprocess sinks and nearby validation.
rg -n -C4 "execFileAsync\\(gitPath, \\['(clone|checkout|rev-parse)'" WebUI/electron/subprocesses/comfyuiTools.ts

Repository: TNG/AI-Playground

Length of output: 1471


🏁 Script executed:

cat -n WebUI/electron/subprocesses/comfyuiTools.ts

Repository: TNG/AI-Playground

Length of output: 19164


Block Git option injection at the argument boundary.

execFile removes shell injection, but Git still treats leading-dash values as options. Terminate clone options with -- and reject leading-dash refs before checkout.

Proposed fix
 async function installGitRepo(gitRepoUrl: string, targetDir: string): Promise<void> {
   try {
     // Ensure targetDir is an absolute path
     const absoluteTargetDir = path.resolve(targetDir)
     removeExistingResource(absoluteTargetDir)
     const gitPath = getGitBinaryPath()
-    await execFileAsync(gitPath, ['clone', gitRepoUrl, absoluteTargetDir])
+    const trimmedGitRepoUrl = gitRepoUrl.trim()
+    if (trimmedGitRepoUrl.startsWith('-')) {
+      throw new Error('Invalid git repository URL')
+    }
+    await execFileAsync(gitPath, ['clone', '--', trimmedGitRepoUrl, absoluteTargetDir])
     appLoggerInstance.info(`Cloned ${gitRepoUrl} into ${absoluteTargetDir}`, 'comfyui-tools')
   } catch (error) {
 async function checkoutGitRef(repoDir: string, gitRef?: string): Promise<void> {
   // Ensure repoDir is an absolute path
   const absoluteRepoDir = path.resolve(repoDir)
-  if (!gitRef || !gitRef.trim()) {
+  const trimmedGitRef = gitRef?.trim()
+  if (!trimmedGitRef) {
     appLoggerInstance.info(`No valid git ref provided for ${absoluteRepoDir}`, 'comfyui-tools')
     const currentRef = await getGitRef(absoluteRepoDir)
     appLoggerInstance.warn(`Repo ${absoluteRepoDir} remains in ref ${currentRef}`, 'comfyui-tools')
     return
   }
+  if (trimmedGitRef.startsWith('-')) {
+    appLoggerInstance.warn(`Invalid git ref provided for ${absoluteRepoDir}`, 'comfyui-tools')
+    return
+  }
 
   try {
     const gitPath = getGitBinaryPath()
-    await execFileAsync(gitPath, ['checkout', gitRef], { cwd: absoluteRepoDir })
-    appLoggerInstance.info(`Checked out ${gitRef} in ${absoluteRepoDir}`, 'comfyui-tools')
+    await execFileAsync(gitPath, ['checkout', trimmedGitRef], { cwd: absoluteRepoDir })
+    appLoggerInstance.info(`Checked out ${trimmedGitRef} in ${absoluteRepoDir}`, 'comfyui-tools')

Also applies to: 129-129

🧰 Tools
🪛 ast-grep (0.44.0)

[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { exec, execFile } from 'node:child_process'
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@WebUI/electron/subprocesses/comfyuiTools.ts` at line 101, The Git clone and
checkout commands are vulnerable to option injection because Git interprets
arguments starting with dashes as options rather than values. In the
execFileAsync call for the clone command at line 101, add the `--` terminator
after the clone subcommand to stop Git from treating subsequent arguments as
options. Similarly, apply the same fix to the checkout command at line 129.
Additionally, before the checkout operation, validate and reject any git
references (refs) that start with a leading dash to prevent them from being
interpreted as Git options, ensuring only safe ref names are passed to the git
checkout command.

Source: Linters/SAST tools

<template>
<div class="v-loading">
<p class="v-loading-text" v-html="util.html2Escape(porps.text)"></p>
<p class="v-loading-text">{{ util.html2Escape(porps.text) }}</p>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Stop escaping before Vue interpolation.

{{ ... }} already text-escapes output, so util.html2Escape(porps.text) will render characters like < as visible entities instead of the original text.

Proposed fix
-    <p class="v-loading-text">{{ util.html2Escape(porps.text) }}</p>
+    <p class="v-loading-text">{{ porps.text }}</p>

If util is no longer used in this component:

-import * as util from '`@/assets/js/util`'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<p class="v-loading-text">{{ util.html2Escape(porps.text) }}</p>
<p class="v-loading-text">{{ porps.text }}</p>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@WebUI/src/components/LoadingBar.vue` at line 3, The issue is that
util.html2Escape() is being called on porps.text before Vue interpolation, which
causes double escaping since Vue's {{ ... }} syntax already handles HTML
escaping automatically. This will result in HTML entities being displayed as
visible text (like &lt; instead of <). Remove the util.html2Escape() function
wrapper and update the interpolation in the LoadingBar component to use {{
porps.text }} directly without any additional escaping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant