Skip to content
This repository was archived by the owner on Sep 15, 2021. It is now read-only.

Repository files navigation

Development of ScanJS has stopped.

We are using ESLint instead. Your options:

  • XSS-prevention rule during CI with eslint-plugin-no-unsanitized. This assumes that you prevent/disallow obfuscation and that your code is subject to code review before it is being scanned (e.g., to catch intentional malicious/obfuscated code)
  • If you want something that warn for "all the things" that scanjs pointed out, you will need to use and build upon eslint-config-scanjs.

Thank you.


ScanJS was was a Static analysis tool for javascript code. ScanJS was created as an aid for security review, to help identify security issues in client-side web applications.

ScanJS used Acorn to convert sources to AST, then walks AST looking for source patterns. You could use the rules file supplied, or load your own rules.

ScanJS Rules

Rules are specified in JSON format - for an example see /common/template_rules.json

At a minimum, each must have rule is made up of 2 attributes:

  • name: the name of the rule
  • source: javascript source which matches one of the patterns below (see Rule Syntax below)

Optionally a rule may have the following attirbutes:

  • testhit: one more JavaScript statements (seperate by semi-colons) that the rule will match
  • testmiss: the rule should not match any of these statements
  • desc: description of the rule
  • threat: for catgorizing rules by threat

Rule Syntax

For the source attribute, the following basic statements are supported:

  • identifier foo: matches any identifier , "foo"
  • property $_any.foo: $_any is wildcard, matches anything.foo
  • objectproperty foo.bar: matches object and property, i.e. foo.bar

You can also matches function calls based on the same syntax:

  • call foo(): matches function calls with this name
  • propertycall $_any.foo: matches anything.foo() but not foo()
  • objectpropertycall: foo.bar(): matches foo.bar() only

You can also search for functions with matching literal arguments:

  • callargs foo('test',ignored,42): matches a function called foo, with 'test' as the first argument, anything as the second argument, and the number 42 as the third argument (i.e. matches ONLY literal arguments).
  • propertycallargs $_any.foo('test',ignored,42): same as above, but function has to be a property.
  • objectpropertycallargs foo.bar('test',ignored,42): same as above, but matches both object and property

You can also search for assignment to a specifically named identifier:

  • assignment foo=$_any: matches when foo is assigned to something
  • propertyassignment $_any.foo=$_any: matches when anything.foo is assigned to something
  • objectpropertyassignment foo.bar=$_any: matches when foo.bar is assigned to something

If you specify $_unsafe on the right hand side (e.g. foo.innerHTML=$_unsafe), it will only match if the RHS contains at least one identifier.

Tips:

  • Javascript is very dynamic, and this is navie approach: write conservative rules and review for false positives
  • One simple statement per rule, not complex statements (yet)!
  • 'foo' does NOT match 'this.foo', if you are looking for something in global (e.g. 'alert()' ), you need to add two rules: 'alert.()' and '$_any.alert()'
  • Try the rule out in the experiment tab to test what it matches

Examples: See /common/template_rules.json and /common/rules.json

Running ScanJS

Run ScanJS in the browser

Run ScanJS from the command line

  • Install node.js
  • scanner.js -t DIRECTORY_PATH

Testing instructions

Tests use the mocha testing framework.

  • npm test
  • or in the browser:http://127.0.0.1:4000/tests/

Tests are included in the rules declaration (see common/rules.json) by specifying the following two attributes, which are specified in the form of a series of javascript statements:

  • testhit: The rule should match each of these statements individualy.
  • testmiss: The rule should not match all of these statements.

About

[DEPRECATED] Static analysis tool for javascript code.

Resources

Stars

426 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - mozilla/scanjs: [DEPRECATED] Static analysis tool for javascript code. · GitHub
Skip to content
This repository was archived by the owner on Sep 15, 2021. It is now read-only.

Repository files navigation

Development of ScanJS has stopped.

We are using ESLint instead. Your options:

  • XSS-prevention rule during CI with eslint-plugin-no-unsanitized. This assumes that you prevent/disallow obfuscation and that your code is subject to code review before it is being scanned (e.g., to catch intentional malicious/obfuscated code)
  • If you want something that warn for "all the things" that scanjs pointed out, you will need to use and build upon eslint-config-scanjs.

