Client Certificate prompt no longer pops up for extension background script
Categories
(Core :: Security: PSM, defect)
Tracking
()
Tracking | Status | |
---|---|---|
firefox-esr115 | --- | unaffected |
firefox124 | --- | wontfix |
firefox125 | --- | wontfix |
firefox126 | --- | verified |
firefox127 | --- | verified |
People
(Reporter: yc, Assigned: kershaw)
References
(Regression)
Details
(Keywords: regression)
Attachments
(3 files)
Steps to reproduce:
- Have self-hosted web server configured with client certificate authentication.
- Import client certificate into Firefox.
- Load below extension from "about:debugging".
background.html
<html>
<head>
<meta charset="UTF-8" />
</head>
<body></body>
<script src="test.js"></script>
</html>
manifest.json
{
"manifest_version": 2,
"name": "Client Cert test",
"version": "1.0",
"description": "Test that client cert works properly in extension.",
"background": {
"page": "background.html",
"persistent": true
},
"content_scripts": [
{
"matches": ["https://example.com/*"],
"js": ["test.js"]
}
],
"permissions": [
"<all_urls>"
]
}
test.js
document.body.style.border = "5px solid red";
async function test() {
await fetch("https://<redacted-host-which-has-client-auth>");
const x = await fetch("https://<redacted-host-which-has-client-auth>", { credentials: 'include' });
console.log(x);
}
test();
Actual results:
There was no "User Identification Request" prompt, with "This site has requested that you identify yourself with a certificate". The fetch requests fails with 403.
Expected results:
There is a User Identification Request prompt, where user can confirm certificate.
Workaround: Downgrade to old Firefox, perform login, upgrade Firefox. Do not clear Site Settings.
Comment 1•1 month ago
|
||
The Bugbug bot thinks this bug should belong to the 'WebExtensions::Untriaged' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.
Comment 2•1 month ago
|
||
Hello,
Would you be able to provide the steps required to self-host a web server with client certificate authentication as well as the actual client certificate you used?
Thank you !
I've attached a script which can reproduce the issue locally.
Steps:
- Run script (rootless). This should generate certificates and start up nginx.
- In Firefox Certificate Manager, Add Security Exception, Location: https://127.0.0.1:8443, Permanently store, Confirm.
(In a real setup, this is not necessary since the root CA is in the trust store) - In Firefox Certificate Manager, Your Certificates, Import client.pfx, Type in password "1888751".
- Modify
fetch
URL above tohttps://127.0.0.1:8443
. - In about:debugging, import extension.
#!/bin/bash
rm -f nginx.conf *.crt *.key *.csr *.srl *.log
cat > nginx.conf << EOL
worker_processes 1;
daemon off;
error_log stderr;
pid nginx.pid;
events {
worker_connections 1024;
}
http {
server {
access_log access.log;
listen 8443 ssl default_server;
listen [::]:8443 ssl default_server;
ssl_certificate ./server.crt;
ssl_certificate_key ./server.key;
server_name _;
ssl_client_certificate ca.crt;
ssl_verify_client optional;
location / {
if (\$ssl_client_verify != SUCCESS) { return 403; }
add_header Content-Type text/plain;
return 200 'hello\n';
}
}
}
EOL
# CA
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 30 -out ca.crt -subj '/CN=1888751/O=1888751'
# Server
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr -subj '/CN=127.0.0.1/O=1888751'
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 30 -sha256
# Client
openssl genrsa -out client.key 4096
openssl req -new -key client.key -out client.csr -subj '/CN=127.0.0.1/O=188751'
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 30 -sha256
openssl pkcs12 -export -out client.pfx -inkey client.key -in client.crt -certfile ca.crt -password pass:1888751
/usr/sbin/nginx -c nginx.conf -p $PWD &
nginx_pid=$!
echo "--- No client cert ---"
curl --cacert ca.crt https://127.0.0.1:8443
echo "--- With client cert ---"
curl --cacert ca.crt --key client.key --cert client.crt https://127.0.0.1:8443
wait $nginx_pid
Comment 4•1 month ago
|
||
Hello and thank you for the additional info !
I reproduced the issue on the latest Nightly (126.0a1/20240401213149), Beta (125.0b7/20240401091600) and Release (124.0.1/20240321230221) under Ubuntu 22.04 LTS.
After loading the extension from Comment 0, there is no prompt and checking the browser toolbox network tab also shows that the fetch requests fail with 403.
Updated•24 days ago
|
Comment 5•23 days ago
|
||
DEBUG : Found commit message:
Bug 1401466 - make the client auth certificate selection dialog tab modal r=jschanck,necko-reviewers,bolsson,kershaw,valentin
Differential Revision: https://phabricator.services.mozilla.com/D183775
Corresponding pushlog: https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=34dcd8f28e9a642600425b3383df225859ea91cd&tochange=9d1733984f18d8faafeeb405e1519bd8f2f239d0
Comment 6•23 days ago
|
||
Set release status flags based on info from the regressing bug 1401466
Updated•21 days ago
|
Comment 8•21 days ago
|
||
Hey Kershaw, can you please help with confirming if this is intended behavior after bug 1401466 (Dana seems OoO, but you reviewed the patch in question -- if you're not the best person to answer, please forward to someone who might).
The commit message makes it sound like there should be a fallback to a last used window, but I couldn't figure out if that's still in the landed version of the patch.
Assignee | ||
Comment 9•21 days ago
|
||
(In reply to Tomislav Jovanovic :zombie from comment #8)
Hey Kershaw, can you please help with confirming if this is intended behavior after bug 1401466 (Dana seems OoO, but you reviewed the patch in question -- if you're not the best person to answer, please forward to someone who might).
The commit message makes it sound like there should be a fallback to a last used window, but I couldn't figure out if that's still in the landed version of the patch.
It's not about fallback to the last used window, because in this case, there is a loadContext
here.
The problem seems to be at this line, since I got the error below:
JavaScript error: resource://gre/modules/psm/ClientAuthDialogService.sys.mjs, line 58: TypeError: can't access property "open", browserWindow.gDialogBox is undefined
I am not sure why gDialogBox
is undefined, but looking at other places where gDialogBox
is used, it can be null.
When gDialogBox
is null, using Services.wm.getMostRecentWindow("").gDialogBox
like the code below seems to work.
if (browserWindow) {
let dialogBox = browserWindow.gDialogBox
? browserWindow.gDialogBox
: Services.wm.getMostRecentWindow("").gDialogBox;
dialogBox
.open(clientAuthAskURI, { hostname, certArray, retVals })
.then(() => {
callback.certificateChosen(retVals.cert, retVals.rememberDecision);
});
return;
}
However, I am not sure if this is a correct fix, since I don't know front end code really well.
Gijs, do you know a better way to fix this?
Thanks.
Comment 10•21 days ago
|
||
The variable name is browserWindow
, but is this actually a browser window in the case where this fails?
I expect not - comment 0 suggests the fetch
call is happening in an extension background script, which I expect isn't associated to a given browser window at all.
The code at https://searchfox.org/mozilla-central/rev/98a54cbdc5964e778af0e6b325f9e7831f00c05b/security/manager/ssl/ClientAuthDialogService.sys.mjs#58 is kind of surprising to me. It looks like we ship this as part of toolkit/gecko, so presumably it also ships on Android (and potentially Thunderbird etc.). But it assumes a lot of things about where connections might come from (ie browser windows).
The fix described in comment #9 will fall back to trying to create a window-modal prompt in "some other window", which might also not be a browser window (either because we're not running in desktop Firefox or because it so happens that the user last selected a different type of window, like the library window or a separate devtools window, the about dialog, ...).
The right fix would probably look more like:
// Otherwise, attempt to open a window-modal dialog on the window that at
// least has the tab the load is occurring in.
let browserWindow = loadContext?.topFrameElement?.ownerGlobal;
// Failing that, open a window-modal dialog on the most recent "main" window.
if (!browserWindow?.gDialogBox) {
// XXXgijs not sure how 'good' this fallback is. This would mean that instead
// of opening a separate, OS-level modal window for the dialog on top of a
// window from which the client cert originated, we open it on a "main"
// window. This could be disorientating if the request is from some non-main
// window, and the prompt shows up elsewhere.
// But this fallback was already here...
browserWindow = Services.wm.getMostRecentBrowserWindow();
}
if (browserWindow?.gDialogBox) {
browserWindow.gDialogBox
.open(clientAuthAskURI, { hostname, certArray, retVals })
.then(() => {
callback.certificateChosen(retVals.cert, retVals.rememberDecision);
});
return;
}
// If we get here, we couldn't find a window with a `gDialogBox` property.
// Fall back to opening the window using the window watcher as a separate
// modal on top of whatever window we can find.
let mostRecentWindow = Services.wm.getMostRecentWindow("");
let response = Services.ww.openWindow(mostRecentWindow, clientAuthAskURI, {hostname, certArray, retVals});
callback.certificateChosen(retVals.cert, retVals.rememberDecision);
(completely untested, probably doesn't work, please check the actual docs for openWindow
and/or other callsites)
And then on top of that we probably need a bug to do something else on android, if we haven't already?
Assignee | ||
Comment 11•17 days ago
|
||
Thanks for the sample code, Gijs. I'll try to write a patch based on it.
Note that I am not sure how to make the case that there is no gDialogBox
work, because of the error caused by the line below.
let response = Services.ww.openWindow(mostRecentWindow, clientAuthAskURI, {hostname, certArray, retVals});
Assignee | ||
Comment 12•17 days ago
|
||
Updated•17 days ago
|
Comment 13•16 days ago
|
||
Set release status flags based on info from the regressing bug 1401466
Comment 14•16 days ago
|
||
:willdurand tagging as Triage Owner. Could you set the severity on this?
This has a patch, wondering if we should keep an eye for uplift or it should ride the train with Fx127
Comment 15•14 days ago
|
||
Pushed by kjang@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/d35fa1190f2a Use getMostRecentBrowserWindow when where is no gDialogBox, r=Gijs
Updated•14 days ago
|
Comment 16•14 days ago
|
||
bugherder |
Comment 17•13 days ago
|
||
Verified as Fixed. Tested on the latest Nightly (127.0a1/20240418214121) under Ubuntu 22.04 LTS.
After loading the extension from Comment 0, the "User Identification Request" prompt is shown, confirming the fix.
Comment 18•13 days ago
|
||
The patch landed in nightly and beta is affected.
:kershaw, is this bug important enough to require an uplift?
- If yes, please nominate the patch for beta approval.
- If no, please set
status-firefox126
towontfix
.
For more information, please visit BugBot documentation.
Assignee | ||
Comment 19•13 days ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D207416
Updated•13 days ago
|
Comment 20•13 days ago
|
||
beta Uplift Approval Request
- User impact if declined: Client certificate dialog could not show when the HTTP request is from an extension
- Code covered by automated testing: yes
- Fix verified in Nightly: yes
- 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: Shoule be low risk, since the patch is straightforward.
- String changes made/needed: N/A
- Is Android affected?: yes
Assignee | ||
Updated•13 days ago
|
Updated•13 days ago
|
Updated•12 days ago
|
Updated•12 days ago
|
Comment 21•12 days ago
|
||
uplift |
https://hg.mozilla.org/releases/mozilla-beta/rev/efd1006aeaaf
Comment 22•8 days ago
|
||
Verified as Fixed. Tested on the latest Beta (126.0b4/20240422091940) under Ubuntu 22.04 LTS.
After loading the extension from Comment 0, the "User Identification Request" prompt is shown, confirming the fix.
Description
•