Manipulation with Offscreen Canvas allows bypassing tainting restrictions
Categories
(Core :: Graphics: Canvas2D, defect, P2)
Tracking
()
People
(Reporter: kirtikumar.a.r, Assigned: aosmond)
References
Details
(Keywords: csectype-sop, reporter-external, sec-moderate, Whiteboard: [adv-main127+][adv-esr115.12+])
Attachments
(4 files, 1 obsolete file)
|
32.96 KB,
application/zip
|
Details | |
|
48 bytes,
text/x-phabricator-request
|
pascalc
:
approval-mozilla-beta+
dveditz
:
sec-approval+
|
Details | Review |
|
48 bytes,
text/x-phabricator-request
|
phab-bot
:
approval-mozilla-esr115+
|
Details | Review |
|
238 bytes,
text/plain
|
Details |
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Steps to reproduce:
- Download the attached ZIP
- Extract it into a folder
- Visit the path locally /canvas_report/main_entry/UntaintingFFDemo.htm
Actual results:
The tainting of the ImageData is possible due to Same-Origin-Policy Bypass
Expected results:
It should block from changing
| Reporter | ||
Comment 1•1 year ago
|
||
This is from Bug 1833876
| Reporter | ||
Comment 2•1 year ago
|
||
A Video PoC to view the difference between Chrome and Firefox can be found attached. The previous issue is public. This appears to be an issue on the file:/// while the network protocol is not working. This is strange because, for the network protocol, the patch is working and not for the storage and maybe some other protocols.
@Gijs, can you please help with triaging this? Thanks!
Comment 3•1 year ago
|
||
Is there a difference between how this works for offscreen canvas vs. "regular" canvas?
| Reporter | ||
Comment 4•1 year ago
|
||
Yes, when you have the image over other protocols same as for the file: it has differences in regular and offscreen. PoC: https://drive.google.com/file/d/1L_Hu_jHm_mBYgOjFQAUOPt2CKkNLLq_P/view?usp=sharing
This poc demonstrates the difference on the 124.0.2, any other to test on?
Updated•1 year ago
|
Comment 5•1 year ago
|
||
I don't think I have anything to add at this point. The graphics/canvas-knowledgeable folks will look into this. bug 1558299 is potentially related.
| Reporter | ||
Comment 6•1 year ago
|
||
Okay, thanks! I assume this issue was verified? I can work on other 2 vulnerability reports?
Updated•1 year ago
|
| Assignee | ||
Comment 7•1 year ago
|
||
We didn't check for a null HTMLCanvasElement when caching results from drawing an HTMLImageElement:
https://searchfox.org/mozilla-central/rev/c7df16ffad1f12a19c81c16bce0b65e4a15304d0/dom/canvas/CanvasImageCache.cpp#288
So when we do the lookup for a new OffscreenCanvas, we hit the cache and avoid tainting ourselves. That is why it has to draw it to an OffscreenCanvas at least once before drawing to a second OffscreenCanvas.
| Assignee | ||
Comment 8•1 year ago
|
||
| Assignee | ||
Comment 9•1 year ago
|
||
I think this could also be triggered with an HTMLCanvasElement that creates the cache entry, is then destroyed, and recreated using the same pointer before the cache entry expires.
| Assignee | ||
Comment 10•1 year ago
|
||
Comment on attachment 9397281 [details]
Bug 1891319.
Security Approval Request
- How easily could an exploit be constructed based on the patch?: I would say easily. It is clear we didn't clear the cache when an element went away before, and a closer inspection would show that we have a null pointer as part of the key for OffscreenCanvas.
- Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
- Which branches (beta, release, and/or ESR) are affected by this flaw, and do the release status flags reflect this affected/unaffected state correctly?: All
- If not all supported branches, which bug introduced the flaw?: None
- Do you have backports for the affected branches?: Yes
- If not, how different, hard to create, and risky will they be?: Only ESR115 required some manual merging, nothing extensive.
- How likely is this patch to cause regressions; how much testing does it need?: Unlikely. We have very good coverage of drawing images into a canvas, so the codepaths should be reasonably well tested.
- Is the patch ready to land after security approval is given?: Yes
- Is Android affected?: Yes
| Reporter | ||
Comment 11•1 year ago
|
||
Oh, that is interesting. The patch was so quick within a week it was done. This felt so good. Thank you!
| Assignee | ||
Comment 12•1 year ago
|
||
To summarize the patch:
-
It switches us to from using
HTMLCanvasElementas part of the key in theCanvasImageCacheto using theCanvasRenderingContext2D. This allows us to keep using a single pointer as part of the key, as well as retaining image element caching functionality for main threadOffscreenCanvas. Since that just supplies thethispointer, it should never be null avoiding the case where a cache hit from a differentOffscreenCanvaswill avoid tainting. -
It now clears any entries tied to the
CanvasRenderingContext2Dobject in its destructor. This avoids the case where a destroyed/recreatedHTMLCanvasElement(nowCanvasRenderingContext2D) might have the same pointer, and thus resulting in cache hits without tainting on a different canvas. The cache entries would have been cleared after a few seconds, but that is enough time, especially when it can be repeated again and again.
| Assignee | ||
Comment 13•1 year ago
|
||
(In reply to Kirtikumar Anandrao Ramchandani from comment #11)
Oh, that is interesting. The patch was so quick within a week it was done. This felt so good. Thank you!
Thank you for your report and reduced test case!
| Reporter | ||
Comment 14•1 year ago
|
||
Hello,
Thank you very much for the well-summarized patch. So I assume this would be included in the upcoming advisories?
Comment 15•1 year ago
|
||
I'm rating this one "sec-moderate" based on the original testcases being limited to file:/// (see some of the see-also bugs). Kirtikumar may wish to investigate comment 9 to see if a reliable http-based testcase could be constructed, and if so we could rate this sec-high.
Comment 16•1 year ago
|
||
Comment on attachment 9397281 [details]
Bug 1891319.
sec-approval+ = dveditz
Comment 17•1 year ago
|
||
So I assume this would be included in the upcoming advisories?
It will be in the advisories of the release it is fixed in.
Updated•1 year ago
|
| Reporter | ||
Comment 18•1 year ago
|
||
Kirtikumar may wish to investigate comment 9 to see if a reliable http-based testcase could be constructed, and if so we could rate this sec-high.
I assume that a poc with slight changes from Chrome Bug 40093588 and Chrome Bug 40093490 can bypass the same way and fetch the image cross-origin bypassing the SOP using canvas.
@Andrew, any possibility you can confirm if a similar idea with slight changes in it would work? In the Chrome bug, it will fetch the bitmap-wise while in this we would try to use a tainting approach of canvas drawing and fetching it.
I am not sure but earlier, a similar one can be used in this scenario to fetch details for the vulnerability of the Comment 12 which Andrew shared a description about. :)
Comment 19•1 year ago
|
||
FYI :dveditz/:aosmond This did not land in time for Fx126.
We are now in RC week for Fx126.
Updated•1 year ago
|
Comment 20•1 year ago
|
||
Can we please get this landed, Andrew? We'll need Beta and ESR115 patches created and nominated for uplift also.
Updated•1 year ago
|
| Reporter | ||
Comment 21•1 year ago
|
||
Hello,
May I know when we are considering this for the advisory? If possible, can we consider the other two vulnerabilities of mine into the advisory by patching them?
Comment 22•1 year ago
|
||
I'm checking up on this. Andrew's out today but well sort this out tomorrow.
Comment 23•1 year ago
|
||
Comment 24•1 year ago
|
||
Backed out on request from aosmond: https://hg.mozilla.org/integration/autoland/rev/c501eb71481422165f7f7dddc50ce203bb160636
Comment 25•1 year ago
|
||
| Assignee | ||
Comment 26•1 year ago
|
||
Updated•1 year ago
|
| Assignee | ||
Updated•1 year ago
|
Comment 27•1 year ago
|
||
esr115 Uplift Approval Request
- User impact if declined: Sec issue
- Code covered by automated testing: yes
- Fix verified in Nightly: no
- Needs manual QE test: no
- Steps to reproduce for manual QE testing: N/A
- Risk associated with taking this patch: Low
- Explanation of risk level: Mostly boilerplate changes to solve unexpected use of nullptr and reused formerly stale pointers
- String changes made/needed: None
- Is Android affected?: yes
Comment 28•1 year ago
|
||
Comment 29•1 year ago
|
||
The patch landed in nightly and beta is affected.
:aosmond, is this bug important enough to require an uplift?
- If yes, please nominate the patch for beta approval.
- If no, please set
status-firefox127towontfix.
For more information, please visit BugBot documentation.
| Assignee | ||
Comment 30•1 year ago
|
||
Comment on attachment 9397281 [details]
Bug 1891319.
Beta/Release Uplift Approval Request
- User impact if declined: Sec issue
- Is this code covered by automated tests?: Yes
- Has the fix been verified in Nightly?: Yes
- Needs manual test from QE?: No
- If yes, steps to reproduce:
- List of other uplifts needed: None
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): Just makes us handle nullptr and stale pointer scenarios properly, the change is well contained and easily understood
- String changes made/needed:
- Is Android affected?: Yes
Comment 31•1 year ago
|
||
| uplift | ||
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Comment 32•1 year ago
|
||
| uplift | ||
Updated•1 year ago
|
Updated•1 year ago
|
Comment 33•1 year ago
|
||
| Reporter | ||
Comment 34•1 year ago
|
||
Hello Tom sir,
A quick change. The vulnerability can also be exploited through the network protocol and doesn't need to be a local storage protocol i.e. file://.
Also because of the exploit idea shared in the Comment 18 which were then ported as See also because the concept shared by Andrew to exploit this is almost fitting the way.
@Andrew sir, can you please update the title? Because we researchers shouldn't update the triage details.
Comment 35•1 year ago
|
||
| Reporter | ||
Comment 36•1 year ago
|
||
Thank you very much for quick update!
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
| Reporter | ||
Comment 37•1 year ago
|
||
Hello,
Was this vulnerability considered for a reward? :)
Comment 38•1 year ago
|
||
(In reply to Kirtikumar Anandrao Ramchandani from comment #37)
Was this vulnerability considered for a reward? :)
No, there was no bounty request on it. Is the above a request?
If this is a concern in the future I urge you either to file issues using the bug bounty form or to mail the bugzilla link to our security mail address as described on our Client Bug Bounty page
Comment 39•1 year ago
|
||
Updating title per comment 34
Updated•1 year ago
|
| Reporter | ||
Comment 40•1 year ago
|
||
Hello Daniel,
Please check your mail. Thanks!
| Reporter | ||
Comment 41•1 year ago
|
||
At the sec-high it includes: UXSS, cross-origin data leaks. Can we bump the severity as the exploit poc shared was demonstrating the SOP bypass of tainting?
Adding info which was shared in Comment 34 in more detail. An attacker has to use the Canvas API like getImageData to fetch the data (Just needs to be adjusted in the initial poc) where using an offscreen canvas within a web worker, you can handle image processing tasks in a separate thread. Finally, the attacker can load an image from another domain, draw it onto an offscreen canvas, manipulate it, and then use getImageData to read the pixel data. This can reveal confidential information in the image, such as QR codes, personal photos, etc. If we have to fetch something like video then frames can be done.
I don't know but maybe also side-channel attack can be possible where an attacker can measure the time it takes to draw a cross-origin image onto an offscreen canvas. By comparing the time it has taken to render for multiple images or different parts of the same image, the attacker can infer information about the size, complexity, or specific characteristics of the image.
Can be like:
function kcheckCanvas() {
const imageData = ctx.getImageData(0, 0, width, height);
}
Comment 42•1 year ago
|
||
Please see comment 15: if you can make it work as you claim please submit a POC showing so.
| Reporter | ||
Comment 43•1 year ago
|
||
Ok, I try :)
Updated•10 months ago
|
Description
•