Thank you.


ScanJS was was a Static analysis tool for javascript code. ScanJS was created as an aid for security review, to help identify security issues in client-side web applications.

ScanJS used Acorn to convert sources to AST, then walks AST looking for source patterns. You could use the rules file supplied, or load your own rules.

ScanJS Rules

Rules are specified in JSON format - for an example see /common/template_rules.json

At a minimum, each must have rule is made up of 2 attributes:

  • name: the name of the rule
  • source: javascript source which matches one of the patterns below (see Rule Syntax below)

Optionally a rule may have the following attirbutes:

  • testhit: one more JavaScript statements (seperate by semi-colons) that the rule will match
  • testmiss: the rule should not match any of these statements
  • desc: description of the rule
  • threat: for catgorizing rules by threat

Rule Syntax

For the source attribute, the following basic statements are supported:

  • identifier foo: matches any identifier , "foo"
  • property $_any.foo: $_any is wildcard, matches anything.foo
  • objectproperty foo.bar: matches object and property, i.e. foo.bar

You can also matches function calls based on the same syntax:

  • call foo(): matches function calls with this name
  • propertycall $_any.foo: matches anything.foo() but not foo()
  • objectpropertycall: foo.bar(): matches foo.bar() only

You can also search for functions with matching literal arguments:

  • callargs foo('test',ignored,42): matches a function called foo, with 'test' as the first argument, anything as the second argument, and the number 42 as the third argument (i.e. matches ONLY literal arguments).
  • propertycallargs $_any.foo('test',ignored,42): same as above, but function has to be a property.
  • objectpropertycallargs foo.bar('test',ignored,42): same as above, but matches both object and property

You can also search for assignment to a specifically named identifier:

  • assignment foo=$_any: matches when foo is assigned to something
  • propertyassignment $_any.foo=$_any: matches when anything.foo is assigned to something
  • objectpropertyassignment foo.bar=$_any: matches when foo.bar is assigned to something

If you specify $_unsafe on the right hand side (e.g. foo.innerHTML=$_unsafe), it will only match if the RHS contains at least one identifier.

Tips:

  • Javascript is very dynamic, and this is navie approach: write conservative rules and review for false positives
  • One simple statement per rule, not complex statements (yet)!
  • 'foo' does NOT match 'this.foo', if you are looking for something in global (e.g. 'alert()' ), you need to add two rules: 'alert.()' and '$_any.alert()'
  • Try the rule out in the experiment tab to test what it matches

Examples: See /common/template_rules.json and /common/rules.json

Running ScanJS

Run ScanJS in the browser

Run ScanJS from the command line

  • Install node.js
  • scanner.js -t DIRECTORY_PATH

Testing instructions

Tests use the mocha testing framework.

  • npm test
  • or in the browser:http://127.0.0.1:4000/tests/

Tests are included in the rules declaration (see common/rules.json) by specifying the following two attributes, which are specified in the form of a series of javascript statements:

  • testhit: The rule should match each of these statements individualy.
  • testmiss: The rule should not match all of these statements.

About

[DEPRECATED] Static analysis tool for javascript code.

Resources

Stars

426 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - mozilla/scanjs: [DEPRECATED] Static analysis tool for javascript code. · GitHub
Skip to content
This repository was archived by the owner on Sep 15, 2021. It is now read-only.

Repository files navigation

Development of ScanJS has stopped.

We are using ESLint instead. Your options:

  • XSS-prevention rule during CI with eslint-plugin-no-unsanitized. This assumes that you prevent/disallow obfuscation and that your code is subject to code review before it is being scanned (e.g., to catch intentional malicious/obfuscated code)
  • If you want something that warn for "all the things" that scanjs pointed out, you will need to use and build upon eslint-config-scanjs.

Thank you.


ScanJS was was a Static analysis tool for javascript code. ScanJS was created as an aid for security review, to help identify security issues in client-side web applications.

ScanJS used Acorn to convert sources to AST, then walks AST looking for source patterns. You could use the rules file supplied, or load your own rules.

ScanJS Rules

Rules are specified in JSON format - for an example see /common/template_rules.json

At a minimum, each must have rule is made up of 2 attributes:

  • name: the name of the rule
  • source: javascript source which matches one of the patterns below (see Rule Syntax below)

