Simplified CSP HTTP header injection, avoiding report-to until actually supported by browsers.
This commit is contained in:
parent
c9c7b7aefe
commit
209d50b0c1
|
@ -1,6 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
|
||||
function ReportingCSP(reportURI, reportGroup) {
|
||||
const REPORT_TO_SUPPORTED = false;
|
||||
// TODO: figure out if we're running on a browser supporting the report-to
|
||||
// CSP directive, breaking report-uri, see
|
||||
// 1. https://www.w3.org/TR/CSP3/#directive-report-uri
|
||||
// 2. https://bugs.chromium.org/p/chromium/issues/detail?id=726634
|
||||
// 3. https://bugzilla.mozilla.org/show_bug.cgi?id=1391243
|
||||
|
||||
const REPORT_TO = {
|
||||
name: "Report-To",
|
||||
value: JSON.stringify({ "url": reportURI,
|
||||
|
@ -9,39 +16,40 @@ function ReportingCSP(reportURI, reportGroup) {
|
|||
};
|
||||
return Object.assign(
|
||||
new CapsCSP(new NetCSP(
|
||||
`report-uri ${reportURI};`,
|
||||
`;report-to ${reportGroup};`
|
||||
)),
|
||||
REPORT_TO_SUPPORTED ? `;report-to ${reportGroup};`
|
||||
: `report-uri ${reportURI};`
|
||||
)),
|
||||
{
|
||||
reportURI,
|
||||
reportGroup,
|
||||
patchHeaders(responseHeaders, capabilities) {
|
||||
let header = null;
|
||||
let hasReportTo = false;
|
||||
let needsReportTo = REPORT_TO_SUPPORTED;
|
||||
for (let h of responseHeaders) {
|
||||
if (this.isMine(h)) {
|
||||
header = h;
|
||||
h.value = this.inject(h.value, "");
|
||||
} else if (h.name === REPORT_TO.name && h.value === REPORT_TO.value) {
|
||||
hasReportTo = true;
|
||||
h.value = "";
|
||||
} else if (needsReportTo &&
|
||||
h.name === REPORT_TO.name && h.value === REPORT_TO.value) {
|
||||
needsReportTo = false;
|
||||
}
|
||||
}
|
||||
|
||||
let blocker = capabilities && this.buildFromCapabilities(capabilities);
|
||||
if (blocker) {
|
||||
if (!hasReportTo) {
|
||||
if (needsReportTo) {
|
||||
responseHeaders.push(REPORT_TO);
|
||||
}
|
||||
if (header) {
|
||||
header.value = this.inject(header.value, blocker);
|
||||
header.value = blocker;
|
||||
} else {
|
||||
header = this.asHeader(blocker);
|
||||
responseHeaders.push(header);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return header;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,20 @@
|
|||
"use strict";
|
||||
|
||||
class NetCSP extends CSP {
|
||||
constructor(start, end) {
|
||||
constructor(start) {
|
||||
super();
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
|
||||
isMine(header) {
|
||||
let {name, value} = header;
|
||||
if (name.toLowerCase() !== CSP.headerName) return false;
|
||||
let startIdx = value.indexOf(this.start);
|
||||
return startIdx > -1 && startIdx < value.lastIndexOf(this.end);
|
||||
return name.toLowerCase() === CSP.headerName && value.startsWith(this.start);
|
||||
}
|
||||
|
||||
inject(headerValue, mine) {
|
||||
let startIdx = headerValue.indexOf(this.start);
|
||||
if (startIdx < 0) return `${headerValue};${mine}`;
|
||||
let endIdx = headerValue.lastIndexOf(this.end);
|
||||
let retValue = `${headerValue.substring(0, startIdx)}${mine}`;
|
||||
|
||||
return endIdx < 0 ? retValue : `${retValue}${headerValue.substring(endIdx + this.end.length + 1)}`;
|
||||
}
|
||||
|
||||
build(...directives) {
|
||||
return `${this.start}${super.build(...directives)}${this.end}`;
|
||||
return `${this.start}${super.build(...directives)}`;
|
||||
}
|
||||
|
||||
|
||||
cleanup(headers) {
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue