Commit Graph

20108 Commits

Author SHA1 Message Date
Florian Bruhin 897965f9dd Update docs
(cherry picked from commit 41b05f9548)
2021-10-21 16:47:02 +02:00
Florian Bruhin 410f26265c CVE-2021-41146: Add --untrusted-args to avoid argument injection
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: baee288890 / #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 8f46ba3f6d)

# Conflicts:
#	qutebrowser/qutebrowser.py
#	tests/unit/test_qutebrowser.py
2021-10-21 16:13:29 +02:00
Florian Bruhin a99f61071a Release v1.13.1 2020-07-17 17:00:38 +02:00
Florian Bruhin cfb4d952dd Update changelog from master 2020-07-17 17:00:22 +02:00
Florian Bruhin 4e6e1efd23 ipc: Handle failing getpass.getuser() on Windows
(cherry picked from commit a03348f951)
2020-07-16 14:36:59 +02:00
Florian Bruhin 2b72f43d9e Load the correct URL in the Qt 5.15 session workaround
If visiting an URL and then later using :back, we accidentally opened the last
URL in the back/forward history rather than the current one.

See #5359
Fixes #5566

(cherry picked from commit 8f073ee095)
2020-07-12 22:07:29 +02:00
Florian Bruhin 7c03f08e08 Move Qt 5.15 session workaround to its own function
See #5359

(cherry picked from commit 0c43cbdede)
2020-07-12 22:07:27 +02:00
Florian Bruhin 3d6125cf15 Shut down tabs properly when a window is closed
(cherry picked from commit d0ae9ba232)
2020-07-12 22:07:22 +02:00
Florian Bruhin 4675e05cae Avoid :help being called with deprecated commands
(cherry picked from commit 5dc0e6528b)
2020-07-12 13:49:43 +02:00
Wayne Cheng 302e55a48f qute-lastpass merge-candidate bugfix from @user202729
(cherry picked from commit 4f83bf6559)
2020-07-10 16:21:59 +02:00
Florian Bruhin 106a3a202e log: Set line number to -1 if it's None for Qt messages
If lineno is set to None in the LogRecord, pytest's logging formatting fails:

    tests/unit/utils/test_log.py:418: in test_empty_message
        log.qt_message_handler(QtCore.QtDebugMsg, self.Context(), "")
    qutebrowser/utils/log.py:508: in qt_message_handler
        qt.handle(record)
    /usr/lib/python3.8/logging/__init__.py:1587: in handle
        self.callHandlers(record)
    /usr/lib/python3.8/logging/__init__.py:1649: in callHandlers
        hdlr.handle(record)
    /usr/lib/python3.8/logging/__init__.py:950: in handle
        self.emit(record)
    ../../pytest/src/_pytest/logging.py:326: in emit
        super().emit(record)
    /usr/lib/python3.8/logging/__init__.py:1089: in emit
        self.handleError(record)
    /usr/lib/python3.8/logging/__init__.py:1081: in emit
        msg = self.format(record)
    /usr/lib/python3.8/logging/__init__.py:925: in format
        return fmt.format(record)
    ../../pytest/src/_pytest/logging.py:89: in format
        return super().format(record)
    /usr/lib/python3.8/logging/__init__.py:667: in format
        s = self.formatMessage(record)
    /usr/lib/python3.8/logging/__init__.py:636: in formatMessage
        return self._style.format(record)
    ../../pytest/src/_pytest/logging.py:185: in format
        return self._fmt % record.__dict__
    E   TypeError: %d format: a number is required, not NoneType

According to typeshed, lineno should never be None:
028f0d5293/stdlib/2and3/logging/__init__.pyi (L386)

Thus, this is our fault, not pytest's. However, before pytest 6.0.0, pytest did
not surface logging errors:

https://github.com/pytest-dev/pytest/pull/7231
b13fcb23d7

Thus, we never noticed something was going wrong here.

(cherry picked from commit e206d346ce)

Make mypy happy

It doesn't know about QMessageLogContext.lineno being Optional[int] rather than
int.

(cherry picked from commit 4136c847fd)
2020-07-10 16:21:55 +02:00
Florian Bruhin 58765f2b8d Clarify how per-domain settings work for content.cookies.accept
(cherry picked from commit 6c9b088834)
2020-07-10 16:21:55 +02:00
Florian Bruhin 63c2d1bebb Improve docstring for _init_pulseaudio()
(cherry picked from commit b77891fce7)
2020-07-10 16:21:55 +02:00
Florian Bruhin 581bbfe9cc Add PYINSTALLER_DEBUG
(cherry picked from commit ad645bba52)

Fix PYINSTALLER_DEBUG

(cherry picked from commit f50faee0ea)
2020-07-10 16:21:50 +02:00
Florian Bruhin e97aa69153 Set Pulseaudio properties
See #3832

(cherry picked from commit 7d38816310)
2020-07-10 16:21:50 +02:00
Florian Bruhin 4b7e032697 inspector: Set only_if_normal=True for modeman.enter when clicked
So we don't e.g. switch from passthrough to insert mode when the inspector is
clicked.

(cherry picked from commit 64d3c04d4d)
2020-07-10 16:21:50 +02:00
Florian Bruhin 7335d3efb0 configfiles: Handle invalid structure during migrations
(cherry picked from commit 8d05f0282a)
2020-07-10 16:21:50 +02:00
Florian Bruhin c211d44c0d Document how content.proxy can have a delay
Closes #5557

(cherry picked from commit 7a7410d906)
2020-07-10 16:21:50 +02:00
Florian Bruhin 05ba5476b9 Suppress context menu properly with rocker gestures
For some reason, the event filter stopped inhibiting the context menu with Qt
5.9 (or possibly 5.8).

(cherry picked from commit 0ed215d81f)

Remove unnecessary return

(cherry picked from commit 8159206576)
2020-07-10 16:21:42 +02:00
Florian Bruhin 8ade7d22f2 Use Pygments from virtualenv's path in asciidoc2html
This allows running mkvenv.py without having Pygments installed system-wide.
Prepending to the PATH (rather than appending) so that the virtualenv's one is
always used, so the system-wide one can be older or broken.

(cherry picked from commit 362d9d917b)
2020-07-10 16:17:04 +02:00
Florian Bruhin a4e40d97dc Disable shared workers wtih Qt 5.14
See https://bugreports.qt.io/browse/QTBUG-82105
Fixes #5279

(cherry picked from commit 27c6573508)
2020-06-29 10:42:02 +02:00
Florian Bruhin 3c2a543425 Fix duplicate import
(cherry picked from commit 7c4a1b03f5)
2020-06-26 11:17:39 +02:00
Florian Bruhin 80a57bc5ff manifest: Prune .mypy_cache
(cherry picked from commit cb15192cd6)
2020-06-26 08:56:18 +02:00
Florian Bruhin 7aa3304dad asciidoc2html: Resolve path for sys.path
For some reason, __file__ was "scripts/dev/../asciidoc2html.py", causing
.parents[1] to point to "scripts/dev/" instead of "scripts/".

See #5534

(cherry picked from commit eed0373feb)
2020-06-26 08:45:40 +02:00
Florian Bruhin 74ba8f3dc6 Release v1.13.0 2020-06-26 08:31:20 +02:00
Florian Bruhin c37093ed25 Update version in session warning 2020-06-25 18:05:37 +02:00
Florian Bruhin 66e19b1e0c Edit changelog 2020-06-25 18:05:16 +02:00
Florian Bruhin 0e78f179ab Update user agent completions 2020-06-25 17:05:53 +02:00
Florian Bruhin 156738195e Change permission workaround logger to debug
Now that we know how this happens (notification permissions in incognito mode),
we don't need to log a warning here.
2020-06-25 16:02:36 +02:00
Florian Bruhin 713592e851 Fix FAQ formatting 2020-06-25 14:23:07 +02:00
Florian Bruhin cb383c6f9f tests: Stabilize test_open_with_ascii_locale
The loaded page caused a 404, but we didn't wait for the new error logging
message. Most of the time that went well because we quit before it could be
logged, but not always.