Optionally a rule may have the following attirbutes:

  • testhit: one more JavaScript statements (seperate by semi-colons) that the rule will match
  • testmiss: the rule should not match any of these statements
  • desc: description of the rule
  • threat: for catgorizing rules by threat

Rule Syntax

For the source attribute, the following basic statements are supported:

  • identifier foo: matches any identifier , "foo"
  • property $_any.foo: $_any is wildcard, matches anything.foo
  • objectproperty foo.bar: matches object and property, i.e. foo.bar

You can also matches function calls based on the same syntax:

  • call foo(): matches function calls with this name
  • propertycall $_any.foo: matches anything.foo() but not foo()
  • objectpropertycall: foo.bar(): matches foo.bar() only

You can also search for functions with matching literal arguments:

  • callargs foo('test',ignored,42): matches a function called foo, with 'test' as the first argument, anything as the second argument, and the number 42 as the third argument (i.e. matches ONLY literal arguments).
  • propertycallargs $_any.foo('test',ignored,42): same as above, but function has to be a property.
  • objectpropertycallargs foo.bar('test',ignored,42): same as above, but matches both object and property

You can also search for assignment to a specifically named identifier:

  • assignment foo=$_any: matches when foo is assigned to something
  • propertyassignment $_any.foo=$_any: matches when anything.foo is assigned to something
  • objectpropertyassignment foo.bar=$_any: matches when foo.bar is assigned to something

If you specify $_unsafe on the right hand side (e.g. foo.innerHTML=$_unsafe), it will only match if the RHS contains at least one identifier.

Tips:

  • Javascript is very dynamic, and this is navie approach: write conservative rules and review for false positives
  • One simple statement per rule, not complex statements (yet)!
  • 'foo' does NOT match 'this.foo', if you are looking for something in global (e.g. 'alert()' ), you need to add two rules: 'alert.()' and '$_any.alert()'
  • Try the rule out in the experiment tab to test what it matches

Examples: See /common/template_rules.json and /common/rules.json

Running ScanJS

Run ScanJS in the browser

Run ScanJS from the command line

  • Install node.js
  • scanner.js -t DIRECTORY_PATH

Testing instructions

Tests use the mocha testing framework.

  • npm test
  • or in the browser:http://127.0.0.1:4000/tests/

Tests are included in the rules declaration (see common/rules.json) by specifying the following two attributes, which are specified in the form of a series of javascript statements:

  • testhit: The rule should match each of these statements individualy.
  • testmiss: The rule should not match all of these statements.

About

[DEPRECATED] Static analysis tool for javascript code.

Resources

Stars

426 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - mozilla/scanjs: [DEPRECATED] Static analysis tool for javascript code. · GitHub
Skip to content
This repository was archived by the owner on Sep 15, 2021. It is now read-only.

Repository files navigation

Development of ScanJS has stopped.

We are using ESLint instead. Your options:

  • XSS-prevention rule during CI with eslint-plugin-no-unsanitized. This assumes that you prevent/disallow obfuscation and that your code is subject to code review before it is being scanned (e.g., to catch intentional malicious/obfuscated code)
  • If you want something that warn for "all the things" that scanjs pointed out, you will need to use and build upon eslint-config-scanjs.

Thank you.


ScanJS was was a Static analysis tool for javascript code. ScanJS was created as an aid for security review, to help identify security issues in client-side web applications.

ScanJS used Acorn to convert sources to AST, then walks AST looking for source patterns. You could use the rules file supplied, or load your own rules.

ScanJS Rules

Rules are specified in JSON format - for an example see /common/template_rules.json

At a minimum, each must have rule is made up of 2 attributes:

  • name: the name of the rule
  • source: javascript source which matches one of the patterns below (see Rule Syntax below)

Optionally a rule may have the following attirbutes:

  • testhit: one more JavaScript statements (seperate by semi-colons) that the rule will match
  • testmiss: the rule should not match any of these statements
  • desc: description of the rule
  • threat: for catgorizing rules by threat

Rule Syntax

For the source attribute, the following basic statements are supported:

  • identifier foo: matches any identifier , "foo"
  • property $_any.foo: $_any is wildcard, matches anything.foo
  • objectproperty foo.bar: matches object and property, i.e. foo.bar

