π‘οΈ Sentinel: [CRITICAL] Fix PDF Compilation Command Injection and DoS#220
π‘οΈ Sentinel: [CRITICAL] Fix PDF Compilation Command Injection and DoS#220
Conversation
Co-authored-by: anchapin <6326294+anchapin@users.noreply.github.com>
|
π 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 New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Reviewer's GuideHardened PDF generation by adding no-shell-escape flags and timeouts around pdflatex/pandoc invocations, including explicit process cleanup on timeout and a Sentinel entry documenting the vulnerability and mitigation. Sequence diagram for hardened PDF compilation with timeout and no_shell_escapesequenceDiagram
actor User
participant Caller as PDFRequestHandler
participant Converter as PDFConverter
participant Subproc as subprocess_Popen
participant Engine as pdflatex
User ->> Caller: request_pdf(tex_content)
Caller ->> Converter: _compile_pdflatex(tex_path, output_path, working_dir)
Converter ->> Subproc: Popen([pdflatex, -interaction=nonstopmode, -no-shell-escape, tex_path.name])
Subproc ->> Engine: start_compilation(tex_file)
alt compilation_finishes_within_30s
Converter ->> Subproc: communicate(timeout=30)
Subproc -->> Converter: stdout, stderr
Converter ->> Converter: check returncode or output_path.exists()
Converter -->> Caller: True
Caller -->> User: return_generated_pdf
else compilation_hangs_or_infinite_loop
Converter ->> Subproc: communicate(timeout=30)
Subproc --x Converter: raise TimeoutExpired
Converter ->> Subproc: kill()
Converter ->> Subproc: communicate()
Subproc -->> Converter: stdout, stderr
Converter ->> Caller: raise RuntimeError(PDF compilation timed out)
Caller -->> User: error_response
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The timeout/kill/communicate pattern is duplicated in four places; consider extracting a small helper (e.g.,
run_with_timeout(cmd, cwd=None, timeout=30)) to centralize the behavior and reduce the chance of divergence in future changes. - The hard-coded 30-second timeout is currently embedded directly in the subprocess calls; it may be cleaner to define this as a module-level constant or configuration parameter so it can be tuned without code changes.
- Raising a generic
RuntimeError("PDF compilation timed out")drops potentially useful diagnostics fromstderr; consider including relevant parts ofstderrin the exception message or logging it before raising to aid debugging operational issues.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The timeout/kill/communicate pattern is duplicated in four places; consider extracting a small helper (e.g., `run_with_timeout(cmd, cwd=None, timeout=30)`) to centralize the behavior and reduce the chance of divergence in future changes.
- The hard-coded 30-second timeout is currently embedded directly in the subprocess calls; it may be cleaner to define this as a module-level constant or configuration parameter so it can be tuned without code changes.
- Raising a generic `RuntimeError("PDF compilation timed out")` drops potentially useful diagnostics from `stderr`; consider including relevant parts of `stderr` in the exception message or logging it before raising to aid debugging operational issues.Help me be more useful! Please click π or π on each comment and I'll use the feedback to improve your reviews.
π¨ Severity: CRITICAL
π‘ Vulnerability: The
PDFConverterandCoverLetterGeneratorusedsubprocess.Popento callpdflatexandpandocwithout the-no-shell-escapeflag or a timeout. This could allow Remote Code Execution (RCE) via LaTeX injections (e.g.,\write18{...}) and Denial of Service (DoS) through infinite compilation loops ifpdflatexhangs on invalid inputs.π― Impact: Attackers could execute arbitrary system commands on the host generating the PDFs or cause the server to hang indefinitely, leading to resource exhaustion.
π§ Fix:
-no-shell-escapeforpdflatexand--pdf-engine-opt=-no-shell-escapeforpandoc.timeoutto thesubprocess.communicate()calls.process.kill()insidesubprocess.TimeoutExpiredexceptions to prevent zombie processes.β Verification: Added/modified tests in
tests/test_pdf_security.pyto assert that-no-shell-escapeis included in the command andsubprocess.TimeoutExpiredproperly handles process kills. Ranpython -m pytestwhich passed 681 tests. Logged Sentinel learning in.jules/sentinel.md.PR created automatically by Jules for task 16983988091594555537 started by @anchapin
Summary by Sourcery
Harden PDF generation against command injection and hangs by securing LaTeX/Pandoc invocations and enforcing timeouts.
Bug Fixes:
Documentation: