[Notifications] Manually remove remote images
AbandonedPublic

Authored by davidedmundson on Jul 13 2017, 9:55 AM.

Details

Reviewers
fvogt
broulik
Group Reviewers
Plasma
Summary

We allow HTML in Notifications and QtQuick Text will even load remote images which poses a privacy threat.
The network access manager factory we install is ineffective as Plasma uses a shared engine nowadays and whenever a new QmlObject shared engine is created, its setupBindings will re-install the KIO access factory.

Test Plan

5.8 branch on Fabian's request as this is a security issue

Can no longer cause network requests by sending a notification with <img src="http://..."> or <span style="background: url(http://...)">.

(Btw I noticed that setupBindings is called >100 times on Plasma startup, setting up the very same QML engine over and over again, including creating a KIO NAM factory, KLocalizedContext and KIcon image provider)

Diff Detail

Repository
R120 Plasma Workspace
Lint
Lint Skipped
Unit
Unit Tests Skipped
broulik created this revision.Jul 13 2017, 9:55 AM
Restricted Application added a project: Plasma. · View Herald TranscriptJul 13 2017, 9:55 AM
Restricted Application added a subscriber: plasma-devel. · View Herald Transcript
broulik updated this revision to Diff 16691.Jul 14 2017, 8:27 AM

Use while loop to avoid off-by-one error when starting over

fvogt requested changes to this revision.Jul 14 2017, 8:40 AM
fvogt added inline comments.
applets/notifications/plugin/textsanitizer.cpp
45 ↗(On Diff #16691)

(Already noted on IRC)

This doesn't do what it's intended to do, findBlockByNumber is needed here.
Otherwise it only goes through the first few blocks and leaves the rest as-is:

notify-send "a" "<span>a</span><div>a</div><div>b</div><img src='http://localhost'/>"

results in

file:///usr/share/plasma/plasmoids/org.kde.plasma.notifications/contents/ui/NotificationItem.qml:268:17: QML TextEdit: localhost: Connection refused

This revision now requires changes to proceed.Jul 14 2017, 8:40 AM
broulik updated this revision to Diff 16692.Jul 14 2017, 9:09 AM
broulik edited edge metadata.
  • Iterate all blocks

Addressing the text first:

The network access manager factory we install is ineffective as Plasma uses a shared engine nowadays and whenever a new QmlObject shared engine is created, its setupBindings will re-install the KIO access factory.

There used to be a .desktop flag for that..

(Btw I noticed that setupBindings is called >100 times on Plasma startup, setting up the very same QML engine over and over again, including creating a KIO NAM factory, KLocalizedContext and KIcon image provider)

calling setupBindings() is needed as we install the ki18n on the context (which is different), but you're right that the stuff with the engine could indeed be done once.

hypothetically (and this would still require a Qt change) if we could override loadResource would that be enough for doing what this is doing?

applets/notifications/plugin/textsanitizer.cpp
41

just make it on the stack?

59

format might not be valid here, does that cause a problem?

60

probably better to do do:

!backgroundUrl.isEmpty() && !isLocalFile..

QTextFormat was still doing some processing at least.

86

(untested)

Make a QTextCursor on qqdoc->textDocument() and then you can insertFragment.
This way you can do it with only shallow copies, and all in a single pass over the original document.

Removing images becomes a lot easier then, as you just skip that fragment rather than trying to remove text.

aacid added a subscriber: aacid.Jan 27 2018, 11:07 PM

Any reason we're not doing the filtering at the dataengine level?

To be honest, having a look at https://developer.gnome.org/notification-spec/#markup we should just filter out everything other than b i u a and img with local src

What do you think?

should just filter out everything other than b i u a and img with local src

Sure, but how would you achieve this? Regular expressions aren't suitable for HTML. It's not like I went this overly complicated way for no reason.

aacid added a comment.EditedJan 28 2018, 12:49 AM

should just filter out everything other than b i u a and img with local src

Sure, but how would you achieve this? Regular expressions aren't suitable for HTML. It's not like I went this overly complicated way for no reason.

By doing something similar to what https://cgit.kde.org/knotifications.git/tree/src/notifybypopup.cpp#n790 does?

This would fail with "invalid but webbrowser-parseable" html, but i guess we don't really care about it either, no?

This would fail with "invalid but webbrowser-parseable" html, but i guess we don't really care about it either, no?

That wouldn't solve anything as <img src="whatever" > without </img> would fail the XML remover but still end up getting loaded.
You could need to signal that it wasn't strippable, and the QtQuick item could load in plain text, but then the patch is getting more complex.


My comment looks surprisngly sensible, I'll follow that up tomorrow eve and see if it works. I'll run the test fvgot has in the earlier comment.


Any reason we're not doing the filtering at the dataengine level?

It's accessing the text document of the TextEdit; which avoids a double text document parse.
Though for the size of a notification at the frequency we get them, that's not a huge problem.

I think QXmlStreamReader may be the way to go, I wasn't aware on how strict the spec is wrt HTML support.

David, an <img> opening tag is still valid XHTML, you might receive a document ended prematurely error at the end since there won't be a closing tag but definitely worth a shot filtering out any tags other than <b> etc and stripping all attributes other than src with local URL, especially the style attribute.

Also, if we did the filtering on dataengine side we could easily backport that to 5.8 since it hardly changed in the meantime whereas the applet underwent significant modifications.

davidedmundson commandeered this revision.Jan 29 2018, 12:22 AM
davidedmundson added a reviewer: broulik.

FYI, started making changes (as I know Kai is away). Will be done by tomorrow eve with autotest suite.