PDF Viewer should use a different principal (defense in depth)
Categories
(Firefox :: PDF Viewer, enhancement, P3)
Tracking
()
People
(Reporter: jwkbugzilla, Unassigned)
References
(Blocks 1 open bug)
Details
(Keywords: sec-want, Whiteboard: [pdfjs-integration])
Comment 1•7 years ago
|
||
Comment 2•7 years ago
|
||
Reporter | ||
Comment 3•7 years ago
|
||
Reporter | ||
Comment 4•7 years ago
|
||
Comment 5•5 years ago
|
||
Clearing needinfo's that I'm unlikely to work on in the near future.
Updated•3 years ago
|
Updated•3 years ago
|
Comment 6•5 months ago
•
|
||
When this issue was filed, the concept of "precursor" did not exist. It does exist now, so we can feasibly consider using a null principal for PDF viewers.
A potential way to resolve this issue is to force all PDF viewers to have an opaque origin:
- E.g. by rewriting the CSP in PdfStreamConverter.sys.mjs and (and something else for non-http channels).
- alternatively: mint a null principal before setting aRequest.owner, with the precursor set to the PDF viewer (and/or the original URL).
- With the above change, the viewer document is now a null principal instead of a content principal. There are several internal checks that confirm that the principal is
resource://pdf.js
. These would have to change, to check that the principal is a null principal with the precursorresource://pdf.js
. - Besides these internal checks, the stream converter itself also needs to be updated: it currently uses
postMessage
to send data to the PDF.js origin. An alternative mechanism would be to useCustomEvent
to send data from system privileged code into the viewer. CustomEvent does not support transferables (an optimization to reduce memory overhead). An alternative to that would be to construct aMessageChannel
and send a port to the viewer. Then the viewer can use the same logic that it had before to send data via the MessagePort.- using CustomEvent would also fix bug 1685092. Side note, in that bug CustomEvent was also proposed and accepted as an alternative to
postMessage
.
- using CustomEvent would also fix bug 1685092. Side note, in that bug CustomEvent was also proposed and accepted as an alternative to
Comment 7•5 months ago
|
||
(I meant to mark this bug as a blocker of bug 1454760 - before we can ever consider allowing extensions to run content script in the PDF viewer, we need to make sure that the viewer cannot script unrelated origins)
Comment 8•5 months ago
|
||
(In reply to Rob Wu [:robwu] from comment #6)
[...] An alternative mechanism would be to use
CustomEvent
to send data from system privileged code into the viewer. CustomEvent does not support transferables (an optimization to reduce memory overhead).
A solution that increases memory usage does not seem like a good idea, at least as far as I'm concerned.
Comment 9•5 months ago
|
||
There are several internal checks that confirm that the principal is resource://pdf.js
Many of them are broken, AFAICT. There's some discussion in Bug 1918257 about this as well (It might be considered a dupe of this). IT talks about another user case we have for identifying PDF.js
Comment 10•5 months ago
|
||
(In reply to Jonas Jenwald [:Snuffleupagus] from comment #8)
(In reply to Rob Wu [:robwu] from comment #6)
[...] An alternative mechanism would be to use
CustomEvent
to send data from system privileged code into the viewer. CustomEvent does not support transferables (an optimization to reduce memory overhead).A solution that increases memory usage does not seem like a good idea, at least as far as I'm concerned.
The next sentence after the quote that you clipped mentions MessageChannel
(and its pair of MessagePort), which do support transferables, to minimize impact on memory usage. In conjunction with CustomEvent
it would look like this:
window.addEventListener("eventName, e => {
let port = event.detail;
port.onmessage = e => {
console.log("Received", e.data);
};
});
var { port1, port2 } = new MessageChannel();
window.dispatchEvent(new CustomEvent("eventName", { detail: port1 }));
var data = new Uint8Array([1, 2, 3]);
port2.postMessage(data, [ data.buffer ]);
console.log("Sent", data); // Shows an empty array - the data has been transferred elsewhere.
Comment 11•5 months ago
|
||
:robwu, can the port be "transfered" from privileged code to the viewer ?
Usually we've to clone the details in the window before sending them in a CustomEvent. I don't think a port is cloneable.
Comment 12•5 months ago
|
||
There's a resource
principal as well as the PDFJS code using a content-principal of the target URL to fetch the pdf file with a contentPolicyType of SEC_OTHER
I think there's value in finding a pdfjs-specific solution rather than making up stuff that sort-of works on the fly.
We could mint a new contentPolicyType "TYPE_PDFJS_DOWNLOAD" to treat this differently (That won't help with the document principal though)
We could also use an ExtendedPrincipal (an array of [foo.example/test.pdf, resource://pdfjs-url]
) and check the principal in nsContentUtils code ( browserglue).
Comment 13•5 months ago
|
||
Last I checked we can't use expanded principals for documents, however. :-(
Description
•