security error the operation is insecure in firefox document.stylesheets

error-handling, javascript, security, stylesheet

Solution

To circumvent the SecurityError in Firefox when attempting to access the cssRules attribute, you must use a `try/catch` statement. The following should work:

// Example call to process_stylesheet() with StyleSheet object.
process_stylesheet(window.document.styleSheets[0]);

function process_stylesheet(ss) {
  // cssRules respects same-origin policy, as per
  // https://code.google.com/p/chromium/issues/detail?id=49001#c10.
  try {
    // In Chrome, if stylesheet originates from a different domain,
    // ss.cssRules simply won't exist. I believe the same is true for IE, but
    // I haven't tested it.
    //
    // In Firefox, if stylesheet originates from a different domain, trying
    // to access ss.cssRules will throw a SecurityError. Hence, we must use
    // try/catch to detect this condition in Firefox.
    if(!ss.cssRules)
      return;
  } catch(e) {
    // Rethrow exception if it's not a SecurityError. Note that SecurityError
    // exception is specific to Firefox.
    if(e.name !== 'SecurityError')
      throw e;
    return;
  }

  // ss.cssRules is available, so proceed with desired operations.
  for(var i = 0; i < ss.cssRules.length; i++) {
    var rule = ss.cssRules[i];
    // Do something with rule
  }
}

Problem

The following code throws an error in the Firefox Console at the line with the continue. ``` SecurityError: The operation is insecure. if( !sheet.cssRules ) { continue; } ``` However does not in Chrome and IE 11... Can someone explain the -why- of this? (And also how to re-work to make it safe.) I assume this is a cross-domain issue, but I'm stuck as how to re-work the code properly. ``` var bgColor = getStyleRuleValue('background-color', 'bg_selector'); function getStyleRuleValue(style, selector, sheet) { var sheets = typeof sheet !== 'undefined' ? [sheet] : document.styleSheets; for (var i = 0, l = sheets.length; i < l; i++) { var sheet = sheets[i]; if( !sheet.cssRules ) { continue; } for (var j = 0, k = sheet.cssRules.length; j < k; j++) { var rule = sheet.cssRules[j]; if (rule.selectorText && rule.selectorText.split(',').indexOf(selector) !== -1) return rule.style[style]; } } return null; } ```

Original source

Related problems