Be more strict about opening URLs.

In the proto tree, copy URLs instead of opening them.

In the export dialog, enable previews only if the advertised MIME type
*and* the contents of the file are plain text, GIF, JPEG, or PNG.

Add warnings to the wslua browser_open_url and browser_open_data_file
documentation.

Fixes #17232.
This commit is contained in:
Gerald Combs 2021-02-12 11:54:54 -08:00 committed by Wireshark GitLab Utility
parent 270c8ed746
commit e99c9afce8
4 changed files with 49 additions and 7 deletions

View File

@ -1103,7 +1103,16 @@ WSLUA_FUNCTION wslua_reload_lua_plugins(lua_State* L) { /* Reload all Lua plugin
}
WSLUA_FUNCTION wslua_browser_open_url(lua_State* L) { /* Opens an URL in a web browser. Requires a GUI. */
WSLUA_FUNCTION wslua_browser_open_url(lua_State* L) { /*
Opens an URL in a web browser. Requires a GUI.
[WARNING]
====
Do not pass an untrusted URL to this function.
It will be passed to the system's URL handler, which might execute malicious code, switch on your Bluetooth-connected foghorn, or any of a number of unexpected or harmful things.
====
*/
#define WSLUA_ARG_browser_open_url_URL 1 /* The url. */
const char* url = luaL_checkstring(L,WSLUA_ARG_browser_open_url_URL);
@ -1121,6 +1130,13 @@ WSLUA_FUNCTION wslua_browser_open_data_file(lua_State* L) { /*
Open a file located in the data directory (specified in the Wireshark preferences) in the web browser.
If the file does not exist, the function silently ignores the request.
Requires a GUI.
[WARNING]
====
Do not pass an untrusted URL to this function.
It will be passed to the system's URL handler, which might execute malicious code, switch on your Bluetooth-connected foghorn, or any of a number of unexpected or harmful things.
====
*/
#define WSLUA_ARG_browser_open_data_file_FILENAME 1 /* The file name. */
const char* file = luaL_checkstring(L,WSLUA_ARG_browser_open_data_file_FILENAME);

View File

@ -17,9 +17,11 @@
#include "ui/qt/widgets/wireshark_file_dialog.h"
#include <ui/qt/widgets/export_objects_view.h>
#include <ui/qt/models/export_objects_model.h>
#include <ui/qt/utils/qt_ui_utils.h>
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QMimeDatabase>
#include <QPushButton>
#include <QComboBox>
#include <QDir>
@ -95,14 +97,27 @@ void ExportObjectDialog::currentHasChanged(QModelIndex current)
QModelIndex sibl = current.sibling(current.row(), ExportObjectModel::colPacket);
if (eo_ui_->buttonBox->button(QDialogButtonBox::Open))
{
QString cont = sibl.sibling(current.row(), ExportObjectModel::colContent).data().toString();
/* For security reasons application and unknown are disabled */
eo_ui_->buttonBox->button(QDialogButtonBox::Open)->setEnabled(! cont.startsWith("application/") && ! cont.startsWith("unknown/"));
QString mime_type = sibl.sibling(current.row(), ExportObjectModel::colContent).data().toString();
eo_ui_->buttonBox->button(QDialogButtonBox::Open)->setEnabled(mimeTypeIsPreviewable(mime_type));
}
wsApp->gotoFrame(sibl.data().toInt());
}
}
bool ExportObjectDialog::mimeTypeIsPreviewable(QString mime_type)
{
// XXX This excludes everything except HTTP. Maybe that's a good thing?
// Take care when adding to this, e.g. text/html or image/svg might contain JavaScript.
QStringList previewable_mime_types = QStringList()
<< "text/plain"
<< "image/gif" << "image/jpeg" << "image/png";
if (previewable_mime_types.contains(mime_type)) {
return true;
}
return false;
}
void ExportObjectDialog::modelDataChanged(const QModelIndex&, int from, int to)
{
bool contentTypes_changed = false;
@ -203,8 +218,16 @@ void ExportObjectDialog::on_buttonBox_clicked(QAbstractButton *button)
QString temp;
saveCurrentEntry(&temp);
if (temp.length() > 0)
QDesktopServices::openUrl(QUrl(QString("file:///").append(temp), QUrl::TolerantMode));
if (temp.length() > 0) {
QMimeDatabase mime_db;
QMimeType mime_type = mime_db.mimeTypeForFile(temp, QMimeDatabase::MatchContent);
if (mimeTypeIsPreviewable(mime_type.name())) {
QDesktopServices::openUrl(QUrl(QString("file:///").append(temp), QUrl::TolerantMode));
} else {
desktop_show_in_folder(temp);
}
}
break;
}
default: // Help, Cancel

View File

@ -55,6 +55,7 @@ private slots:
void currentHasChanged(QModelIndex current);
private:
bool mimeTypeIsPreviewable(QString mime_type);
void saveCurrentEntry(QString *tempFile = Q_NULLPTR);
void saveAllEntries();

View File

@ -614,7 +614,9 @@ void ProtoTree::itemDoubleClicked(const QModelIndex &index)
} else {
QString url = finfo.url();
if (!url.isEmpty()) {
QDesktopServices::openUrl(QUrl(url));
QApplication::clipboard()->setText(url);
QString push_msg = tr("Copied ") + url;
wsApp->pushStatus(WiresharkApplication::TemporaryStatus, push_msg);
}
}
}