You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up from the adversarial review of PR #366 (GIS count k-anonymity). PR #366 suppresses the spatial-query / proximity / batch count paths named in the original report, but the review found the same class of count/presence leak in adjacent GIS endpoints that #366 does not touch. Filing so the module's count surfaces get consistent k-anonymity.
Findings (file:line on origin/19.0)
OGC Features numberMatched/numberReturned — spp_api_v2_gis/services/ogc_service.py:305-306 returns numberMatched = layers_service.get_feature_count(...) and numberReturned = len(features) for GET /gis/ogc/collections/{id}/items with an attacker-controlled bbox. get_feature_count is a raw search_count (services/layers_service.py:377,406) with no k-anonymity. For a data layer over a person-like model this is a per-bbox count oracle at arbitrary granularity — and the endpoint also returns the actual feature geometries and properties (individual records, _fetch_layer_featureslayers_service.py:317-380).
Report feature record_count — _get_report_feature_by_id / report items return "record_count": data.record_count per area plus raw_value/display_value (services/layers_service.py:~470-482) with no suppression; a small admin area with record_count=1 leaks single-beneficiary presence via the OGC items list and single-feature endpoint.
Export — export_service serializes the same report/data-layer GeoJSON (services/export_service.py:95,113), so GeoPackage/ZIP exports carry the same unsuppressed per-area record_count/values and any data-layer records.
Notes
The raw data-layer record exposure may be a pre-existing admin-configuration design choice (layers configured over person models); worth a design decision on whether GIS data layers should ever expose individual records to gis:read.
The unsuppressed report record_count and OGC numberMatched under an attacker-chosen bbox are the clearest count/presence oracles and should get the same k-anonymity treatment PR security(gis): apply k-anonymity suppression to spatial query beneficiary counts #366 applies to spatial queries (reuse spp.analytics.service.get_effective_k_threshold() + a canonical-suppression helper).
Cleared as safe: statistics router total_count = number of indicator definitions; geofence counts = the caller's own saved AOIs.
Distinct from #367 (batch differencing) and #368 (proximity-beyond differencing). Source: adversarial review of PR #366.
Follow-up from the adversarial review of PR #366 (GIS count k-anonymity). PR #366 suppresses the spatial-query / proximity / batch count paths named in the original report, but the review found the same class of count/presence leak in adjacent GIS endpoints that #366 does not touch. Filing so the module's count surfaces get consistent k-anonymity.
Findings (file:line on origin/19.0)
numberMatched/numberReturned—spp_api_v2_gis/services/ogc_service.py:305-306returnsnumberMatched = layers_service.get_feature_count(...)andnumberReturned = len(features)forGET /gis/ogc/collections/{id}/itemswith an attacker-controlledbbox.get_feature_countis a rawsearch_count(services/layers_service.py:377,406) with no k-anonymity. For a data layer over a person-like model this is a per-bbox count oracle at arbitrary granularity — and the endpoint also returns the actual feature geometries and properties (individual records,_fetch_layer_featureslayers_service.py:317-380).record_count—_get_report_feature_by_id/ report items return"record_count": data.record_countper area plusraw_value/display_value(services/layers_service.py:~470-482) with no suppression; a small admin area withrecord_count=1leaks single-beneficiary presence via the OGC items list and single-feature endpoint.export_serviceserializes the same report/data-layer GeoJSON (services/export_service.py:95,113), so GeoPackage/ZIP exports carry the same unsuppressed per-arearecord_count/values and any data-layer records.Notes
gis:read.record_countand OGCnumberMatchedunder an attacker-chosen bbox are the clearest count/presence oracles and should get the same k-anonymity treatment PR security(gis): apply k-anonymity suppression to spatial query beneficiary counts #366 applies to spatial queries (reusespp.analytics.service.get_effective_k_threshold()+ a canonical-suppression helper).statisticsroutertotal_count= number of indicator definitions;geofencecounts = the caller's own saved AOIs.Distinct from #367 (batch differencing) and #368 (proximity-beyond differencing). Source: adversarial review of PR #366.