Skip to content

πŸ›‘οΈ Sentinel: [HIGH] Fix PDF Compilation Command Injection and Resource Exhaustion Risks#389

Open
anchapin wants to merge 2 commits into
mainfrom
sentinel/fix-pdf-compilation-security-1897174070991137640
Open

πŸ›‘οΈ Sentinel: [HIGH] Fix PDF Compilation Command Injection and Resource Exhaustion Risks#389
anchapin wants to merge 2 commits into
mainfrom
sentinel/fix-pdf-compilation-security-1897174070991137640

Conversation

@anchapin

@anchapin anchapin commented Jul 3, 2026

Copy link
Copy Markdown
Owner

🚨 Severity: HIGH
πŸ’‘ Vulnerability: Unrestricted LaTeX compilation allowing potential command execution (RCE) and lacking timeouts, causing possible resource exhaustion (DoS).
🎯 Impact: Attackers could execute arbitrary commands or cause denial of service.
πŸ”§ Fix: Enforced -no-shell-escape on LaTeX compilers and added 30-second timeouts with cleanup. Suppressed false-positive Bandit B704 for LaTeX contexts.
βœ… Verification: Verified timeouts and restricted execution flags via automated tests (test_pdf_security.py).


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

Summary by Sourcery

Harden PDF generation against command injection and resource exhaustion when compiling LaTeX to PDF.

Bug Fixes:

  • Prevent potential command injection in LaTeX PDF compilation by disabling shell escapes for pdflatex and pandoc engines.
  • Reduce risk of resource exhaustion and denial of service during PDF compilation by enforcing timeouts and cleaning up hung subprocesses.

Enhancements:

  • Document the new PDF compilation security measures and lessons learned in the Sentinel security notes.
  • Annotate LaTeX escaping helper to suppress false-positive Bandit B704 warnings in this constrained context.

Enforces -no-shell-escape on pdflatex and pandoc commands to prevent RCE
and adds process timeouts to prevent DoS via resource exhaustion. Also
suppresses a false positive XSS warning in the markupsafe HTML context.

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

sourcery-ai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds security hardening to LaTeX-based PDF generation by enforcing no-shell-escape flags, introducing 30-second timeouts with explicit subprocess cleanup for pdflatex and pandoc invocations, documenting the vulnerability in Sentinel notes, and suppressing a Bandit false positive for safe LaTeX escaping code.

Sequence diagram for secured PDF compilation subprocess handling

sequenceDiagram
    participant CoverLetterGenerator
    participant pdflatex_process

    CoverLetterGenerator->>pdflatex_process: subprocess.Popen(pdflatex_args)
    CoverLetterGenerator->>pdflatex_process: process.communicate(timeout=30)
    alt subprocess.TimeoutExpired
        CoverLetterGenerator->>pdflatex_process: process.kill()
        CoverLetterGenerator->>pdflatex_process: process.communicate()
        CoverLetterGenerator-->>CoverLetterGenerator: pdf_created False / return False
    else completed
        pdflatex_process-->>CoverLetterGenerator: stdout, stderr
        CoverLetterGenerator-->>CoverLetterGenerator: check returncode or output_path.exists()
    end

    Note over CoverLetterGenerator,pdflatex_process: pdflatex_args include -interaction=nonstopmode and -no-shell-escape
Loading

Flow diagram for hardened PDF compilation with pdflatex fallback to pandoc

flowchart TD
    A[Start _compile_pdf or _compile_pdflatex] --> B[Run pdflatex with -no-shell-escape]
    B --> C{TimeoutExpired?}
    C -->|Yes| D[process.kill and communicate / return False or pdf_created False]
    C -->|No| E{pdflatex success or output_path.exists}
    E -->|Yes| F[Return True or pdf_created True]
    E -->|No| G[Try pandoc fallback]

    G --> H[Run pandoc with --pdf-engine-opt=-no-shell-escape]
    H --> I{TimeoutExpired?}
    I -->|Yes| J[process.kill and communicate / return False or pdf_created False]
    I -->|No| K{pandoc success or output_path.exists}
    K -->|Yes| F
    K -->|No| L[Return False or pdf_created False]
