Skip to content

Instantly share code, notes, and snippets.

@diegodlh
Last active June 21, 2019 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diegodlh/f70f367093240ec97c7860c306069fef to your computer and use it in GitHub Desktop.
Save diegodlh/f70f367093240ec97c7860c306069fef to your computer and use it in GitHub Desktop.
Header Editor custom function to include Hypothesis as trusted source in CSP
// CSP directives to which Hypothesis will be added as trusted source
let directives = ['script-src', 'style-src', 'font-src', 'frame-src'];
// Hypothesis sources
let hyp_sources = ['hypothes.is', '*.hypothes.is'];
for (const i in val) {
// where val is the list of http response headers,
// for each header check if it is a Content Security Policy header
if (val[i].name.toLowerCase() === 'content-security-policy') {
let policies = {};
val[i].value.split(';').forEach(policy => { // policy directives are separated with ';'
// for each policy directive,
// save list of sources under directive's name
policy = policy.trim().split(' '); // directive sources are separated with ' '
let directive = policy[0];
let sources = policy.slice(1);
policies[directive] = sources; // to-do: if directive exists, append
})
directives.forEach(directive => {
// for each directive to which Hypothesis should be added as trusted source
if (directive in policies) {
// if directive already exists in the CSP response header,
// append Hypothesis sources as trusted sources to it
policies[directive] = policies[directive].concat(hyp_sources);
} else if ('default-src' in policies) { // to-do: some directives fall back to others before (e.g. frame-src)
// if directive was not included in the CSP response header,
// but the default directive is set to 'none' (meaning that
// resource types, for which the corresponding fetch directive
// is absent, should be blocked), add the directive, and
// append Hypothesis sources as trusted sources to it
if (policies['default-src'].includes("'none'")) { // is it always 'none'?
policies[directive] = hyp_sources;
}
}
})
// rebuild the csp header value before returning it
let value = [];
Object.keys(policies).forEach(directive => {
value.push([directive].concat(policies[directive]).join(' '));
})
value = value.join(';');
val[i].value = value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment