Skip to content

DOM.setFileInputFiles crashes renderer when using nodeId #568

@stephanmoneybird

Description

@stephanmoneybird

Problem

Calling Node#select_file can crash the browser tab with:

ERROR:content/browser/bad_message.cc:29  Terminating renderer for bad IPC message, reason 2

Reason 2 corresponds to RFH_CAN_ACCESS_FILES_OF_PAGE_STATE — Chrome's security check that verifies the renderer process has been granted read access to files referenced in page state.

Root cause

Ferrum's Node#select_file uses nodeId to identify the element:

# lib/ferrum/node.rb:113
page.command("DOM.setFileInputFiles", slowmoable: true, nodeId: node_id, files: Array(value))

DOM.setFileInputFiles with nodeId can fail to properly grant the renderer process read access to the specified files. When Chrome later serializes page state containing the file reference, the access check fails and the renderer is killed.

This is particularly reproducible after same-document navigations (e.g. Turbo Drive in Rails apps), where the nodeId may reference a stale DOM context.

Fix

Using backendNodeId instead of nodeId resolves the crash. The backendNodeId is already available via description["backendNodeId"]:

def select_file(value)
  files = Array(value).map { |f| File.expand_path(f) }
  page.command("DOM.setFileInputFiles", slowmoable: true,
                                        backendNodeId: description["backendNodeId"],
                                        files: files)
end

For reference, Puppeteer uses objectId (not nodeId) for this CDP command, which is why Puppeteer-based tools don't hit this issue.

Environment

  • Ferrum: 0.17.1
  • Cuprite: 0.17
  • Chromium: 145.0.7632.45
  • macOS (Darwin 25.3.0)
  • Ruby 4.0.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions