pdftract/notes/bf-5soyd.md

131 lines
5.1 KiB
Markdown

# JavaScript Detection Points in pdftract
## Summary
JavaScript detection in pdftract is implemented across multiple files. The system **detects but NEVER executes** embedded JavaScript per TH-04.
## Primary Detection Files
### 1. `crates/pdftract-core/src/detection.rs` (lines 15-93)
**Main entry point:** `detect_javascript()` function
**Detection mechanism:**
- Walks document tree checking for JavaScript actions in:
- Catalog `/OpenAction` (line 48)
- Catalog `/AA` (Additional Actions) (line 53)
- Page-level `/AA` dictionaries (line 60)
- AcroForm field `/AA` dictionaries (line 86)
- Annotation `/A` and `/AA` entries (lines 65-82)
**Helper functions:**
- `has_js_action()` (lines 95-130): Checks if object is a JavaScript action
- Detects `/S == /JavaScript` or `/S == /JS` (line 118)
- Detects `/JS` entry containing JavaScript code (line 124)
- `has_js_in_aa()` (lines 132-166): Checks `/AA` dictionaries for JavaScript
- `has_js_in_acroform()` (lines 168-224): Recursively checks AcroForm fields
**Return value:** `bool` - true if any JavaScript action is found
### 2. `crates/pdftract-core/src/javascript.rs` (lines 25-95)
**Enhanced detection:** `detect_javascript()` function that returns detailed action information
**Detection mechanism:**
- Similar tree walk as `detection.rs` but returns structured data
- Returns `Vec<JavascriptAction>` with:
- `location`: String describing where JS was found (e.g., "catalog.openaction", "page.0.aa.O")
- `code_excerpt`: First 200 characters of JavaScript code
**Helper functions:**
- `check_object_for_js()` (lines 97-131): Checks individual objects for `/JS` entries
- `check_aa_for_js()` (lines 133-162): Checks `/AA` dictionaries
- `check_annotations_for_js()` (lines 164-199): Checks annotation arrays
- `extract_js_code()` (lines 201-241): Extracts JavaScript code from `/JS` entries
- Handles both string and stream-based JavaScript
- Truncates to 200 characters for security reporting
**Return value:** `(Vec<JavascriptAction>, Vec<Diagnostic>)` - detected actions + diagnostics
### 3. `crates/pdftract-core/src/extract.rs` (lines 971-986)
**Integration point:** JavaScript detection is called during PDF extraction
**Code location:**
```rust
// TH-04: Detect JavaScript actions in the document
use crate::javascript::detect_javascript;
let (js_actions, js_diagnostics) =
detect_javascript(&catalog, &pages_for_js_detection, &resolver_arc);
```
**Result stored in:** `PdfResult.javascript_actions: Vec<JavascriptActionJson>` (line 274)
### 4. `crates/pdftract-core/src/diagnostics.rs` (lines 1068-1072, 2362)
**Diagnostic reporting:** Emits warning when JavaScript is detected
**Diagnostic code:** `DiagCode::SecurityJavascriptPresent`
**Message format:**
```
"Detected {} JavaScript action(s) in PDF document. JavaScript was NOT executed."
```
**Suggested action:**
"The PDF contains embedded JavaScript. Review the document metadata.javascript_actions array for details. pdftract never executes embedded JS."
## Detection Mechanism Details
### How JavaScript is Detected
1. **Action type detection:** Checks for `/S (subtype) == /JavaScript` or `/S == /JS`
2. **Code presence detection:** Checks for `/JS` entry containing JavaScript code
3. **Location tracking:** Records where JavaScript was found (catalog, pages, annotations, forms)
### No Execution Path
**Explicitly stated in code:**
- `detection.rs` line 24: "JavaScript is NEVER EXECUTED; only its presence is flagged."
- `javascript.rs` line 4: "Per TH-04, pdftract NEVER executes embedded JavaScript"
- `diagnostics.rs` line 1071: "The JavaScript is NEVER executed by pdftract"
### JavaScript Entry Points Checked
1. **Catalog level:**
- `/OpenAction`: Actions to execute when document opens
- `/AA`: Additional actions (O=open, C=close, etc.)
2. **Page level:**
- `/AA`: Page-specific additional actions
3. **Annotation level:**
- `/A`: Primary action for annotation
- `/AA`: Additional actions for annotation
4. **Form field level:**
- `/AA`: Field-specific additional actions
- Recursively checks `/Kids` for nested fields
## Key Code Locations
| File | Lines | Purpose |
|------|-------|---------|
| `detection.rs` | 41-93 | Boolean JavaScript detection |
| `detection.rs` | 95-130 | `has_js_action()` - checks `/S == /JavaScript` and `/JS` |
| `detection.rs` | 132-166 | `has_js_in_aa()` - checks `/AA` dictionaries |
| `detection.rs` | 168-224 | `has_js_in_acroform()` - checks form fields |
| `javascript.rs` | 25-95 | Structured JavaScript detection with code extraction |
| `javascript.rs` | 201-241 | `extract_js_code()` - extracts JS code, truncates to 200 chars |
| `extract.rs` | 971-986 | Integration point calling JavaScript detection |
| `diagnostics.rs` | 1068-1072 | Diagnostic code definition |
| `diagnostics.rs` | 2362 | Suggested action text |
## Conclusion
The pdftract codebase has a robust two-layer JavaScript detection system:
1. **Simple boolean detection** in `detection.rs` for quick checks
2. **Detailed extraction** in `javascript.rs` for security reporting
**No execution path exists** - the code explicitly prevents JavaScript execution and only reports its presence for downstream security review.