Trim headers considered unsafe from the WASM net requests

Some headers cannot be sent via XMLHttpRequest. In case one of those is
assigned to a network request, the header will now be trimmed on WASM so
that the request continues. Qt will print a warning on each request that
had its headers trimmed.

The list seems stable so it is not a lot of burden to sync Qt with it on
potential (unlikely) changes.

Fixes: QTBUG-95585
Change-Id: Id504ef43ad7e466ab567d4646d7ca00d6b7920d7
Reviewed-by: Aleksandr Reviakin <aleksandr.reviakin@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Mikolaj Boc 2022-10-21 16:30:19 +02:00
parent f4b028114a
commit 0b382080c2

View File

@ -17,6 +17,42 @@
#include <emscripten/fetch.h> #include <emscripten/fetch.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace {
constexpr const char *BannedHeaders[] = {
"accept-charset",
"accept-encoding",
"access-control-request-headers",
"access-control-request-method",
"connection",
"content-length",
"cookie",
"cookie2",
"date",
"dnt",
"expect",
"host",
"keep-alive",
"origin",
"referer",
"te",
"trailer",
"transfer-encoding",
"upgrade",
"via",
};
bool isUnsafeHeader(QLatin1StringView header)
{
return header.startsWith(QStringLiteral("proxy-"), Qt::CaseInsensitive)
|| header.startsWith(QStringLiteral("sec-"), Qt::CaseInsensitive)
|| std::any_of(std::begin(BannedHeaders), std::end(BannedHeaders),
[&header](const char *bannedHeader) {
return 0
== header.compare(QLatin1StringView(bannedHeader),
Qt::CaseInsensitive);
});
}
} // namespace
QNetworkReplyWasmImplPrivate::QNetworkReplyWasmImplPrivate() QNetworkReplyWasmImplPrivate::QNetworkReplyWasmImplPrivate()
: QNetworkReplyPrivate() : QNetworkReplyPrivate()
@ -190,15 +226,22 @@ void QNetworkReplyWasmImplPrivate::doSendRequest()
QList<QByteArray> headersData = request.rawHeaderList(); QList<QByteArray> headersData = request.rawHeaderList();
int arrayLength = getArraySize(headersData.count()); int arrayLength = getArraySize(headersData.count());
const char* customHeaders[arrayLength]; const char *customHeaders[arrayLength];
QStringList trimmedHeaders;
if (headersData.count() > 0) { if (headersData.count() > 0) {
int i = 0; int i = 0;
for (int j = 0; j < headersData.count(); j++) { for (const auto &headerName : headersData) {
customHeaders[i] = headersData[j].constData(); if (isUnsafeHeader(QLatin1StringView(headerName.constData()))) {
i += 1; trimmedHeaders.push_back(QString::fromLatin1(headerName));
customHeaders[i] = request.rawHeader(headersData[j]).constData(); } else {
i += 1; customHeaders[i++] = headerName.constData();
customHeaders[i++] = request.rawHeader(headerName).constData();
}
}
if (!trimmedHeaders.isEmpty()) {
qWarning() << "Qt has trimmed the following forbidden headers from the request:"
<< trimmedHeaders.join(QLatin1StringView(", "));
} }
customHeaders[i] = nullptr; customHeaders[i] = nullptr;
attr.requestHeaders = customHeaders; attr.requestHeaders = customHeaders;