desktop/source/lib/init.cxx | 8 +++++++ include/tools/hostfilter.hxx | 28 ++++++++++++++++++++++++++ sc/source/core/tool/webservicelink.cxx | 8 +++++-- sc/source/ui/docshell/externalrefmgr.cxx | 5 +++- tools/Library_tl.mk | 1 tools/source/inet/hostfilter.cxx | 31 +++++++++++++++++++++++++++++ ucb/source/ucp/webdav-curl/CurlSession.cxx | 7 ++++++ 7 files changed, 85 insertions(+), 3 deletions(-)
New commits: commit cf767af8de12157155eaf525ee845b196826aeb9 Author: Szymon Kłos <[email protected]> AuthorDate: Fri Dec 1 08:35:51 2023 +0100 Commit: Szymon Kłos <[email protected]> CommitDate: Tue Jan 9 07:49:11 2024 +0100 lok: external data source list Make possible to filter allowed data sources. It is used for WebDAV curl, WEBSERVICE function, cell external references. Change-Id: Ifc82af31ff1123b5656a21e6a27624fb1616db39 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160196 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161772 Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index b8acbcd9e599..dc6931e931bb 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -233,6 +233,8 @@ #include <com/sun/star/ui/XAcceleratorConfiguration.hpp> #include <svtools/acceleratorexecute.hxx> +#include <tools/hostfilter.hxx> + using namespace css; using namespace vcl; using namespace desktop; @@ -7749,6 +7751,12 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char } } + char* pAllowlist = ::getenv("LOK_HOST_ALLOWLIST"); + if (pAllowlist) + { + HostFilter::setAllowedHostsRegex(pAllowlist); + } + // What stage are we at ? if (pThis == nullptr) { diff --git a/include/tools/hostfilter.hxx b/include/tools/hostfilter.hxx new file mode 100644 index 000000000000..afbf885b0cb4 --- /dev/null +++ b/include/tools/hostfilter.hxx @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_TOOLS_HOSTFILTER_HXX +#define INCLUDED_TOOLS_HOSTFILTER_HXX + +#include <rtl/ustring.hxx> +#include <tools/toolsdllapi.h> + +// Helper for filtering allowed hosts for remote connections + +class TOOLS_DLLPUBLIC HostFilter +{ +public: + static void setAllowedHostsRegex(const char* sAllowedRegex); + + static bool isForbidden(const OUString& rHost); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx index 156048430636..c30f34300edf 100644 --- a/sc/source/core/tool/webservicelink.cxx +++ b/sc/source/core/tool/webservicelink.cxx @@ -7,7 +7,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include <comphelper/lok.hxx> #include <comphelper/processfactory.hxx> #include <sfx2/linkmgr.hxx> #include <sfx2/bindings.hxx> @@ -16,6 +15,9 @@ #include <com/sun/star/ucb/SimpleFileAccess.hpp> #include <com/sun/star/io/XInputStream.hpp> +#include <tools/hostfilter.hxx> +#include <tools/urlobj.hxx> + #include <utility> #include <webservicelink.hxx> #include <brdcst.hxx> @@ -37,7 +39,9 @@ sfx2::SvBaseLink::UpdateResult ScWebServiceLink::DataChanged(const OUString&, co aResult.clear(); bHasResult = false; - if (comphelper::LibreOfficeKit::isActive()) + INetURLObject aURLObject(aURL); + const OUString sHost = aURLObject.GetHost(); + if (HostFilter::isForbidden(sHost)) { SAL_WARN("sc.ui", "ScWebServiceLink::DataChanged: blocked access to external file: \"" << aURL << "\""); diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index 860ea8058c6e..f5b3dbd26fa1 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -50,6 +50,7 @@ #include <svl/urihelper.hxx> #include <svl/sharedstringpool.hxx> #include <sfx2/linkmgr.hxx> +#include <tools/hostfilter.hxx> #include <tools/urlobj.hxx> #include <unotools/charclass.hxx> #include <comphelper/configuration.hxx> @@ -2542,7 +2543,9 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, OUSt if (!isFileLoadable(aFile)) return nullptr; - if (comphelper::LibreOfficeKit::isActive()) + INetURLObject aURLObject(aFile); + const OUString sHost = aURLObject.GetHost(); + if (HostFilter::isForbidden(sHost)) { SAL_WARN( "sc.ui", "ScExternalRefManager::loadSrcDocument: blocked access to external file: \"" << aFile << "\""); return nullptr; diff --git a/tools/Library_tl.mk b/tools/Library_tl.mk index 8269e6ae98bf..99176a7c0902 100644 --- a/tools/Library_tl.mk +++ b/tools/Library_tl.mk @@ -67,6 +67,7 @@ $(eval $(call gb_Library_add_exception_objects,tl,\ tools/source/inet/inetmime \ tools/source/inet/inetmsg \ tools/source/inet/inetstrm \ + tools/source/inet/hostfilter \ tools/source/memtools/multisel \ tools/source/misc/cpuid \ tools/source/misc/extendapplicationenvironment \ diff --git a/tools/source/inet/hostfilter.cxx b/tools/source/inet/hostfilter.cxx new file mode 100644 index 000000000000..5bc63d42cfb7 --- /dev/null +++ b/tools/source/inet/hostfilter.cxx @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <tools/hostfilter.hxx> +#include <regex> + +static std::regex g_AllowedHostsRegex(""); +static bool g_AllowedHostsSet = false; + +void HostFilter::setAllowedHostsRegex(const char* sAllowedRegex) +{ + g_AllowedHostsSet = sAllowedRegex && sAllowedRegex[0] != ' + if (g_AllowedHostsSet) + g_AllowedHostsRegex = sAllowedRegex; +} + +bool HostFilter::isForbidden(const OUString& rHost) +{ + if (!g_AllowedHostsSet) + return false; + + return !std::regex_match(rHost.toUtf8().getStr(), g_AllowedHostsRegex); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx index a54e9d1addfb..11dc964fbe00 100644 --- a/ucb/source/ucp/webdav-curl/CurlSession.cxx +++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx @@ -37,6 +37,7 @@ #include <rtl/strbuf.hxx> #include <rtl/ustrbuf.hxx> #include <systools/curlinit.hxx> +#include <tools/hostfilter.hxx> #include <config_version.h> #include <map> @@ -1116,6 +1117,12 @@ auto CurlProcessor::ProcessRequest( ::std::pair<::std::vector<OUString> const&, DAVResource&> const* const pRequestedHeaders) -> void { + if (HostFilter::isForbidden(rURI.GetHost())) + { + SAL_WARN("ucb.ucp.webdav.curl", "Access denied to host: " << rURI.GetHost()); + throw uno::RuntimeException("access to host denied"); + } + if (pEnv) { // add custom request headers passed by caller for (auto const& rHeader : pEnv->m_aRequestHeaders)
