registry  /  forgr  /  0.7.2

forgr@0.7.2

Convert Markdown files into polished PDFs

AI Security Review

scanned 4h ago · by lpm-firewall-ai

No confirmed malicious attack surface. On an explicit PDF-render command, the package may download a Chromium runtime to its own cache and render user-provided Markdown into a PDF.

Static reason
One or more suspicious static signals were detected.; previous stored version diff introduced dangerous source
Trigger
User runs forgr on a Markdown file without a cached Chromium binary.
Impact
Writes ~/.forgr/browsers and the user-selected PDF output; no confirmed exfiltration or foreign control-surface mutation.
Mechanism
User-invoked Playwright Chromium bootstrap and local PDF rendering.
Rationale
The scanner conflates a manually named script with an npm lifecycle hook and flags expected Playwright bootstrap behavior. Source inspection shows package-aligned, user-triggered browser setup without a concrete malicious chain.
Evidence
package.jsonscripts/postinstall.jssrc/pdf.jssrc/pipeline.jssrc/markdown.jssrc/browsers-path.js~/.forgr/browsers

Decision evidence

public snapshot
AI called this Clean at 96.0% confidence as Benign with low false-positive risk.
Evidence for block
  • src/pdf.js runs `npx playwright-core install chromium-headless-shell` only when Chromium is absent during PDF rendering.
  • scripts/postinstall.js contains the same Chromium-download helper but is not an npm lifecycle hook.
Evidence against
  • package.json has no preinstall/install/postinstall lifecycle hook; `install-chromium` is an explicit user script.
  • package.json references scripts/preuninstall.js, but that file is absent and excluded from published files.
  • src/pdf.js stores only Playwright browser assets under ~/.forgr/browsers and deletes bundled FFmpeg there.
  • src/pipeline.js reads the user-selected Markdown file and writes the requested PDF output.
  • No package-owned HTTP client, credential harvesting, agent-control writes, payload loading, or persistence mechanism was found.
Behavioral surface
Source
ChildProcessEnvironmentVarsFilesystemShell
Supply chain
HighEntropyStrings
ManifestNo manifest risk signals triggered.
scanned 10 file(s), 38.6 KB of source

Source & flagged code

4 flagged · loading source
scripts/postinstall.jsView file
2import { rm } from 'fs/promises'; L3: import { execSync } from 'child_process'; L4: import { homedir } from 'os';
High
Child Process

Package source references child process execution.

scripts/postinstall.jsView on unpkg · L2
52try { L53: execSync('npx playwright-core install chromium-headless-shell', { L54: stdio: 'inherit',
High
Runtime Package Install

Package source invokes a package manager install command at runtime.

scripts/postinstall.jsView on unpkg · L52
src/assets/fonts/IBMPlexMono-600.woff2View file
path = src/assets/fonts/IBMPlexMono-600.woff2 kind = high_entropy_blob sizeBytes = 50600 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

src/assets/fonts/IBMPlexMono-600.woff2View on unpkg
src/pdf.jsView file
matchType = previous_version_dangerous_delta matchedPackage = forgr@0.7.0 matchedIdentity = npm:Zm9yZ3I:0.7.0 similarity = 0.800 summary = stored previous version shares package body but lacks this dangerous source file
Critical
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version; route for source-aware review.

src/pdf.jsView on unpkg

Findings

1 Critical4 High2 Medium4 Low
CriticalPrevious Version Dangerous Deltasrc/pdf.js
HighChild Processscripts/postinstall.js
HighShell
HighRuntime Package Installscripts/postinstall.js
HighShips High Entropy Blobsrc/assets/fonts/IBMPlexMono-600.woff2
MediumEnvironment Vars
MediumStructural Risk Force Deep Review
LowNon Install Lifecycle Scripts
LowScripts Present
LowFilesystem
LowHigh Entropy Strings