← Back to index

DOM-based test cases — DOM selector injection

High: 0 Medium: 0 Low: 0 Safe: 0 Total: 0

Scenarios highlight untrusted data flowing into querySelector, jQuery root selectors, and delegated find() calls. Controls let you mutate location.hash or broadcast selectors via postMessage.

High severity — tainted selectors reach DOM sinks

DS-H1 (High): location.hash fed into document.querySelector
// inline-script[#1]
function runUnsafeHashSelector() {
  var sel = location.hash ? decodeURIComponent(location.hash.slice(1)) : '';
  var victim = document.querySelector(sel);
  if (victim) victim.innerHTML = '<em>hijacked</em>';
}
runUnsafeHashSelector();
DS-H2 (High): message payload used as root jQuery selector
// inline-script[#2]
function dsMessage(e) {  
  var sel = e.data;
  try {
    var $target = $(sel);
    $target.text('updated by message');
  } catch (err) {
    console.warn('Selector error', err);
  }
};
dsMessage(document.cookie)
DS-H3 (High): find() selector built from window.name
// inline-script[#3]
(function(){
  var root = document.getElementById('ds-root');
  if (!root) return;
  var target = window.name || '.card';
  try {
    $(root).find(target).addClass('highlighted');
  } catch (err) {
    console.warn('find selector failed', err);
  }
})();
Selector root block
DS-H4 (High): Query parameter forwarded to find()
// inline-script[#4]
(function(){
  var params = new URLSearchParams(location.search);
  var target = params.get('selector') || '.card';
  try {
    $('#selector-grid').find(target).addClass('highlighted');
  } catch (err) {
    console.warn('find selector failed', err);
  }
})();
Item A
Item B

Medium severity — risky configuration / weak validation

DS-M1 (Medium): wildcard postMessage broadcasting selector strings
// inline-script[#5]
(function(){
  const frame = document.getElementById('selector-msg-target');
  if (frame) frame.srcdoc = "<!doctype html><title>selector-target</title>";
  window.broadcastSelector = function(payload) {
    if (!frame || !frame.contentWindow) return;
    frame.contentWindow.postMessage(payload, '*');
  };
})();

Safe scenarios — escaping and allow-lists

DS-S1 (Safe): CSS.escape applied to hash-derived selector
// inline-script[#7]
function runSafeHashSelector() {
  var raw = location.hash ? decodeURIComponent(location.hash.slice(1)) : '';
  var escaped = CSS.escape(String(raw));
  var el = document.getElementById('selector-scope');
  if (!el) return;
  try {
    var target = el.querySelector('#' + escaped);
    if (target) target.classList.add('selected');
  } catch (err) {}
}
runSafeHashSelector();
Item one
Item two

External scenarios (click to run)

Insecure sets : user-controlled values, weak attributes
onclick="extSelectorFromCookie()"