Skip to content

πŸ›‘οΈ Sentinel: [CRITICAL] Fix Remote Code Execution in PDF Compilers#318

Open
anchapin wants to merge 1 commit into
mainfrom
sentinel/fix-pdflatex-rce-2-17041182512615523487
Open

πŸ›‘οΈ Sentinel: [CRITICAL] Fix Remote Code Execution in PDF Compilers#318
anchapin wants to merge 1 commit into
mainfrom
sentinel/fix-pdflatex-rce-2-17041182512615523487

Conversation

@anchapin
Copy link
Copy Markdown
Owner

@anchapin anchapin commented May 23, 2026

🚨 Severity: CRITICAL
πŸ’‘ Vulnerability: Remote Code Execution (RCE) via \write18 in LaTeX compilation, and Denial of Service (DoS) via missing timeouts.
🎯 Impact: Maliciously crafted inputs or AI hallucinations could execute arbitrary shell commands on the host system or cause infinite processing loops.
πŸ”§ Fix:

  • Added -no-shell-escape flag to pdflatex calls.
  • Added --pdf-engine-opt=-no-shell-escape to pandoc fallback calls.
  • Added a 30-second timeout to process.communicate(timeout=30) with appropriate process termination on expiration.
    βœ… Verification:
  • Unit tests run properly (pytest tests/test_pdf_security.py)
  • Code properly formatted/linted.

PR created automatically by Jules for task 17041182512615523487 started by @anchapin

Summary by Sourcery

Harden PDF compilation against LaTeX-based remote code execution and unbounded execution during PDF generation.

Bug Fixes:

  • Disable LaTeX shell execution by adding no-shell-escape flags to all pdflatex and pandoc-based PDF compilation paths.
  • Prevent unbounded PDF compilation by enforcing a 30-second timeout with proper subprocess termination in pdflatex and pandoc invocations.

Documentation:

  • Document the LaTeX RCE and DoS vulnerability, its root cause, and the mitigation strategy in the Sentinel security notes.

Addresses a critical RCE vulnerability where `pdflatex` and `pandoc` were invoked without strictly restricting shell execution or applying timeout bounds. A maliciously crafted input could inject commands using `\write18` to execute arbitrary shell commands on the host machine.

The fix enforces the `-no-shell-escape` flag for `pdflatex` and `--pdf-engine-opt=-no-shell-escape` for `pandoc`, and implements a 30-second subprocess timeout with proper process cleanup (`process.kill()`) to prevent infinite compilation loops (DoS).

Co-authored-by: anchapin <6326294+anchapin@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

πŸ‘‹ Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a πŸ‘€ emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 23, 2026

Reviewer's Guide

Harden PDF compilation by disabling LaTeX shell execution for both primary and fallback compilers and by enforcing a 30-second timeout with proper subprocess cleanup to mitigate RCE and DoS risks.

Sequence diagram for secured PDF compilation with timeout and no shell escape

sequenceDiagram
    participant Caller as CoverLetterGenerator
    participant Converter as _compile_pdflatex
    participant Popen as subprocess_Popen

    Caller->>Converter: _compile_pdflatex(tex_path, output_path, working_dir)
    Converter->>Popen: Popen(["pdflatex", "-interaction=nonstopmode", "-no-shell-escape", tex_path.name])
    activate Popen
    Converter->>Popen: communicate(timeout=30)

    alt compilation completes in time
        Popen-->>Converter: stdout, stderr
        Converter->>Converter: check returncode or output_path.exists()
        Converter-->>Caller: True or False
    else subprocess.TimeoutExpired
        Converter->>Popen: kill()
        Popen-->>Converter: communicate()
        Converter-->>Caller: RuntimeError("PDF compilation timed out")
    end
    deactivate Popen
Loading

File-Level Changes

Change Details Files
Disable LaTeX shell command execution for all PDF compilation paths.
  • Add -no-shell-escape flag to all pdflatex invocations used for cover letter and generic PDF generation.
  • Add --pdf-engine-opt=-no-shell-escape to all pandoc fallback calls that use xelatex as the PDF engine.
cli/generators/cover_letter_generator.py
cli/pdf/converter.py
Introduce bounded execution with timeouts and cleanup for LaTeX-related subprocesses.
  • Wrap process.communicate() calls in a 30-second timeout for both pdflatex and pandoc subprocesses.
  • On timeout, kill the subprocess, drain stdout/stderr, and raise a RuntimeError to signal the failure to callers.
cli/generators/cover_letter_generator.py
cli/pdf/converter.py
Document the new LaTeX RCE and DoS class of vulnerabilities and mitigations in the Sentinel security log.
  • Add a Sentinel entry describing the RCE vector via \write18 and the associated DoS risk from unbounded compilation.
  • Document the requirement to always use -no-shell-escape / --pdf-engine-opt=-no-shell-escape and explicit subprocess timeouts as standard hardening.
.jules/sentinel.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The subprocess timeout/kill/RuntimeError pattern is duplicated across the pdflatex and pandoc paths; consider extracting a small helper (e.g., run_with_timeout(cmd, cwd=None, timeout=30)) to reduce repetition and keep the behavior consistent in one place.
  • The 30-second timeout is currently hard-coded in multiple places; you may want to centralize this as a configuration constant or parameter so it can be tuned per environment without code changes.
  • When the PDF compilation times out or fails, you currently discard stdout/stderr; consider including relevant portions of stderr in the raised exception or log to aid debugging operational issues.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The subprocess timeout/kill/RuntimeError pattern is duplicated across the pdflatex and pandoc paths; consider extracting a small helper (e.g., `run_with_timeout(cmd, cwd=None, timeout=30)`) to reduce repetition and keep the behavior consistent in one place.
- The 30-second timeout is currently hard-coded in multiple places; you may want to centralize this as a configuration constant or parameter so it can be tuned per environment without code changes.
- When the PDF compilation times out or fails, you currently discard `stdout`/`stderr`; consider including relevant portions of `stderr` in the raised exception or log to aid debugging operational issues.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click πŸ‘ or πŸ‘Ž on each comment and I'll use the feedback to improve your reviews.

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