You can also matches function calls based on the same syntax:

  • call foo(): matches function calls with this name
  • propertycall $_any.foo: matches anything.foo() but not foo()
  • objectpropertycall: foo.bar(): matches foo.bar() only

You can also search for functions with matching literal arguments:

  • callargs foo('test',ignored,42): matches a function called foo, with 'test' as the first argument, anything as the second argument, and the number 42 as the third argument (i.e. matches ONLY literal arguments).
  • propertycallargs $_any.foo('test',ignored,42): same as above, but function has to be a property.
  • objectpropertycallargs foo.bar('test',ignored,42): same as above, but matches both object and property

You can also search for assignment to a specifically named identifier:

  • assignment foo=$_any: matches when foo is assigned to something
  • propertyassignment $_any.foo=$_any: matches when anything.foo is assigned to something
  • objectpropertyassignment foo.bar=$_any: matches when foo.bar is assigned to something

If you specify $_unsafe on the right hand side (e.g. foo.innerHTML=$_unsafe), it will only match if the RHS contains at least one identifier.

Tips:

  • Javascript is very dynamic, and this is navie approach: write conservative rules and review for false positives
  • One simple statement per rule, not complex statements (yet)!
  • 'foo' does NOT match 'this.foo', if you are looking for something in global (e.g. 'alert()' ), you need to add two rules: 'alert.()' and '$_any.alert()'
  • Try the rule out in the experiment tab to test what it matches

Examples: See /common/template_rules.json and /common/rules.json

Running ScanJS

Run ScanJS in the browser

Run ScanJS from the command line

  • Install node.js
  • scanner.js -t DIRECTORY_PATH

Testing instructions

Tests use the mocha testing framework.

  • npm test
  • or in the browser:http://127.0.0.1:4000/tests/

Tests are included in the rules declaration (see common/rules.json) by specifying the following two attributes, which are specified in the form of a series of javascript statements:

  • testhit: The rule should match each of these statements individualy.
  • testmiss: The rule should not match all of these statements.

About

[DEPRECATED] Static analysis tool for javascript code.

Resources

Stars

426 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - mozilla/scanjs: [DEPRECATED] Static analysis tool for javascript code. · GitHub
Skip to content
This repository was archived by the owner on Sep 15, 2021. It is now read-only.

Repository files navigation

Development of ScanJS has stopped.

We are using ESLint instead. Your options:

  • XSS-prevention rule during CI with eslint-plugin-no-unsanitized. This assumes that you prevent/disallow obfuscation and that your code is subject to code review before it is being scanned (e.g., to catch intentional malicious/obfuscated code)
  • If you want something that warn for "all the things" that scanjs pointed out, you will need to use and build upon eslint-config-scanjs.

Thank you.


ScanJS was was a Static analysis tool for javascript code. ScanJS was created as an aid for security review, to help identify security issues in client-side web applications.

ScanJS used Acorn to convert sources to AST, then walks AST looking for source patterns. You could use the rules file supplied, or load your own rules.

ScanJS Rules

Rules are specified in JSON format - for an example see /common/template_rules.json

At a minimum, each must have rule is made up of 2 attributes:

  • name: the name of the rule
  • source: javascript source which matches one of the patterns below (see Rule Syntax below)

Optionally a rule may have the following attirbutes:

  • testhit: one more JavaScript statements (seperate by semi-colons) that the rule will match
  • testmiss: the rule should not match any of these statements
  • desc: description of the rule
  • threat: for catgorizing rules by threat

Rule Syntax

For the source attribute, the following basic statements are supported:

  • identifier foo: matches any identifier , "foo"
  • property $_any.foo: $_any is wildcard, matches anything.foo
  • objectproperty foo.bar: matches object and property, i.e. foo.bar

You can also matches function calls based on the same syntax:

  • call foo(): matches function calls with this name
  • propertycall $_any.foo: matches anything.foo() but not foo()
  • objectpropertycall: foo.bar(): matches foo.bar() only

You can also search for functions with matching literal arguments:

  • callargs foo('test',ignored,42): matches a function called foo, with 'test' as the first argument, anything as the second argument, and the number 42 as the third argument (i.e. matches ONLY literal arguments).
  • propertycallargs $_any.foo('test',ignored,42): same as above, but function has to be a property.
  • objectpropertycallargs foo.bar('test',ignored,42): same as above, but matches both object and property

You can also search for assignment to a specifically named identifier:

  • assignment foo=$_any: matches when foo is assigned to something
  • propertyassignment $_any.foo=$_any: matches when anything.foo is assigned to something
  • objectpropertyassignment foo.bar=$_any: matches when foo.bar is assigned to something

If you specify $_unsafe on the right hand side (e.g. foo.innerHTML=$_unsafe), it will only match if the RHS contains at least one identifier.

Tips:

  • Javascript is very dynamic, and this is navie approach: write conservative rules and review for false positives
  • One simple statement per rule, not complex statements (yet)!
  • 'foo' does NOT match 'this.foo', if you are looking for something in global (e.g. 'alert()' ), you need to add two rules: 'alert.()' and '$_any.alert()'
  • Try the rule out in the experiment tab to test what it matches

Examples: See /common/template_rules.json and /common/rules.json

Running ScanJS

Run ScanJS in the browser

Run ScanJS from the command line

  • Install node.js
  • scanner.js -t DIRECTORY_PATH

Testing instructions

Tests use the mocha testing framework.

  • npm test
  • or in the browser:http://127.0.0.1:4000/tests/

Tests are included in the rules declaration (see common/rules.json) by specifying the following two attributes, which are specified in the form of a series of javascript statements:

  • testhit: The rule should match each of these statements individualy.
  • testmiss: The rule should not match all of these statements.

About

[DEPRECATED] Static analysis tool for javascript code.

Resources

Stars

426 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - mozilla/scanjs: [DEPRECATED] Static analysis tool for javascript code. · GitHub
Skip to content
This repository was archived by the owner on Sep 15, 2021. It is now read-only.

Repository files navigation

Development of ScanJS has stopped.

We are using ESLint instead. Your options:

  • XSS-prevention rule during CI with eslint-plugin-no-unsanitized. This assumes that you prevent/disallow obfuscation and that your code is subject to code review before it is being scanned (e.g., to catch intentional malicious/obfuscated code)
  • If you want something that warn for "all the things" that scanjs pointed out, you will need to use and build upon eslint-config-scanjs.

Thank you.


ScanJS was was a Static analysis tool for javascript code. ScanJS was created as an aid for security review, to help identify security issues in client-side web applications.

ScanJS used Acorn to convert sources to AST, then walks AST looking for source patterns. You could use the rules file supplied, or load your own rules.

ScanJS Rules

Rules are specified in JSON format - for an example see /common/template_rules.json

At a minimum, each must have rule is made up of 2 attributes:

  • name: the name of the rule
  • source: javascript source which matches one of the patterns below (see Rule Syntax below)

Optionally a rule may have the following attirbutes:

  • testhit: one more JavaScript statements (seperate by semi-colons) that the rule will match
  • testmiss: the rule should not match any of these statements
  • desc: description of the rule
  • threat: for catgorizing rules by threat

Rule Syntax

For the source attribute, the following basic statements are supported:

  • identifier foo: matches any identifier , "foo"
  • property $_any.foo: $_any is wildcard, matches anything.foo
  • objectproperty foo.bar: matches object and property, i.e. foo.bar

You can also matches function calls based on the same syntax:

  • call foo(): matches function calls with this name
  • propertycall $_any.foo: matches anything.foo() but not foo()
  • objectpropertycall: foo.bar(): matches foo.bar() only

You can also search for functions with matching literal arguments:

  • callargs foo('test',ignored,42): matches a function called foo, with 'test' as the first argument, anything as the second argument, and the number 42 as the third argument (i.e. matches ONLY literal arguments).
  • propertycallargs $_any.foo('test',ignored,42): same as above, but function has to be a property.
  • objectpropertycallargs foo.bar('test',ignored,42): same as above, but matches both object and property

You can also search for assignment to a specifically named identifier:

  • assignment foo=$_any: matches when foo is assigned to something
  • propertyassignment $_any.foo=$_any: matches when anything.foo is assigned to something
  • objectpropertyassignment foo.bar=$_any: matches when foo.bar is assigned to something

If you specify $_unsafe on the right hand side (e.g. foo.innerHTML=$_unsafe), it will only match if the RHS contains at least one identifier.

