Skip to content

DataFlow::globalVarRef(<name>) does not resolve document.defaultView (Window alias) #20823

@Eliav2

Description

@Eliav2

Description
DataFlow::globalVarRef("history") (and similar globalVarRef("window")) misses flows where the global Window object is accessed via document.defaultView. Some bundlers/runtime environments reference the window object as document.defaultView, so calls like document.defaultView.history.pushState(...) are not recognized as flowing from the global history.

Repro (minimal JS):

// Common patterns CodeQL handles:
history.pushState({}, "", "/ok");
window.history.pushState({}, "", "/ok2");

// Missed pattern:
document.defaultView.history.pushState({}, "", "/missed");

Typical QL snippet

import javascript, DataFlow

predicate isSink(DataFlow::Node sink) {
  exists(DataFlow::MethodCallNode call |
    call = DataFlow::globalVarRef("history").getAMemberCall(["pushState", "replaceState"]) and
    sink = call.getArgument(2)
  )
}

Expected
Flows where the receiver is document.defaultView.history should be treated equivalently to window.history/history, i.e., the third argument should be identified as a sink.

Actual
document.defaultView.history.pushState(...) is not matched; globalVarRef("history") does not cover the document.defaultView alias to Window.

Why this matters
Some bundlers / frameworks generate code that references the Window via document.defaultView. Analyses relying on globalVarRef currently miss those navigation calls, reducing coverage.

Suggested direction
Enhance globalVarRef (or provide an additional utility) to recognize document.defaultView as an alias of the global Window, so document.defaultView.history is resolved consistently with window.history.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions