Skip to content

fix(ocr-service): drop node-tesseract-ocr and call the tesseract binary with execFile - #1362

Closed
Gustav-Ahrens wants to merge 1 commit into
webdriverio:mainfrom
Gustav-Ahrens:fix/ocr-service-drop-node-tesseract-ocr
Closed

Gustav-Ahrens wants to merge 1 commit into
webdriverio:mainfrom
Gustav-Ahrens:fix/ocr-service-drop-node-tesseract-ocr

Conversation

@Gustav-Ahrens

Copy link
Copy Markdown

Closes #1361

Summary

@wdio/ocr-service depended on node-tesseract-ocr, which carries an unpatched critical advisory (GHSA-8j44-735h-w4w2, CVE-2026-26832: the file path is concatenated into a shell command and run with child_process.exec). The package has had no release since May 2022 and the advisory lists no patched version, so every project that installs the OCR service gets one npm audit critical it cannot clear.

This PR removes the dependency. The service now runs the system tesseract binary itself through child_process.execFile with an argument array, so the screenshot path and the options never pass through a shell. isSystemTesseractAvailable() uses execFileSync for the same reason.

What changes

  • packages/ocr-service/src/utils/tesseract.ts: new runSystemTesseract(filePath, { lang, oem, psm, presets }) builds [filePath, 'stdout', '-l', lang, '--oem', oem, '--psm', psm, ...presets] and calls execFile('tesseract', args, { maxBuffer: 10 MiB }). getSystemOcrData() calls it with the same options as before (eng, oem 1, psm 3, alto). isSystemTesseractAvailable() calls execFileSync(binary, ['--version']).
  • packages/ocr-service/package.json and pnpm-lock.yaml: node-tesseract-ocr removed.
  • Tests: the node-tesseract-ocr mock is replaced by execFile / execFileSync mocks. Two new tests assert that a binary name and a file path containing shell metacharacters are passed through as single literal arguments.
  • Changeset: patch for @wdio/ocr-service.

What does not change

  • The command that runs is the same as the one node-tesseract-ocr built: tesseract <file> stdout -l <lang> --oem 1 --psm 3 alto. The only behavioural difference is the stdout buffer: 10 MiB instead of Node's 1 MiB default, so the ALTO XML of a busy full-screen capture no longer risks maxBuffer exceeded.
  • The tesseract.js fallback path is untouched.

Verification

  • pnpm vitest --run packages/ocr-service: 84 passed.
  • pnpm build, pnpm run test:types, pnpm run test:lint: clean.
  • Full unit suite: 1197 passed, 3 failed in packages/image-comparison-core/src/methods/processDiffPixels.test.ts. Those three fail identically on main on this machine (Node 26.12, macOS) with the change stashed, so they are unrelated.
  • Real-binary equivalence (Tesseract 5.5.3): ran the old node-tesseract-ocr.recognize() and the new runSystemTesseract() on the same 1080x2400 app screenshot with identical options. The raw ALTO output was byte-identical (8304 bytes), and getSystemOcrData() returned 31 words and 16 lines from it.

Generated with Full Stack Ground Control (support@fullstack.co.za)

…ry with execFile

node-tesseract-ocr builds one shell command string from the screenshot
path and runs it with child_process.exec (GHSA-8j44-735h-w4w2, critical,
no patched release since 2022). Run the system tesseract binary directly
with execFile and an argument array instead, so the path and options
never pass through a shell. The command and its output are unchanged.

Closes webdriverio#1361

Co-Authored-By: Full Stack Ground Control <support@fullstack.co.za>
@changeset-bot

changeset-bot Bot commented Oct 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3272769

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@wdio/ocr-service Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@linux-foundation-easycla

Copy link
Copy Markdown

CLA Missing ID

  • ❌ The email address for the commit (3272769) is not linked to the GitHub account, preventing the EasyCLA check. Consult this Help Article and GitHub Help to resolve. (To view the commit's email address, add .patch at the end of this PR page's URL.) For further assistance with EasyCLA, please visit our EasyCLA portal and chat with our support bot.

@Gustav-Ahrens

Copy link
Copy Markdown
Author

Closing this draft; the OCR service works as is for our use, and the advisory is tracked in #1361 for the maintainers to handle as they see fit.

@Gustav-Ahrens
Gustav-Ahrens deleted the fix/ocr-service-drop-node-tesseract-ocr branch October 20, 2026 14:14
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.

ocr-service: node-tesseract-ocr carries an unpatched critical advisory (GHSA-8j44-735h-w4w2)

1 participant