Skip to content

Commit

Permalink
HTM-1286: Fix code scanning alert no. 352: Server-side request forgery (
Browse files Browse the repository at this point in the history
#1031)

* Fix code scanning alert no. 352: Server-side request forgery

CoPilot AI generated patch

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Improve AI code, add unit test

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Matthijs Laan <[email protected]>
  • Loading branch information
3 people authored Nov 12, 2024
1 parent ef324ba commit c988cbd
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.geotools.data.wfs.WFSDataStoreFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -63,6 +64,9 @@ public class LayerExportController {
private static final Logger logger =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

@Value("#{'${tailormap-api.export.allowed-outputformats}'.split(',')}")
private List<String> allowedOutputFormats;

private final FeatureSourceRepository featureSourceRepository;

public LayerExportController(FeatureSourceRepository featureSourceRepository) {
Expand Down Expand Up @@ -128,6 +132,12 @@ public ResponseEntity<?> download(
@RequestParam(required = false) String crs,
HttpServletRequest request) {

// Validate outputFormat
if (!allowedOutputFormats.contains(outputFormat)) {
logger.warn("Invalid output format requested: {}", outputFormat);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid output format");
}

TMFeatureType tmft = service.findFeatureTypeForLayer(layer, featureSourceRepository);
AppLayerSettings appLayerSettings = application.getAppLayerSettings(appTreeLayerNode);

Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ tailormap-api.features.wfs_count_exact=false
# maximum number of items to return in a single (WFS/JDBC) feature info request
tailormap-api.feature.info.maxitems=30

# Should match the list in tailormap-viewer class AttributeListExportService
tailormap-api.export.allowed-outputformats=csv,text/csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,excel2007,application/vnd.shp,application/x-zipped-shp,SHAPE-ZIP,application/geopackage+sqlite3,application/x-gpkg,geopackage,geopkg,gpkg,application/geo+json,application/geojson,application/json,json,DXF-ZIP

# whether the API should use GeoTools "Unique Collection" (use DISTINCT in SQL statements) or just
# retrieve all values when calculating the unique values for a property.
# There might be a performance difference between the two, depending on the data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void shouldExportGeoJSON() throws Exception {
get(url)
.with(setServletPath(url))
.accept(MediaType.APPLICATION_JSON)
.param("outputFormat", "application/json")
.param("outputFormat", MediaType.APPLICATION_JSON_VALUE)
.param("attributes", "geom,naam,code"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
Expand Down Expand Up @@ -159,7 +159,7 @@ void shouldExportGeoJSONWithFilterAndSort() throws Exception {
get(url)
.accept(MediaType.APPLICATION_JSON)
.with(setServletPath(url))
.param("outputFormat", "application/json")
.param("outputFormat", MediaType.APPLICATION_JSON_VALUE)
.param("filter", "(BRONHOUDER IN ('G1904','L0002','L0004'))")
.param("sortBy", "CLASS")
.param("sortOrder", "asc"))
Expand All @@ -176,7 +176,7 @@ void shouldExportGeoJSONWithFilterAndSort() throws Exception {
get(url)
.accept(MediaType.APPLICATION_JSON)
.with(setServletPath(url))
.param("outputFormat", "application/json")
.param("outputFormat", MediaType.APPLICATION_JSON_VALUE)
.param("filter", "(BRONHOUDER IN ('G1904','L0002','L0004'))")
.param("sortBy", "CLASS")
.param("sortOrder", "desc"))
Expand All @@ -197,7 +197,7 @@ void shouldNotExportHiddenAttributesInGeoJSONWhenRequested() throws Exception {
get(url)
.accept(MediaType.APPLICATION_JSON)
.with(setServletPath(url))
.param("outputFormat", "application/json")
.param("outputFormat", MediaType.APPLICATION_JSON_VALUE)
// terminationdate,geom_kruinlijn are hidden attributes
.param(
"attributes", "identificatie,bronhouder,class,terminationdate,geom_kruinlijn"))
Expand All @@ -216,7 +216,7 @@ void shouldNotExportHiddenAttributesInGeoJSON() throws Exception {
get(url)
.accept(MediaType.APPLICATION_JSON)
.with(setServletPath(url))
.param("outputFormat", "application/json")
.param("outputFormat", MediaType.APPLICATION_JSON_VALUE)
.param("filter", "(bronhouder ILIKE 'L0001')"))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
Expand All @@ -237,7 +237,19 @@ void test_wms_secured_proxy_not_in_public_app() throws Exception {
get(testUrl)
.accept(MediaType.APPLICATION_JSON)
.with(setServletPath(testUrl))
.param("outputFormat", "application/json"))
.param("outputFormat", MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isForbidden());
}

@Test
void testInvalidOutputFormatNotAccepted() throws Exception {
final String testUrl = apiBasePath + layerBegroeidTerreindeelPostgis + "/export/download";
mockMvc
.perform(
get(testUrl)
.accept(MediaType.APPLICATION_JSON)
.with(setServletPath(testUrl))
.param("outputFormat", "Invalid value!"))
.andExpect(status().isBadRequest());
}
}
1 change: 1 addition & 0 deletions src/test/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ tailormap-api.base-path=/api
tailormap-api.admin.base-path=/api/admin
management.endpoints.web.base-path=/api/actuator
tailormap-api.new-admin-username=tm-admin
tailormap-api.export.allowed-outputformats=application/geopackage+sqlite3,application/json
tailormap-api.timeout=5000
tailormap-api.management.hashed-password=#{null}
spring.profiles.active=test
Expand Down

0 comments on commit c988cbd

Please sign in to comment.