Tips:

  • Javascript is very dynamic, and this is navie approach: write conservative rules and review for false positives
  • One simple statement per rule, not complex statements (yet)!
  • 'foo' does NOT match 'this.foo', if you are looking for something in global (e.g. 'alert()' ), you need to add two rules: 'alert.()' and '$_any.alert()'
  • Try the rule out in the experiment tab to test what it matches

Examples: See /common/template_rules.json and /common/rules.json

Running ScanJS

Run ScanJS in the browser

Run ScanJS from the command line

  • Install node.js
  • scanner.js -t DIRECTORY_PATH

Testing instructions

Tests use the mocha testing framework.

  • npm test
  • or in the browser:http://127.0.0.1:4000/tests/

Tests are included in the rules declaration (see common/rules.json) by specifying the following two attributes, which are specified in the form of a series of javascript statements:

  • testhit: The rule should match each of these statements individualy.
  • testmiss: The rule should not match all of these statements.

About

[DEPRECATED] Static analysis tool for javascript code.

Resources

Stars

426 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - mozilla/scanjs: [DEPRECATED] Static analysis tool for javascript code. · GitHub
Skip to content
This repository was archived by the owner on Sep 15, 2021. It is now read-only.

Repository files navigation

Development of ScanJS has stopped.

We are using ESLint instead. Your options:

  • XSS-prevention rule during CI with eslint-plugin-no-unsanitized. This assumes that you prevent/disallow obfuscation and that your code is subject to code review before it is being scanned (e.g., to catch intentional malicious/obfuscated code)
  • If you want something that warn for "all the things" that scanjs pointed out, you will need to use and build upon eslint-config-scanjs.

Thank you.


ScanJS was was a Static analysis tool for javascript code. ScanJS was created as an aid for security review, to help identify security issues in client-side web applications.

ScanJS used Acorn to convert sources to AST, then walks AST looking for source patterns. You could use the rules file supplied, or load your own rules.

ScanJS Rules

Rules are specified in JSON format - for an example see /common/template_rules.json

At a minimum, each must have rule is made up of 2 attributes:

  • name: the name of the rule
  • source: javascript source which matches one of the patterns below (see Rule Syntax below)

Optionally a rule may have the following attirbutes:

  • testhit: one more JavaScript statements (seperate by semi-colons) that the rule will match
  • testmiss: the rule should not match any of these statements
  • desc: description of the rule
  • threat: for catgorizing rules by threat

Rule Syntax

For the source attribute, the following basic statements are supported:

  • identifier foo: matches any identifier , "foo"
  • property $_any.foo: $_any is wildcard, matches anything.foo
  • objectproperty foo.bar: matches object and property, i.e. foo.bar

You can also matches function calls based on the same syntax:

  • call foo(): matches function calls with this name
  • propertycall $_any.foo: matches anything.foo() but not foo()
  • objectpropertycall: foo.bar(): matches foo.bar() only

You can also search for functions with matching literal arguments:

  • callargs foo('test',ignored,42): matches a function called foo, with 'test' as the first argument, anything as the second argument, and the number 42 as the third argument (i.e. matches ONLY literal arguments).
  • propertycallargs $_any.foo('test',ignored,42): same as above, but function has to be a property.
  • objectpropertycallargs foo.bar('test',ignored,42): same as above, but matches both object and property

You can also search for assignment to a specifically named identifier:

  • assignment foo=$_any: matches when foo is assigned to something
  • propertyassignment $_any.foo=$_any: matches when anything.foo is assigned to something
  • objectpropertyassignment foo.bar=$_any: matches when foo.bar is assigned to something

If you specify $_unsafe on the right hand side (e.g. foo.innerHTML=$_unsafe), it will only match if the RHS contains at least one identifier.

Tips:

  • Javascript is very dynamic, and this is navie approach: write conservative rules and review for false positives
  • One simple statement per rule, not complex statements (yet)!
  • 'foo' does NOT match 'this.foo', if you are looking for something in global (e.g. 'alert()' ), you need to add two rules: 'alert.()' and '$_any.alert()'
  • Try the rule out in the experiment tab to test what it matches

Examples: See /common/template_rules.json and /common/rules.json

Running ScanJS

Run ScanJS in the browser

