ArticleView: expose only minimal API to JavaScript

https://doc.qt.io/archives/qt-5.5/qtwebkit-bridge.html#internet-security
Qt WebKit Bridge documentation recommends:
  When exposing native objects to an open web environment, it is
  important to understand the security implications. Think whether the
  exposed object enables the web environment access things that
  shouldn't be open, and whether the web content loaded by that web page
  comes from a trusted source.

The author of Qt WebChannel has said the following in a talk that
introduced this Qt module (WebKit Bridge replacement for Qt WebEngine):
  My suggestion here is to write dedicated QObjects with a slim, minimal
  API that only have the signals and methods that you deem safe to be
  used from the outside.
- see a comment under https://redirect.invidious.io/watch?v=KnvnTi6XafA
This commit is contained in:
Igor Kushnir 2022-06-02 10:51:30 +03:00
parent aa33b8bebc
commit 99982a1c11
2 changed files with 25 additions and 1 deletions

View file

@ -50,6 +50,24 @@
using std::map; using std::map;
using std::list; using std::list;
/// This class exposes only slim, minimal API to JavaScript clients in order to
/// reduce attack surface available to potentionally malicious external scripts.
class ArticleViewJsProxy: public QObject
{
Q_OBJECT
public:
/// Note: view becomes the parent of this proxy object.
explicit ArticleViewJsProxy( ArticleView & view ):
QObject( &view ), articleView( view )
{}
Q_INVOKABLE void onJsActiveArticleChanged( QString const & id )
{ articleView.onJsActiveArticleChanged( id ); }
private:
ArticleView & articleView;
};
/// AccentMarkHandler class /// AccentMarkHandler class
/// ///
/// Remove accent marks from text /// Remove accent marks from text
@ -222,6 +240,7 @@ ArticleView::ArticleView( QWidget * parent, ArticleNetworkAccessManager & nm,
groups( groups_ ), groups( groups_ ),
popupView( popupView_ ), popupView( popupView_ ),
cfg( cfg_ ), cfg( cfg_ ),
jsProxy( new ArticleViewJsProxy( *this ) ),
pasteAction( this ), pasteAction( this ),
articleUpAction( this ), articleUpAction( this ),
articleDownAction( this ), articleDownAction( this ),
@ -1140,7 +1159,7 @@ void ArticleView::linkHovered ( const QString & link, const QString & , const QS
void ArticleView::attachToJavaScript() void ArticleView::attachToJavaScript()
{ {
ui.definition->page()->mainFrame()->addToJavaScriptWindowObject( QString( "articleview" ), this ); ui.definition->page()->mainFrame()->addToJavaScriptWindowObject( "articleview", jsProxy );
} }
void ArticleView::linkClicked( QUrl const & url_ ) void ArticleView::linkClicked( QUrl const & url_ )
@ -3090,3 +3109,5 @@ void ResourceToSaveHandler::downloadFinished()
deleteLater(); deleteLater();
} }
} }
#include "articleview.moc"

View file

@ -15,6 +15,7 @@
#include "groupcombobox.hh" #include "groupcombobox.hh"
#include "ui_articleview.h" #include "ui_articleview.h"
class ArticleViewJsProxy;
class ResourceToSaveHandler; class ResourceToSaveHandler;
/// A widget with the web view tailored to view and handle articles -- it /// A widget with the web view tailored to view and handle articles -- it
@ -32,6 +33,8 @@ class ArticleView: public QFrame
Ui::ArticleView ui; Ui::ArticleView ui;
ArticleViewJsProxy * const jsProxy;
QAction pasteAction, articleUpAction, articleDownAction, QAction pasteAction, articleUpAction, articleDownAction,
goBackAction, goForwardAction, selectCurrentArticleAction, goBackAction, goForwardAction, selectCurrentArticleAction,
copyAsTextAction, inspectAction; copyAsTextAction, inspectAction;