diff --git a/.needle-predispatch-sha b/.needle-predispatch-sha index 112f204..4a4ce4d 100644 --- a/.needle-predispatch-sha +++ b/.needle-predispatch-sha @@ -1 +1 @@ -0a2fb17d7262c890ed31554704a8df7f7cbfa902 +641ecd024e930510088d581afc4590876c838718 diff --git a/crates/pdftract-core/src/detection.rs b/crates/pdftract-core/src/detection.rs index ced28b8..bcf5677 100644 --- a/crates/pdftract-core/src/detection.rs +++ b/crates/pdftract-core/src/detection.rs @@ -11,7 +11,7 @@ use crate::parser::catalog::Catalog; use crate::parser::object::{ObjRef, PdfDict, PdfObject}; use crate::parser::pages::PageDict; use crate::parser::xref::XrefResolver; -use tracing::{debug, info}; +use tracing::{debug, info, warn}; /// Detect JavaScript presence in a PDF document. /// @@ -48,12 +48,14 @@ pub fn detect_javascript( // Check catalog /OpenAction if has_js_action(&catalog.open_action, resolver) { info!("JavaScript actions detected: catalog /OpenAction"); + warn!("JavaScript execution attempted but not supported - detection only (per TH-04 threat model)"); return true; } // Check catalog /AA if has_js_in_aa(&catalog.aa, resolver) { info!("JavaScript actions detected: catalog /AA (Additional Actions)"); + warn!("JavaScript execution attempted but not supported - detection only (per TH-04 threat model)"); return true; } @@ -62,6 +64,7 @@ pub fn detect_javascript( // Check page /AA if has_js_in_aa(&page.aa, resolver) { info!("JavaScript actions detected: page {} /AA (Additional Actions)", page_idx); + warn!("JavaScript execution attempted but not supported - detection only (per TH-04 threat model)"); return true; } @@ -73,6 +76,7 @@ pub fn detect_javascript( if let Some(action) = annot_dict.get("A") { if has_js_action(&Some(action.clone()), resolver) { info!("JavaScript actions detected: page {} annotation /A (primary action)", page_idx); + warn!("JavaScript execution attempted but not supported - detection only (per TH-04 threat model)"); return true; } } @@ -80,6 +84,7 @@ pub fn detect_javascript( if let Some(aa) = annot_dict.get("AA") { if has_js_in_aa(&Some(aa.clone()), resolver) { info!("JavaScript actions detected: page {} annotation /AA (additional actions)", page_idx); + warn!("JavaScript execution attempted but not supported - detection only (per TH-04 threat model)"); return true; } } @@ -92,6 +97,7 @@ pub fn detect_javascript( if let Some(form_dict) = acroform { if has_js_in_acroform(form_dict, resolver) { info!("JavaScript actions detected: AcroForm fields /AA (Additional Actions)"); + warn!("JavaScript execution attempted but not supported - detection only (per TH-04 threat model)"); return true; } } diff --git a/notes/bf-2pxsu.md b/notes/bf-2pxsu.md new file mode 100644 index 0000000..3aa7e5b --- /dev/null +++ b/notes/bf-2pxsu.md @@ -0,0 +1,53 @@ +# bf-2pxsu: Add logging for JavaScript execution attempts + +## Task Completion Summary + +Successfully added warning-level logging for JavaScript execution attempts in pdftract-core's detection module. + +## Changes Made + +### File: `crates/pdftract-core/src/detection.rs` + +1. **Added `warn` import to logging macros:** + - Changed `use tracing::{debug, info};` to `use tracing::{debug, info, warn};` + +2. **Added execution warning at all JavaScript detection points:** + - Catalog `/OpenAction` detection + - Catalog `/AA` (Additional Actions) detection + - Page-level `/AA` detection + - Page annotation `/A` (primary action) detection + - Page annotation `/AA` (additional actions) detection + - AcroForm fields `/AA` detection + +Each warning uses the message: +``` +"JavaScript execution attempted but not supported - detection only (per TH-04 threat model)" +``` + +## Acceptance Criteria + +- ✅ `log::debug!` or `log::warn!` macro added at any execution entry point +- ✅ Log message clearly states 'JavaScript execution attempted but not supported' +- ✅ Log includes a warning that execution is not supported (references TH-04 threat model) +- ✅ Code compiles successfully +- ✅ All tests pass (46 detection tests, 0 failed) + +## Implementation Notes + +Since pdftract is a detection-only tool (per TH-04 threat model), there is no actual JavaScript execution path. The warning logs fire whenever JavaScript is detected to explicitly communicate that: + +1. JavaScript was found in the PDF +2. Execution is NOT supported and will NEVER occur +3. This is detection-only for downstream security review + +The warnings are emitted at the same points where JavaScript detection occurs, providing clear visibility when JavaScript is present while reinforcing the security posture. + +## Testing + +- Compilation: ✅ `cargo check --package pdftract-core` +- Unit tests: ✅ All 46 detection-related tests pass +- No behavior changes - only added logging + +## Dependencies + +This bead built upon bf-2pyg1, which added the initial debug/info logging for JavaScript detection points. diff --git a/notes/bf-2pyg1.md b/notes/bf-2pyg1.md new file mode 100644 index 0000000..168155d --- /dev/null +++ b/notes/bf-2pyg1.md @@ -0,0 +1,62 @@ +# Verification Note: bf-2pyg1 - Debug logging for JavaScript detection + +## Summary +Successfully added debug logging for JavaScript detection in the pdftract-core crate. + +## Changes Made + +### File: `crates/pdftract-core/src/detection.rs` + +1. **Added logging imports**: `use tracing::{debug, info};` +2. **Added info-level logs** at JavaScript detection points in `detect_javascript()`: + - `info!("JavaScript actions detected: catalog /OpenAction")` + - `info!("JavaScript actions detected: catalog /AA (Additional Actions)")` + - `info!("JavaScript actions detected: page {} /AA (Additional Actions)", page_idx)` + - `info!("JavaScript actions detected: page {} annotation /A (primary action)", page_idx)` + - `info!("JavaScript actions detected: page {} annotation /AA (additional actions)", page_idx)` + - `info!("JavaScript actions detected: AcroForm fields /AA (Additional Actions)")` + +3. **Added debug-level logs** in helper functions: + - `debug!("JavaScript action detected with /S == {}", s_name)` + - `debug!("JavaScript action detected with /JS entry")` + - `debug!("JavaScript detected in /AA dictionary with action key: /{}", key)` + +4. **Fixed loop iteration**: Changed `for page in pages` to `for (page_idx, page) in pages.iter().enumerate()` to provide page index context in logs + +## Verification Results + +### Compilation +✅ **PASS**: Code compiles successfully with `cargo check --package pdftract-core` + +### Tests +✅ **PASS**: All 28 detection tests pass: +- `test_detect_javascript_empty` - OK +- `test_detect_javascript_no_javascript` - OK +- `test_detect_javascript_with_acroform_field_js` - OK +- `test_detect_javascript_with_annotation_js` - OK +- `test_detect_javascript_with_catalog_aa_js` - OK +- `test_detect_javascript_with_catalog_openaction_js` - OK +- `test_detect_javascript_with_page_aa_js` - OK +- Plus 21 other detection tests - OK + +## Acceptance Criteria + +- ✅ **PASS**: `log::debug!` or `log::info!` macro added at JavaScript detection point +- ✅ **PASS**: Log message clearly states 'JavaScript actions detected' or similar +- ✅ **PASS**: Log includes relevant context (page indices, action types, locations) +- ✅ **PASS**: Code compiles successfully + +## Technical Details + +The implementation uses the `tracing` crate (already used in the codebase) with both `info!` and `debug!` macros: +- `info!` for high-level detection events (what was found and where) +- `debug!` for detailed detection internals (specific keys and subtypes) + +All log messages provide clear context about: +- **Location**: catalog level, page level, annotation level, or AcroForm fields +- **Type**: /OpenAction, /AA (Additional Actions), /A (primary action) +- **Context**: Page indices for page-level detections + +## Commit Information +- **Commit**: (to be created with git commit) +- **Files modified**: `crates/pdftract-core/src/detection.rs`