github h4ckf0r0day/obscura v0.2.3

2 hours ago

v0.2.3

Security, concurrency, and browser compatibility are the focus of this release. The JavaScript engine has been updated, exposed CDP and MCP servers now have built-in authentication, concurrent sessions are more reliable, and rendering gained another broad correctness and performance pass. 114 commits since v0.2.2.

Highlights

CDP and MCP now protect exposed control ports. Non-loopback binds require a bearer token of at least 32 bytes. Browser-origin requests and invalid Host headers are rejected, request sizes and connection counts are bounded, and multiworker CDP preserves the same security checks (#1030, #1048).
Deno and V8 have been updated. deno_core moves from 0.350 to 0.412 and V8 to 150.4, removing the old advisory exceptions while retaining Obscura's runtime behavior and performance (#1031).
Concurrent automation is faster and more reliable. Concurrent pages keep independent live isolates, disconnected clients release their state, browser attachments receive unique sessions, and the multiworker server now starts immediately, uses OS-assigned ports, and avoids proxy latency (#872, #873, #978, #1048).
Rendering is faster and more faithful. Resource loads use the page transport, font databases and repeated text shaping are reused, live form state reaches paint, and layout, hit testing, scrolling, stacking, text decoration, and transform safety were improved (#879, #890, #935, #959, #983, #998, #1019).
Web platform behavior continues to close on browsers. CharacterData ranges, slots, URL setters, accessible names, Web IDL enumerability, selection-aware input, pointer events, :scope, and document.write ordering now follow browser behavior more closely (#887, #931, #984, #999, #1004, #1005, #1008, #1029).

Security

• CDP supports OBSCURA_CDP_TOKEN; MCP HTTP supports OBSCURA_MCP_TOKEN. Non-loopback binds are refused without a sufficiently long token.
• CDP rejects browser-origin requests and DNS-rebinding-style Host headers. MCP browser requests are denied unless their origin is explicitly allowed.
• MCP headers, bodies, batches, pending requests, and live connections are bounded.
• CORS preflights validate methods and headers, intermediate redirect hops are checked, and credentials are removed on cross-origin redirects (#942, #967, #973).
• Script-visible responses hide Set-Cookie, unexposed cross-origin headers, opaque response bodies, and internal resource bytes.
• Cookie handling now preserves host-only scope, rejects public-suffix domains, enforces SameSite rules, and prevents insecure origins or document.cookie from overwriting protected cookies (#915).
• WebCrypto output sizes are capped against memory exhaustion (#910).
• Transform layers are dimension-capped so hostile transforms cannot force an aborting allocation (#1019).
• Rustls was updated for RUSTSEC-2026-0285 (#1025).
• Docker continues to run as the non-root uid 65532 (#859).

CDP and automation

• Concurrent pages on one connection retain independent JavaScript heaps and object handles (#872).
• Browser attachment sessions are unique and detach independently (#978).
• Client state is released after disconnect instead of accumulating in long-running servers (#873).
• Discovery endpoints advertise the client-facing host and port (#945).
Fetch.fulfillRequest preserves binary bodies, multi-valued response headers remain intact, and the Fetch domain follows the same interception behavior as the main server path (#912, #913, #919).
• History navigation updates its index only after successful navigation and retains network events (#920).
Runtime.evaluate and callFunctionOn preserve undefined in by-value results (#938).
• DOM methods return protocol errors for unresolvable object ids instead of placeholder values (#917).
• Backspace removes an entire surrogate pair, and Enter respects textarea selections (#939, #1005).
• Mouse input now dispatches browser-shaped pointer and mouse transitions, focuses interactive targets, respects pointer-events, and acknowledges commands before navigation events.
• Multiworker serving uses OS-assigned internal ports, readiness polling, TCP_NODELAY, and resilient client dispatch instead of adjacent ports and a fixed startup delay.

Networking and runtime

• Render resources use the owning page transport, preserving proxy, stealth, headers, cookies, interception, SSRF checks, and request accounting (#890).
• CORS validates preflight permissions and every redirect hop (#942, #973).
• Fetch methods are normalized to uppercase, and cross-origin redirects strip authorization and cookie credentials (#969, #967).
• JavaScript cannot access deno_core internals or bootstrap handoff state.
• Worker message handlers survive initialization, frame realms no longer crash on rejection or dynamic import, and late V8 flag changes are ignored instead of aborting (#850, #853, #871).
document.write preserves blocking script order (#1029).
• The module response-size environment override now reaches the actual module loader cap (#849).

Rendering

• Font databases are cached across documents, reducing repeated startup and discovery work (#879).
• Repeated text runs reuse bounded shaping templates, and table column measurement avoids redundant layout and shaping (#983, #1048).
• Live input values and checkbox state are painted from the DOM without slow attribute reconstruction (#959).
• DOM-only screenshots remain network-free (#998).
• Overline and line-through text decorations are painted (#935).
• Rounded float boundaries no longer abort layout (#884).
• Hit testing follows stacking order and inherited pointer-events.
• Overflow axes, scroll chaining, sticky and fixed geometry, percentage sizing, and positioned inline-flex containing blocks were corrected.
• Image and font resources are shared safely without bypassing the page transport.

DOM and JavaScript

• CharacterData mutations update live ranges, and node identity and id lookup remain correct after mutation (#984).
• Removing an id attribute updates the document id index (#1013).
HTMLSlotElement exposes assignedNodes() and assignedElements() (#931).
• URL search, hash, and port setters follow WHATWG behavior (#1008).
btoa() encodes Latin-1 rather than UTF-8 (#996).
• Web IDL operations are enumerable on interface prototypes (#999).
• Accessible names handle labels, hidden references, links, nested controls, and visibility consistently (#1004).
Element.querySelector() and matches() bind :scope to the correct element.
• Iframe events follow capture, target, and bubble ordering.
• Window named properties can be shadowed by normal JavaScript assignment.

MCP, packaging, and stealth

• MCP network history includes scripted requests, and console messages are available to clients (#950, #951).
• Distribution binaries use size-optimized LTO builds while retaining unwind-based panic containment (#962).
Navigator, PluginArray, Plugin, MimeType, and MimeTypeArray are exposed as their standard interfaces (#962).
• Stealth tracker blocking can be disabled when the caller needs the unfiltered resource set (#995).
• Release builds continue to publish render, render-stealth, no-render, and no-render-stealth variants.

Contributors

Thanks to @mnaza, @AntonioRossi, @lisa0314, @michabbb, @Railly, @Yubo-Cao, @lkraider, @ntdatt812, @kws1207, @mrummuka, and @gilbertwong96 for contributions to this release.

Full Changelog: v0.2.2...v0.2.3

Don't miss a new obscura release

NewReleases is sending notifications on new releases.