github h4ckf0r0day/obscura v0.2.7

one hour ago

v0.2.7

This release improves iframe automation, form handling, session history, and browser robustness. It adds opt-in MCP web search, fixes rendering hangs and process aborts, isolates CDP connection storage, and repairs Windows runtime packaging. 87 commits since v0.2.6.

Highlights

• Iframe automation uses the correct document and evaluation world. Child-frame evaluation, remote objects, uploads, and owner-frame metadata now follow the frame that owns them. Playwright iframe locators can resolve their content frames (#1479 (#1479), #1498 (#1498), #1502 (#1502)).
• Back and Forward preserve live document state. Same-document history traversal moves the cursor without duplicating entries or reloading the document. Identical-URL entries remain distinct, and replacements preserve forward history (#1577 (#1577)).
• Forms, selects, and tables support more existing automation. Native ownership determines which controls belong to a form, which options belong to a select, and which rows and cells belong to a table. Live collections and legacy mutation APIs are implemented (#1485 (#1485), #1488 (#1488)).
• Several crash and hang paths are fixed. Grid sizing stops when floating-point redistribution cannot progress. Invalid grid spans, malformed CSS imports, short SVG viewBox values, and deeply nested documents no longer trigger the repaired abort paths.
• MCP gains opt-in web search. The new web_search tool uses Keenable to find pages that agents can then open with browser_navigate. Deep-document and nested-table Markdown extraction also avoid repeated work (#1445 (#1445), #1493 (#1493)).
• Windows archives include required runtime dependencies. Packaging resolves and bundles the required Visual C++ runtime DLLs and checks the extracted distribution (#1492 (#1492)).

Behavior changes

• Noninteractive confirm() now returns false instead of automatically accepting the action. alert() remains nonblocking and prompt() returns null. Client-controlled synchronous dialogs remain unsupported (#1475 (#1475)).
• Each CDP connection receives an independent copy-on-write localStorage snapshot of the server’s startup profile and a fresh IndexedDB store. Changed localStorage keys merge back into the persistent profile when the connection closes. Embeddable persistent context copies continue sharing their configured live profile stores (#1478 (#1478)).

Security

• The privileged deno_core bootstrap alias is removed from page and frame globals (#1429 (#1429)).
• Newly created profile directories use owner-only permissions on Unix. Cookie files use mode 0600, and failed cookie saves produce an error log. Existing directory permissions are preserved; Windows directories inherit their parent’s ACL. Profile contents remain plaintext (#1512 (#1512), #1549 (#1549)).
• CDP WebSocket connections accept the endpoint’s own HTTP Origin by default. Other origins require OBSCURA_CDP_ALLOWED_ORIGINS. Native clients without an Origin remain supported, and Host validation and bearer authentication remain enforced (#1501 (#1501)).
• File uploads validate the target input, node identity, and owning frame before reading local files. Invalid or retired handles return protocol errors. Local file access still requires explicit opt-in (#1477 (#1477)).
• Imported public-suffix cookies receive exact-host scope instead of being silently discarded. SameSite validation and cookie-prefix restrictions remain enforced (#1550 (#1550)).
• History URL validation uses the committed document URL rather than a queued Location destination, preventing pending navigation from changing the origin used by history updates (#1577 (#1577)).

CDP and automation

• Child-frame evaluations and function calls execute in the selected frame’s V8 realm. Remote objects and property-derived handles retain their producing evaluation world. Released, retired, and cross-world handles are rejected instead of being redirected into the main document (#1498 (#1498)).
• DOM.describeNode and DOM.getOuterHTML preserve remote-node ownership. Frame owner elements report live child frameId metadata through document responses and child-node events (#1479 (#1479), #1502 (#1502)).
• DOM selector queries stay within the requested subtree, support :scope, and report invalid selectors and node IDs as protocol errors. Explicit shadow-root queries do not pierce unrelated trees (#1481 (#1481)).
• Lifecycle subscriptions replay the current document’s completed lifecycle state, allowing clients to attach after loading without waiting for events that already happened (#1418 (#1418)).
• Page.navigateToHistoryEntry preserves the runtime, history state, and popstate behavior when traversing within the live document (#1577 (#1577)).
• Discovery requests are routed by their request-target path. Header values, query values, and endpoint prefixes no longer change endpoint selection. Discovery URLs also accept trailing slashes (#1549 (#1549), #1570 (#1570)).

MCP and extraction

• Set OBSCURA_WEB_SEARCH=keenable to enable web_search. Enabling it sends search queries to Keenable. The integration supports the public endpoint and optional KEENABLE_API_KEY, with bounded responses and result limits (#1445 (#1445)).
• Search limits accept integer-valued JSON numbers such as 5.0, while preserving defaults and clamping.
• Markdown extraction bounds recursive traversal and uses an explicit stack for deeper subtrees. Nested tables reuse converted cell output instead of recursively converting the same content again. CLI Markdown output, LP.getMarkdown, and MCP share the repair (#1493 (#1493)).
• MCP cookie and storage-state imports retain public-suffix host cookies with exact-host delivery (#1550 (#1550)).

Networking and page lifecycle

• Native GET and POST navigation preserve the initiating document when deriving Origin, Referer, Fetch Metadata, and cookie context. Redirects retain origin/site taint and progressively reduced referrers. Native stealth POST uses the selected stealth transport (#1486 (#1486)).
• Eligible Last-Modified subresources use age-adjusted heuristic cache freshness, capped at 24 hours. Explicit cache controls and existing bypass rules remain in effect (#1457 (#1457)).
• Empty HTTP error responses fail navigation instead of reporting a successful empty page (#1366 (#1366)).
• Classic scripts marked nomodule are skipped (#1525 (#1525)).
• Nested frame parent chains and message sources preserve browsing-context identity across navigation, removal, and reinsertion. Retired frames cannot alias the main window or an unrelated sibling (#1397 (#1397), #1504 (#1504)).

DOM, JavaScript, and rendering

• Custom elements receive connection, disconnection, and observed-attribute reactions during DOM mutations. Attribute and style caches update before callbacks run, including reentrant attribute changes (#1381 (#1381)).
• Twenty-four previously aliased HTML interfaces gain distinct native wrapper prototypes. Constructor identity, prototype changes, and instanceof behavior no longer leak between unrelated tags (#1482 (#1482)).
• Tables expose live rows, bodies, section rows, and cell collections, with row/cell indices and insertion/deletion APIs. Native ownership excludes nested tables and foreign namespaces (#1476 (#1476), #1488 (#1488)).
• Selects support native indexed access and legacy option APIs. Form submission respects actual control ownership, multiple selections, disabled-control rules, and the activated submit button (#1480 (#1480), #1485 (#1485), #1488 (#1488)).
• Input selection survives assignment of an unchanged value. setRangeText() handles explicit undefined defaults, unsigned offset conversion, and unknown input-type fallback (#1443 (#1443), #1444 (#1444)).
• Constructed DocumentFragment objects preserve wrapper identity. Node-ID operations resolve the calling frame’s document (#1544 (#1544), #1538 (#1538)).
• HTML serialization correctly escapes textarea/title text and attribute values, preserves namespace prefixes, and handles legacy void elements. Foreign xmlns attributes retain their correct identity (#1511 (#1511), #1524 (#1524)).
• Shadow-DOM layout can be retained after unrelated metadata and fixed-size image-source updates. Attribute-dependent generated content invalidates retained layout when its inputs change (#1380 (#1380)).
• Closed dialogs are hidden through the UA cascade while preserving author display overrides (#1568 (#1568)).

Reliability and runtime performance

• Grid track redistribution stops when floating-point state cannot progress, fixing a rendering hang (#1473 (#1473)).
• Invalid zero-span grid placements are ignored. Malformed CSS imports and short SVG viewBox values no longer trigger the repaired panic paths (#1466 (#1466), #1467 (#1467)).
• Deep-document parsing bounds nesting without dropping elements or text. CDP connection threads receive additional native stack headroom for layout (#1474 (#1474)).
• Large PBKDF2 derivations run on bounded, cancellable workers instead of blocking the event loop. Small derivations retain a bounded native fast path (#1469 (#1469)).
• Repeated select-length reads reuse live option snapshots instead of rebuilding and decoding option lists (#1535 (#1535)).
• History synchronization transfers only changed URL ranges, uses bounded bookkeeping, and moves native data without a JSON round trip (#1577 (#1577)).
• Storage remains usable when page code replaces its global constructor (#1500 (#1500)).

Packaging and validation

• Windows packaging bundles required Visual C++ runtime dependencies and validates extracted archives. Dedicated regression checks cover all four Windows variants (#1492 (#1492)).
• Scoop installation metadata and Windows installation instructions are corrected (#1454 (#1454)).
• A native ARM64 validation job covers fontless screenshots and client-disconnect cleanup (#1575 (#1575)).
• CI preserves the exact release binary before workspace tests can rebuild it with different dependency features. Performance measurements use matching release configurations (#1553 (#1553)).
• Final main validation passed 2,670 render tests with five existing skips, 1,701 no-render tests with three existing skips, and the stealth networking checks.
• All four release build configurations passed: render, render+stealth, no-render, and no-render+stealth.
• Main passed the complete 33/33 obstacle course.
• The independent performance comparison passed 34 scenarios, with five trials per build and 340 recorded samples.
• The CI-built executable separately passed the Playwright history, raw CDP, frame-position, and cookie-origin reproductions.
• Documentation now uses the repository’s GitHub guides and reflects current CLI and CDP behavior (#1441 (#1441), #1442 (#1442)).

Contributors

Thanks to @963s, @anirudhqwerty, @Bl0ck154, @coolswood, @dsenften, @flolep2607, @ilya-bogin-keenable, @Johnbjoseph-cybersec, @jpdjere, @Ker102, @Kevsosmooth, @kk376, @lkarlslund, @shahzadaliofficial, and @velinxs for contributions to this release.

Full Changelog: v0.2.6...v0.2.7

Don't miss a new obscura release

NewReleases is sending notifications on new releases.