Run ScanJS from the command line

  • Install node.js
  • scanner.js -t DIRECTORY_PATH

Testing instructions

Tests use the mocha testing framework.

  • npm test
  • or in the browser:http://127.0.0.1:4000/tests/

Tests are included in the rules declaration (see common/rules.json) by specifying the following two attributes, which are specified in the form of a series of javascript statements:

  • testhit: The rule should match each of these statements individualy.
  • testmiss: The rule should not match all of these statements.

About

[DEPRECATED] Static analysis tool for javascript code.

Resources

Stars

426 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - mozilla/scanjs: [DEPRECATED] Static analysis tool for javascript code. · GitHub
Skip to content
This repository was archived by the owner on Sep 15, 2021. It is now read-only.

Repository files navigation

Development of ScanJS has stopped.

We are using ESLint instead. Your options:

  • XSS-prevention rule during CI with eslint-plugin-no-unsanitized. This assumes that you prevent/disallow obfuscation and that your code is subject to code review before it is being scanned (e.g., to catch intentional malicious/obfuscated code)
  • If you want something that warn for "all the things" that scanjs pointed out, you will need to use and build upon eslint-config-scanjs.

Thank you.


ScanJS was was a Static analysis tool for javascript code. ScanJS was created as an aid for security review, to help identify security issues in client-side web applications.

ScanJS used Acorn to convert sources to AST, then walks AST looking for source patterns. You could use the rules file supplied, or load your own rules.

ScanJS Rules

Rules are specified in JSON format - for an example see /common/template_rules.json

At a minimum, each must have rule is made up of 2 attributes:

  • name: the name of the rule
  • source: javascript source which matches one of the patterns below (see Rule Syntax below)

Optionally a rule may have the following attirbutes:

  • testhit: one more JavaScript statements (seperate by semi-colons) that the rule will match
  • testmiss: the rule should not match any of these statements
  • desc: description of the rule
  • threat: for catgorizing rules by threat

Rule Syntax

For the source attribute, the following basic statements are supported:

  • identifier foo: matches any identifier , "foo"
  • property $_any.foo: $_any is wildcard, matches anything.foo
  • objectproperty foo.bar: matches object and property, i.e. foo.bar

You can also matches function calls based on the same syntax:

  • call foo(): matches function calls with this name
  • propertycall $_any.foo: matches anything.foo() but not foo()
  • objectpropertycall: foo.bar(): matches foo.bar() only

You can also search for functions with matching literal arguments:

  • callargs foo('test',ignored,42): matches a function called foo, with 'test' as the first argument, anything as the second argument, and the number 42 as the third argument (i.e. matches ONLY literal arguments).
  • propertycallargs $_any.foo('test',ignored,42): same as above, but function has to be a property.
  • objectpropertycallargs foo.bar('test',ignored,42): same as above, but matches both object and property

You can also search for assignment to a specifically named identifier:

  • assignment foo=$_any: matches when foo is assigned to something
  • propertyassignment $_any.foo=$_any: matches when anything.foo is assigned to something
  • objectpropertyassignment foo.bar=$_any: matches when foo.bar is assigned to something

If you specify $_unsafe on the right hand side (e.g. foo.innerHTML=$_unsafe), it will only match if the RHS contains at least one identifier.

Tips:

  • Javascript is very dynamic, and this is navie approach: write conservative rules and review for false positives
  • One simple statement per rule, not complex statements (yet)!
  • 'foo' does NOT match 'this.foo', if you are looking for something in global (e.g. 'alert()' ), you need to add two rules: 'alert.()' and '$_any.alert()'
  • Try the rule out in the experiment tab to test what it matches

Examples: See /common/template_rules.json and /common/rules.json

Running ScanJS

Run ScanJS in the browser

Run ScanJS from the command line

  • Install node.js
  • scanner.js -t DIRECTORY_PATH

Testing instructions

Tests use the mocha testing framework.

  • npm test
  • or in the browser:http://127.0.0.1:4000/tests/

Tests are included in the rules declaration (see common/rules.json) by specifying the following two attributes, which are specified in the form of a series of javascript statements:

  • testhit: The rule should match each of these statements individualy.
  • testmiss: The rule should not match all of these statements.

About

[DEPRECATED] Static analysis tool for javascript code.

Resources

Stars

426 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages