Skip to content

Instantly share code, notes, and snippets.

@oreoshake
Last active December 15, 2015 15:19
Show Gist options
  • Save oreoshake/5281050 to your computer and use it in GitHub Desktop.
Save oreoshake/5281050 to your computer and use it in GitHub Desktop.
Woke up, saw a javascript parser generator, wrote this
w3:
policy
= directive (" "? ";" " "? directive?)*
directive
= report_uri_directive / declaritive_directive
report_uri_directive
= "report-uri " host_source? [a-zA-Z/_-]*
declaritive_directive
= name:directive_name " " sources:source_list {
// inline/eval values are only valid in style/script/default blocks
switch(name) {
case "default-src":
case "script-src":
case "style-src":
break;
default:
for(var i=0; i < sources.length; i++) {
var s = sources[i][0];
if(s === "'unsafe-inline'" || s === "'unsafe-eval'") {
console.log(name + " doesn't honor " + s);
return null;
}
}
}
return name + " " + sources;
}
directive_name
= "default-src" / "script-src" / "object-src" / "style-src" / "img-src" / "media-src" / "frame-src" / "font-src" / "connect-src"
source_list
= "'none'" / (source_expression [ ]?)* // space is only optional if before semi-colon :-/
source_expression
= keyword_source / scheme_source / host_source // jank covers up javascript/blob/etc
host_source
= (scheme "://" / "/")? host (port)?
scheme_source
= scheme_only ":"
keyword_source
= "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
scheme_only
= "data" / "javascript" / "blob" / "chrome-extension" / "about"
scheme
= "https" / "http" / "ws"
host
= ("*.")? host_char+ ("." host_char+)* / "*"
host_char
= [a-zA-Z] / [0-9] / '-'
port
= (":" [0-9]+) / ":*"
Firefox OG:
policy
= directive (" "? ";" " "? directive?)*
directive
= report_uri_directive / declaritive_directive
report_uri_directive
= "report-uri " host_source? [a-zA-Z/_\-.]*
declaritive_directive
= name:directive_name " " sources:source_list {
// inline/eval values are only valid in style/script/default blocks
if(name === 'options') {
for(var i=0; i < sources.length; i++) {
var s = sources[i][0];
if(s !== "inline-script" && s !== "eval-script") {
console.log("Invalid value in 'options' directive: " + s);
return null;
}
}
} else if(name === 'style-src') {
if(sources.indexOf('inline-script') > -1) {
console.log("inline-script is not honored in the style-src directive (FF bug)");
}
}
// verify inline-script/eval is in the right place
for(var i=0; i < sources.length; i++) {
var s = sources[i][0];
if(name !== 'options' && (s === 'inline-script' || s === 'eval-script')) {
console.log(s + " is not allowed in the " + name + " directive, it only works in the 'options' directive");
return null;
}
}
return name + " " + sources;
}
directive_name
= "default-src" / "allow" / "options" / "script-src" / "object-src" / "style-src" / "img-src" / "media-src" / "frame-src" / "font-src" / "xhr-src" / "frame-ancestors" / "form-action"
source_list
= "'none'" / (source_expression [ ]?)*
source_expression
= keyword_source / scheme_source / host_source
host_source
= (scheme "://" / "/")? host (port)?
scheme_source
= scheme_only ":"
keyword_source
= "'self'" / "inline-script" / "eval-script"
scheme_only
= "data" / "javascript" / "blob" / "about"
scheme
= "https" / "http" / "ws"
host
= ("*.")? host_char+ ("." host_char+)* / "*"
host_char
= [a-zA-Z] / [0-9] / '-'
port
= (":" [0-9]+) / ":*"
@devd
Copy link

devd commented Mar 31, 2013

Cool! BTW, the Mozilla CSP Parser is already in JS, if you want a quick way to write ``CSPLint'' (an idea that I really like)

http://mxr.mozilla.org/mozilla-central/source/content/base/src/CSPUtils.jsm

@oreoshake
Copy link
Author

Good call, this attempt was just an academic exercise after stumbling across an online parser generator (sets off all my nerd alarms) 😄

@imelven is that 1.0 compliant? Having a parser for the OG header would be nice for the time being, so I'll incorporate this regardless.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment