Age | Commit message (Collapse) | Author |
|
On Windows, if an application is registered as an URL handler like this:
HKEY_CLASSES_ROOT
https
URL Protocol = ""
[...]
shell
open
command
(Default) = ".../qutebrowser.exe" "%1"
one would think that Windows takes care of making sure URLs can't inject
arguments by containing a quote. However, this is not the case, as
stated by the Microsoft docs:
https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa767914(v=vs.85)
Security Warning: Applications that handle URI schemes must consider how to
respond to malicious data. Because handler applications can receive data
from untrusted sources, the URI and other parameter values passed to the
application may contain malicious data that attempts to exploit the handling
application.
and
As noted above, the string that is passed to a pluggable protocol handler
might be broken across multiple parameters. Malicious parties could use
additional quote or backslash characters to pass additional command line
parameters. For this reason, pluggable protocol handlers should assume that
any parameters on the command line could come from malicious parties, and
carefully validate them. Applications that could initiate dangerous actions
based on external data must first confirm those actions with the user. In
addition, handling applications should be tested with URIs that are overly
long or contain unexpected (or undesirable) character sequences.
Indeed it's trivial to pass a command to qutebrowser this way - given how
trivial the exploit is to recreate given the information above, here's a PoC:
https:x" ":spawn calc
(or qutebrowserurl: instead of https: if qutebrowser isn't registered as a
default browser)
Some applications do escape the quote characters before calling
qutebrowser - but others, like Outlook Desktop or .url files, do not.
As a fix, we add an --untrusted-args flag and some early validation of the raw
sys.argv, before parsing any arguments or e.g. creating a QApplication (which
might already allow injecting Qt flags there).
We assume that there's no way for an attacker to inject flags *before* the %1
placeholder in the registry, and add --untrusted-args as the last argument of
the registry entry. This way, it'd still be possible for users to customize
their invocation flags without having to remove --untrusted-args.
After --untrusted-args, however, we have some rather strict checks:
- There should be zero or one arguments, but not two (or more)
- Any argument may not start with - (flag) or : (qutebrowser command)
We also add the --untrusted-args flag to the Linux .desktop file, though it
should not be needed there, as the specification there is sane:
https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables
Implementations must take care not to expand field codes into multiple
arguments unless explicitly instructed by this specification. This means
that name fields, filenames and other replacements that can contain spaces
must be passed as a single argument to the executable program after
expansion.
There is no comparable mechanism on macOS, which opens the application without
arguments and then sends an "open" event to it:
https://doc.qt.io/qt-5/qfileopenevent.html
This issue was introduced in qutebrowser v1.7.0 which started registering it as
URL handler: baee2888907b260881d5831c68500941937261a0 / #4086
This is by no means an issue isolated to qutebrowser. Many other projects have
had similar trouble with Windows' rather unexpected behavior:
Electron / Exodus Bitcoin wallet:
- http://web.archive.org/web/20190702112128/https://medium.com/0xcc/electrons-bug-shellexecute-to-blame-cacb433d0d62
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000006
- https://medium.com/hackernoon/exploiting-electron-rce-in-exodus-wallet-d9e6db13c374
IE/Firefox:
- https://bugzilla.mozilla.org/show_bug.cgi?id=384384
- https://bugzilla.mozilla.org/show_bug.cgi?id=1572838
Others:
- http://web.archive.org/web/20210930203632/https://www.vdoo.com/blog/exploiting-custom-protocol-handlers-in-windows
- https://parsiya.net/blog/2021-03-17-attack-surface-analysis-part-2-custom-protocol-handlers/
- etc. etc.
See CVE-2021-41146 / GHSA-vw27-fwjf-5qxm:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-41146
https://github.com/qutebrowser/qutebrowser/security/advisories/GHSA-vw27-fwjf-5qxm
Thanks to Ping Fan (Zetta) Ke of Valkyrie-X Security Research Group
(VXRL/@vxresearch) for finding and responsibly disclosing this issue.
(cherry picked from commit 8f46ba3f6dc7b18375f7aa63c48a1fe461190430)
|
|
|
|
|
|
- Move desktop-file-name before special arguments.
- Set action=store_true to not expect an argument for
temp-basedir-restarted (didn't lead to a bug as it's only passed via
--json-args).
|
|
Fixes #6091
|
|
See #6091
|
|
Needed to write tests.
|
|
|
|
Closes #6015
|
|
|
|
Fixes #5245
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The general consensus seems to be that the inspector is the first tab of the
devtools, and Chromium also calls them devtools everywhere.
Closes #5438
|
|
This essentially does two things:
1) Use a set for LogFilter
This means we don't support filters like "eggs.bacon" anymore (but we *do*
support loggers like that) - however, those were already disallowed by the
--logfilter argument validation anyways!
In return, we get probably slightly better performance (checking set membership
rather than iterating all filters) and more straightforward code.
2) Move parsing from various locations around the code to the LogFilter class.
|
|
|
|
Log levels can now be configured in config.py by setting
loggin.level.console (for stdout/stderr) and logging.level.ram (for
:messages).
This is of interest for users who would like password-manager
integration that uses `fake-key` to send sensitive strings to websites.
The default 'debug' ram logging would store various logs containing the
sensitive data.
Previously the loglevel was only configurable through CLI flags, and
those only affected the console loglevel. We felt a config value would
be nicer than just adding another flag for RAM loglevel, requiring you
to create an alias for qutebrowser and ensure _that_ alias gets used
anywhere qutebrowser might be invoked.
Logging is initialized before the config is loaded, so configuration-set
loglevels have to be loaded in a second, later stage. However, this
stage will only set the console loglevel if it wasn't set on the CLI, as
a CLI flag feels like a more explicit action that should override a
config.
Fixes #5286.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config-cli-option
|
|
jay/scroll-perf
|
|
|
|
Qt 5.12.3 disabled renderer process stack traces (by setting OFFICIAL_BUILD).
Comments in Chromium's source say that printing the stack trace has "security
implications", though it's unclear what those implications are precisely.
On older Qt versions, pass --disable-in-process-stack-traces for the same
effect. In newer Qt versions, pass --enable-in-process-stack-traces when
"--debug-flag stack" is given to re-enable them.
|
|
jay/private-window
|
|
Otherwise, log.py tries to import QtCore, but at this early point (before
running earlyinit) we shouldn't rely on PyQt being available.
This restores the graphical error message shown when PyQt is missing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Sometimes I want to see all the logs _except_ for the sql stuff and
"marked cookies as dirty". with this you should be able to pass
`--logfilter \!sql,save`.
|
|
See #3010
|
|
|
|
|
|
|
|
|
|
And lots and lots of whitespace changes.
|