Verified Commit 004fc760 authored by Booteille's avatar Booteille

Improve CSP management. Enforce CSP for Qwant.

parent f6ebf051
......@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- [Invidious] Enforce CSP for qwant.com
- [Nitter] Enforce CSP for embeds
### Fixed
- [Nitter] Fix query missing from redirection. #38
## [0.13.1] - 2019-10-09
### Added
......
......@@ -36,6 +36,9 @@ export const config = {
"youtu.be",
"s.ytimg.com",
],
toInterceptCSP: [
"www.qwant.com",
],
},
instance: "invidio.us",
isEnabled: true,
......@@ -71,6 +74,7 @@ export const config = {
"pbs.twimg.com",
"video.twimg.com",
],
toInterceptCSP: [],
},
instance: "nitter.net",
isEnabled: true,
......
......@@ -18,14 +18,24 @@ export enum PING_ERROR {
TYPE,
}
export enum FILTER_TYPE {
CSP,
REDIRECT
}
/**
* Generate redirection filters from domains
*
* @param {FILTER_TYPE} type
* @param {string} service
* @returns {Promise<unknown[]>}
*/
export const domainsFilter = async (service?: string) => {
const invidious = _.map((await domainsToRedirect()).invidious, (d: string) => `*://${d}/*`);
const nitter = _.map((await domainsToRedirect()).nitter, (d: string) => `*://${d}/*`);
export const filterDomains = async (type: FILTER_TYPE, service?: string) => {
const domains = type === FILTER_TYPE.CSP ? await domainsToInterceptCSP() : await domainsToRedirect();
const filter = type === FILTER_TYPE.CSP ? "*://*.{d}/*" : "*://{d}/*";
const invidious = _.map(domains.invidious, (d: string) => filter.replace("{d}", d));
const nitter = _.map(domains.nitter, (d: string) => filter.replace("{d}", d));
if (service === "invidious") {
return invidious;
......@@ -33,9 +43,24 @@ export const domainsFilter = async (service?: string) => {
return nitter;
}
return _.concat(_.map((await domainsToRedirect()).invidious, (d: string) => `*://${d}/*`),
_.map((await domainsToRedirect()).nitter, (d: string) => `*://${d}/*`),
);
return _.concat(invidious, nitter);
};
/**
* Returns array of domains needing to change their CSP policy
* @returns {Promise<unknown[]>}
*/
export const domainsToInterceptCSP = async () => {
try {
const settings = await SettingsManager.load();
return {
invidious: settings.invidious.appSettings.domains.toInterceptCSP,
nitter: settings.nitter.appSettings.domains.toInterceptCSP,
};
} catch (e) {
console.error(e);
}
};
/**
......
......@@ -6,7 +6,7 @@ import * as NitterManager from "./lib/API/nitter";
import * as BackwardCompatibilityManager from "./lib/backward_compatibility";
import {toggleIcon} from "./lib/browser_action";
import {Event} from "./lib/events";
import {canWriteToClipboard, domainsFilter, domainToUrl, info, isEnabled} from "./lib/helpers";
import {canWriteToClipboard, domainToUrl, FILTER_TYPE, filterDomains, info, isEnabled} from "./lib/helpers";
import {toggleCleanable} from "./lib/page_action";
import * as SettingsManager from "./lib/settings";
......@@ -24,7 +24,7 @@ const handleCSP = async (r) => {
}
const headersToDelete = ["content-security-policy", "x-frame-options"];
const frameFilters = ["http://*", "http://*:*", "https://*", "https://*:*", "file://*"].join(" ");
const sourceFilters = ["http://*", "http://*:*", "https://*", "https://*:*", "file://*"].join(" ");
let csp = "";
r.responseHeaders = r.responseHeaders.filter((h) => {
......@@ -35,7 +35,9 @@ const handleCSP = async (r) => {
return !_.includes(headersToDelete, name);
});
csp = replaceCSP(csp, "frame-ancestors", frameFilters);
csp = replaceCSP(csp, "frame-ancestors", sourceFilters);
csp = replaceCSP(csp, "media-src", sourceFilters);
csp = replaceCSP(csp, "frame-src", sourceFilters);
r.responseHeaders.push({
name: headersToDelete[0],
......@@ -84,9 +86,7 @@ const redirectInvidious = async (r) => {
const redirectNitter = async (r) => {
info(`Trying to redirect ${r.url}`);
const settings = await SettingsManager.load();
const newUrl = await NitterManager.generateUrl(new URL(r.url), domainToUrl(settings.nitter.appSettings.instance));
const newUrl = await NitterManager.generateUrl(new URL(r.url));
info(`Redirecting to ${newUrl.href}`);
......@@ -104,7 +104,7 @@ const redirect = async (r) => {
if (await InvidiousManager.mustRedirect(r)) {
browser.webRequest.onHeadersReceived.addListener(
await handleCSP,
{urls: await domainsFilter("invidious"), types: ["sub_frame", "object"]},
{urls: await filterDomains(FILTER_TYPE.CSP, "invidious"), types: ["sub_frame", "object"]},
["blocking", "responseHeaders"],
);
......@@ -112,7 +112,7 @@ const redirect = async (r) => {
} else if (await NitterManager.mustRedirect(r)) {
browser.webRequest.onHeadersReceived.addListener(
await handleCSP,
{urls: await domainsFilter("nitter")},
{urls: await filterDomains(FILTER_TYPE.CSP, "nitter"), types: ["sub_frame", "object"]},
["blocking", "responseHeaders"],
);
......@@ -128,9 +128,15 @@ const reload = async () => {
browser.webRequest.onBeforeRequest.removeListener(await run);
}
browser.webRequest.onHeadersReceived.addListener(
await handleCSP,
{urls: await filterDomains(FILTER_TYPE.CSP, "invidious"), types: ["main_frame"]},
["blocking", "responseHeaders"],
);
browser.webRequest.onBeforeRequest.addListener(
await run,
{urls: await domainsFilter()},
{urls: await filterDomains(FILTER_TYPE.REDIRECT)},
["blocking"],
);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment