From ecbe1d942e41a29a8d0bffdb328643e4c2a278b1 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Tue, 8 Dec 2009 12:25:54 +0100 Subject: xss attach prevention. I have to say, BRUTE prevention :) Hope this works. Also some fixes in Urlbar class to ensure that a KUrl is a KUrl and a QString is a QString. Removed the annoying "restore url on focus out" feature. No other browsers have it and I really cannot understand gain --- src/application.cpp | 80 ++++++++++++++++----------------------------------- src/application.h | 6 ++-- src/urlbar/urlbar.cpp | 36 +++++++++++------------ src/urlbar/urlbar.h | 1 - src/webpage.cpp | 9 +++--- src/webview.cpp | 2 +- 6 files changed, 49 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/application.cpp b/src/application.cpp index 3a0ce638..246d6aa5 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -52,6 +52,7 @@ #include #include #include +#include // Qt Includes #include @@ -265,71 +266,26 @@ KIcon Application::icon(const KUrl &url) } -KUrl Application::guessUrlFromString(const QString &string) -{ - QString urlStr = string.trimmed(); - QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*")); - - // Might be a file. - if (QFile::exists(urlStr)) - { - QFileInfo info(urlStr); - return KUrl::fromPath(info.absoluteFilePath()); - } - - // Check if it looks like a qualified URL. Try parsing it and see. - if (test.exactMatch(urlStr)) - { - KUrl url(urlStr); - - if (url.isValid()) - { - return url; - } - } - else // Might be a shorturl - try to detect the schema. - { - int dotIndex = urlStr.indexOf(QLatin1Char(':')); - - if (dotIndex != -1) - { - QString prefix = urlStr.left(dotIndex).toLower(); - QString schema = (prefix == QLatin1String("ftp")) ? prefix : QLatin1String("http"); - QUrl qurl(schema + QLatin1String("://") + urlStr, QUrl::TolerantMode); - KUrl url(qurl); - - if (url.isValid()) - { - return url; - } - } - } - - // Fall back to QUrl's own tolerant parser. - KUrl url = KUrl(urlStr); - - return url; -} - - void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type) { if (url.isEmpty()) return; - if ( !url.isValid() ) + KUrl loadingUrl = xssSanitization(url); + + if ( !loadingUrl.isValid() ) { - KMessageBox::error(0, i18n("Malformed URL:\n%1", url.url())); + KMessageBox::error(0, i18n("Malformed URL:\n%1", loadingUrl.url(KUrl::RemoveTrailingSlash))); return; } // loading home pages - if (mainWindow()->newTabPage(url)) + if (mainWindow()->newTabPage(loadingUrl)) return; - if (url.scheme() == QLatin1String("mailto")) + if (loadingUrl.scheme() == QLatin1String("mailto")) { - KToolInvocation::invokeMailer(url); + KToolInvocation::invokeMailer(loadingUrl); return; } @@ -365,8 +321,6 @@ void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type) // - web shortcuts with space separator // - relative urls // - ... - KUrl loadingUrl(url); - if (loadingUrl.isRelative()) { QString fn = loadingUrl.url(KUrl::RemoveTrailingSlash); @@ -408,7 +362,7 @@ void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type) void Application::loadUrl(const QString& urlString, const Rekonq::OpenType& type) { - return loadUrl( guessUrlFromString(urlString), type ); + return loadUrl( QUrl::fromUserInput(urlString), type ); } @@ -445,3 +399,19 @@ AdBlockManager *Application::adblockManager() } return s_adblockManager; } + + +KUrl Application::xssSanitization(const KUrl &url) +{ + QString urlString = url.url(); + + QList l; // TODO: learn regular expression + l << '\'' << '\"' << '<' << '>'; + foreach(const QChar &c, l) + { + QStringList list = urlString.split(c); + urlString = list.at(0); + } + return KUrl(urlString); +} + \ No newline at end of file diff --git a/src/application.h b/src/application.h index b15720f5..fa2354f2 100644 --- a/src/application.h +++ b/src/application.h @@ -33,7 +33,6 @@ // KDE Includes #include #include -#include #include #include @@ -135,9 +134,8 @@ private slots: void postLaunch(); private: - - KUrl guessUrlFromString(const QString &url); - + KUrl xssSanitization(const KUrl &url); + static QPointer s_historyManager; static QPointer s_bookmarkProvider; static QPointer s_sessionManager; diff --git a/src/urlbar/urlbar.cpp b/src/urlbar/urlbar.cpp index 2adfcd17..e9952c01 100644 --- a/src/urlbar/urlbar.cpp +++ b/src/urlbar/urlbar.cpp @@ -138,12 +138,13 @@ void UrlBar::setUrl(const QUrl& url) { if(url.scheme() == "about") { - m_currentUrl = ""; + m_currentUrl = KUrl(); setFocus(); } else - m_currentUrl = url; - + { + m_currentUrl = KUrl(url); + } updateUrl(); } @@ -166,8 +167,14 @@ void UrlBar::updateUrl() } KIcon icon; - if(m_currentUrl.isEmpty()) icon = KIcon("arrow-right"); - else icon = Application::icon(m_currentUrl); + if(m_currentUrl.isEmpty()) + { + icon = KIcon("arrow-right"); + } + else + { + icon = Application::icon(m_currentUrl); + } if (count()) { @@ -190,14 +197,14 @@ void UrlBar::updateUrl() } -void UrlBar::activated(const QString& url) +void UrlBar::activated(const QString& urlString) { - if (url.isEmpty()) + if (urlString.isEmpty()) return; - setUrl(url); + setUrl(urlString); - Application::historyManager()->addHistoryEntry(url); + Application::historyManager()->addHistoryEntry(urlString); emit activated(m_currentUrl); } @@ -260,15 +267,6 @@ void UrlBar::paintEvent(QPaintEvent *event) } -void UrlBar::focusOutEvent(QFocusEvent *event) -{ - // set back last loaded url in case user cleared it - if (!m_currentUrl.equals(KUrl(lineEdit()->text()))) setUrl(m_currentUrl); - - KHistoryComboBox::focusOutEvent(event); -} - - QSize UrlBar::sizeHint() const { return lineEdit()->sizeHint(); @@ -293,7 +291,7 @@ QLinearGradient UrlBar::generateGradient(const QColor &color, int height) void UrlBar::setBackgroundColor(QColor c) { - s_defaultBaseColor=c; + s_defaultBaseColor = c; repaint(); } diff --git a/src/urlbar/urlbar.h b/src/urlbar/urlbar.h index 0e8bab26..8d267b2c 100644 --- a/src/urlbar/urlbar.h +++ b/src/urlbar/urlbar.h @@ -78,7 +78,6 @@ private slots: protected: virtual void paintEvent(QPaintEvent *event); - virtual void focusOutEvent(QFocusEvent *event); virtual void keyPressEvent(QKeyEvent *event); private: diff --git a/src/webpage.cpp b/src/webpage.cpp index 92318b36..a6c37906 100644 --- a/src/webpage.cpp +++ b/src/webpage.cpp @@ -187,7 +187,6 @@ void WebPage::manageNetworkErrors(QNetworkReply* reply) if( reply->error() == QNetworkReply::NoError ) return; - if( reply->url() != m_requestedUrl ) // prevent favicon loading return; @@ -223,6 +222,7 @@ QString WebPage::errorPage(QNetworkReply *reply) // display "not found" page QString notfoundFilePath = KStandardDirs::locate("data", "rekonq/htmls/notfound.html"); QFile file(notfoundFilePath); + bool isOpened = file.open(QIODevice::ReadOnly); if (!isOpened) { @@ -231,18 +231,17 @@ QString WebPage::errorPage(QNetworkReply *reply) } QString title = i18n("Error loading: %1", reply->url().path()); - QString imagesPath = QString("file://") + KGlobal::dirs()->findResourceDir("data", "rekonq/pics/bg.png") + QString("rekonq/pics"); - QString msg = "

" + reply->errorString() + "

"; + QString urlString = reply->url().toString( QUrl::RemoveUserInfo | QUrl::RemoveQuery ); - msg += "

" + i18nc("%1=an URL, e.g.'kde.org'", "When connecting to: %1", reply->url().toString()) + "

"; + msg += "

" + i18nc("%1=an URL, e.g.'kde.org'", "When connecting to: %1", urlString ) + "

"; msg += "
  • " + i18n("Check the address for errors such as ww.kde.org instead of www.kde.org"); msg += "
  • " + i18n("If the address is correct, try to check the network connection.") + "
  • " ; msg += i18n("If your computer or network is protected by a firewall or proxy, make sure that rekonq is permitted to access the network."); msg += "
  • " + i18n("Of course, if rekonq does not work properly, you can always say it is a programmer error ;)"); msg += "


"; - msg += "url().path() + "';\" value=\""; + msg += ""; QString html = QString(QLatin1String(file.readAll())) diff --git a/src/webview.cpp b/src/webview.cpp index 78c4caf8..fede781e 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -75,7 +75,7 @@ WebView::WebView(QWidget* parent) // download system connect(this, SIGNAL(linkShiftClicked(const KUrl &)), m_page, SLOT(downloadUrl(const KUrl &))); - connect(m_page, SIGNAL(downloadRequested(const QNetworkRequest &)), m_page, SLOT(downloadRequest(const QNetworkRequest &r))); + connect(m_page, SIGNAL(downloadRequested(const QNetworkRequest &)), m_page, SLOT(downloadRequest(const QNetworkRequest &))); // kwallet KWebWallet *w = m_page->wallet(); -- cgit v1.2.1