Fix server WMS access control security issue

Fixes #32475
This commit is contained in:
Alessandro Pasotti 2019-10-29 11:43:02 +01:00
parent 328f365b16
commit b77dc8b806
2 changed files with 51 additions and 3 deletions

View File

@ -3073,7 +3073,7 @@ namespace QgsWms
{
const QgsWmsParametersLayer param = mContext.parameters( *layer );
if ( param.mNickname.isEmpty() )
if ( ! mContext.layersToRender().contains( layer ) )
{
continue;
}

View File

@ -12,11 +12,22 @@ __copyright__ = 'Copyright 2015, The QGIS Project'
print('CTEST_FULL_OUTPUT')
import os
import json
from qgis.testing import unittest
import urllib.request
import urllib.parse
import urllib.error
from test_qgsserver_accesscontrol import TestQgsServerAccessControl
from utilities import unitTestDataPath
from qgis.core import QgsProject
from qgis.server import (
QgsServer,
QgsBufferServerRequest,
QgsBufferServerResponse,
QgsAccessControlFilter
)
class TestQgsServerAccessControlWMS(TestQgsServerAccessControl):
@ -97,8 +108,8 @@ class TestQgsServerAccessControlWMS(TestQgsServerAccessControl):
str(response).find("name=\"Country\"") != -1,
"No Country layer in GetProjectSettings\n%s" % response)
self.assertTrue(
str(response).find("name=\"Country\"")
< str(response).find("name=\"Hello\""),
str(response).find("name=\"Country\"") <
str(response).find("name=\"Hello\""),
"Hello layer not after Country layer\n%s" % response)
response, headers = self._get_restricted(query_string)
@ -450,6 +461,7 @@ class TestQgsServerAccessControlWMS(TestQgsServerAccessControl):
# # Subset String # #
def test_wms_getmap_subsetstring(self):
query_string = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
@ -898,6 +910,42 @@ class TestQgsServerAccessControlWMS(TestQgsServerAccessControl):
str(response).find("<qgs:pk>") != -1,
"Unexpected result from GetFeatureInfo Hello/2\n%s" % response)
def test_security_issue_gh32475(self):
"""Test access control security issue GH 32475"""
class Filter(QgsAccessControlFilter):
def layerFilterSubsetString(self, layer):
handler = iface.requestHandler()
if handler.parameter("LAYER_PERM") == "yes":
if layer.name() == "as_symbols" or layer.shortName() == "as_symbols":
return "\"gid\" != 1"
return None
def _gfi(restrict, layers):
qs = ("?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&"
+ "BBOX=612616,5810132,619259,5813237"
+ "&CRS=EPSG:25832&WIDTH=2759&HEIGHT=1290&&STYLES="
+ "&FORMAT=application/json&QUERY_LAYERS=%s"
+ "&INFO_FORMAT=application/json&I=508&J=560&FEATURE_COUNT=10" ) % layers
if restrict:
qs = qs + "&LAYER_PERM=yes"
request = QgsBufferServerRequest(qs)
response = QgsBufferServerResponse()
server.handleRequest(request, response, project)
return json.loads(bytes(response.body()).decode('utf8'))['features']
server = self._server
project = QgsProject()
project.read(os.path.join(unitTestDataPath('qgis_server'), 'test_project_wms_grouped_nested_layers.qgs'))
iface = server.serverInterface()
filter = Filter(iface)
iface.registerAccessControl(filter, 100)
self.assertEqual(len(_gfi(False, 'areas and symbols')), 1)
self.assertEqual(len(_gfi(True, 'areas and symbols')), 0)
self.assertEqual(len(_gfi(False, 'as_symbols')), 1)
self.assertEqual(len(_gfi(True, 'as_symbols')), 0)
if __name__ == "__main__":
unittest.main()