See https://github.com/qutebrowser/qutebrowser/issues/5390#issuecomment-629268747
2020-06-25 13:41:38 +02:00
Florian Bruhin 76e8debbc0 ci: Switch from TRAVIS to CI env vars 2020-06-24 19:36:30 +02:00
Florian Bruhin a0f078da38 ci: Switch to qutebrowser/ci dockerfiles 2020-06-24 19:33:06 +02:00
Florian Bruhin 419f25bbee Update PyPI classifiers 2020-06-24 17:49:14 +02:00
Florian Bruhin 0e2db8eadc Add "tox -e mypy-diff"
Not done by default with "tox -e mypy" because it disables mypy's caching,
causing its runtime to go from <1s to ~15s:
https://github.com/python/mypy/issues/9041

See #1456
2020-06-24 15:01:16 +02:00
Florian Bruhin a04e7fe0df mypy requirements: Add lxml 2020-06-24 14:00:58 +02:00
Florian Bruhin 898535fbf8 Re-enable "Running :spawn with invalid quoting"
Let's assume this doesn't segfault anymore nowadays and let's see what happens.

Closes #1614
2020-06-24 11:37:20 +02:00
Florian Bruhin 4b9ddfb85b tests: Simplify some open() calls 2020-06-24 10:26:46 +02:00
Florian Bruhin 82203682e7 Merge remote-tracking branch 'origin/pr/5534' 2020-06-24 10:18:20 +02:00
Florian Bruhin 6c63b58762 tests: Fix flakyness in editor bdd tests
There likely was a race condition between JS processing the input and us
clicking the button there. Log the text async from JS via oninput= to avoid
having to click a button.

See https://github.com/qutebrowser/qutebrowser/issues/5390#issuecomment-625179233
2020-06-24 10:11:56 +02:00
Julin S 6cbf7e3976 redo old edit 2020-06-24 11:29:27 +05:30
Florian Bruhin 3a3f7786ad Revert "Remove Qt 5.8 workarounds for _remove_tab"
After 86d7943203, this now also re-adds the
workaround for QTBUG-58982 (#2290) because it is apparently still needed with
Qt 5.7...

This reverts commit 87d7dd9342.
2020-06-23 20:04:20 +02:00
Florian Bruhin 0518571f91 tests: Set splitter handle width for InspectorSplitter tests
How the handle width of 5 is distributed on macOS seems like totally random.
Instead of trying to get our calculations to work, just force the handle width
to an even number.
2020-06-23 18:33:47 +02:00
Florian Bruhin adbaf092a2 Delete widget in WrapperLayout.unwrap()
This was removed in f5f3bf63b5 but is still
needed so that the underlying QWebEngineView is actually deleted with Qt <
5.12. Otherwise, test_spawning_an_editor_and_closing_the_tab in
test_editor_bdd.py would fail because the element doesn't actually vanish.
2020-06-23 18:21:51 +02:00
Florian Bruhin 523fcfdc17 Use :devtools in inspector test 2020-06-23 17:58:00 +02:00
Florian Bruhin 1ebf9a8017 Fix handling of odd splitter size in InspectorSplitter tests
Turns out 7a6e4821a1 was the wrong way around!
2020-06-23 17:30:50 +02:00
Florian Bruhin 86d7943203 Re-add segfault workarounds
Some tests (e.g. in test_invocations.py) still seem to segfault without this.
This partially reverts 87d7dd9342.

See #2261
2020-06-23 17:29:44 +02:00
Florian Bruhin 1adb46420e Revert "Remove now unneeded WrapperLayout.unwrap"
This reverts commit 370bd12a15.

Turns one of out the workarounds removed in
87d7dd9342 is still needed until Qt 5.12...
2020-06-23 17:25:22 +02:00
Florian Bruhin 10ce807e1a Fix test_version
Needs re.MULTILINE because of the qutebrowser ASCII art logo...
2020-06-23 16:19:54 +02:00
Florian Bruhin e1c776ad90 Update docs 2020-06-23 14:55:56 +02:00