Loading

File-Level Changes

Change Details Files
Harden CoverLetterGenerator LaTeX PDF compilation against RCE and DoS.
  • Add -no-shell-escape flag to pdflatex invocation when compiling cover letter PDFs.
  • Wrap pdflatex communicate() with a 30-second timeout and kill/cleanup the process on TimeoutExpired, marking PDF creation as failed.
  • Add --pdf-engine-opt=-no-shell-escape to pandoc/xelatex fallback invocation for cover letter PDFs.
  • Wrap pandoc communicate() with a 30-second timeout and kill/cleanup the process on TimeoutExpired, marking PDF creation as failed.
cli/generators/cover_letter_generator.py
Harden generic PDF converter LaTeX compilation against RCE and DoS.
  • Add -no-shell-escape flag to pdflatex invocation in the shared PDF converter helper.
  • Wrap pdflatex communicate() with a 30-second timeout and kill/cleanup the process on TimeoutExpired, returning False on timeout.
  • Add --pdf-engine-opt=-no-shell-escape to pandoc/xelatex invocation in the shared PDF converter helper.
  • Wrap pandoc communicate() with a 30-second timeout and kill/cleanup the process on TimeoutExpired, returning False on timeout.
cli/pdf/converter.py
Document the newly addressed PDF compilation risks in Sentinel security notes.
  • Add a Sentinel entry describing the missing timeouts and shell-escape restrictions for TeX engines as vulnerabilities.
  • Capture the security learning around enforcing resource limits and disabling shell escapes for subprocess-based TeX execution.
  • Document prevention guidance recommending -no-shell-escape and communicate() timeouts with cleanup.
.jules/sentinel.md
Suppress a Bandit B704 false positive on latex_escape return value.
  • Annotate the latex_escape Markup return line with a nosec B704 comment to acknowledge and suppress the static analysis warning for this safe usage.
resume_pdf_lib/generator.py

Possibly linked issues

  • #N/A: PR directly addresses high-severity Bandit findings by securing LaTeX subprocess calls and adding a B704 nosec suppression.

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

@sourcery-ai sourcery-ai 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.

Hey - I've left some high level feedback:

  • The timeout handling logic for LaTeX compilation is duplicated across multiple call sites; consider extracting a shared helper (e.g., run_with_timeout(cmd, cwd, timeout=30)) that encapsulates Popen, communicate, timeout cleanup, and return-code handling to reduce repetition and risk of divergence.
  • In _compile_pdf in cover_letter_generator.py, when a TimeoutExpired occurs you set pdf_created = False but still fall through to the if process.returncode == 0 or output_path.exists() check; returning immediately (or skipping that block) after the timeout would make the control flow clearer and avoid relying on process.returncode after a forced kill.
  • The hard-coded timeout=30 appears in several places; consider making this a configurable constant (e.g., LATEX_COMPILE_TIMEOUT_SECONDS) so it can be tuned centrally and referenced consistently across all compilation paths.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The timeout handling logic for LaTeX compilation is duplicated across multiple call sites; consider extracting a shared helper (e.g., `run_with_timeout(cmd, cwd, timeout=30)`) that encapsulates `Popen`, `communicate`, timeout cleanup, and return-code handling to reduce repetition and risk of divergence.
- In `_compile_pdf` in `cover_letter_generator.py`, when a `TimeoutExpired` occurs you set `pdf_created = False` but still fall through to the `if process.returncode == 0 or output_path.exists()` check; returning immediately (or skipping that block) after the timeout would make the control flow clearer and avoid relying on `process.returncode` after a forced kill.
- The hard-coded `timeout=30` appears in several places; consider making this a configurable constant (e.g., `LATEX_COMPILE_TIMEOUT_SECONDS`) so it can be tuned centrally and referenced consistently across all compilation paths.

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.

Enforces -no-shell-escape on pdflatex and pandoc commands to prevent RCE
and adds process timeouts to prevent DoS via resource exhaustion. Also
suppresses a false positive XSS warning in the markupsafe HTML context.
Includes black formatting fixes to pass CI checks.

Co-authored-by: anchapin <6326294+anchapin@users.noreply.github.com>
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