Skip to content

Commit

Permalink
Content sanitisation in attributes table (#4409)
Browse files Browse the repository at this point in the history
* Add virtual column with content to be sanitized

* call Dom purify on each property instead of full features objet

* update cypress test to match columns and check valued is purified
  • Loading branch information
nworr authored May 7, 2024
1 parent 2445864 commit 25eb33d
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
7 changes: 4 additions & 3 deletions assets/src/legacy/attributeTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,7 @@ var lizAttributeTable = function() {
layerConfig['columns'] = describeFeatureTypeResponse.columns;
}

const sanitizedResponse = JSON.parse(DOMPurify.sanitize(JSON.stringify(responses[0].features)));

buildLayerAttributeDatatable(layerName, tableSelector, sanitizedResponse, layerConfig.aliases, layerConfig.types, allColumnsKeyValues, callBack);
buildLayerAttributeDatatable(layerName, tableSelector, responses[0].features, layerConfig.aliases, layerConfig.types, allColumnsKeyValues, callBack);

document.body.style.cursor = 'default';
}).catch(() => {
Expand Down Expand Up @@ -1843,6 +1841,9 @@ var lizAttributeTable = function() {
if( ($.inArray(idx, hiddenFields) > -1) )
continue;
var prop = feat.properties[idx];
if (typeof prop == 'string') {
prop = DOMPurify.sanitize(prop);
}
line[idx] = prop;
}

Expand Down
12 changes: 11 additions & 1 deletion tests/end2end/cypress/integration/attribute_table-ghaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('Attribute table', () => {

it('should have correct column order', () => {

const correct_column_order = ['', 'quartier', 'quartmno', 'libquart', 'photo', 'url'];
const correct_column_order = ['', 'quartier', 'quartmno', 'libquart', 'photo', 'url', 'thumbnail'];

// postgreSQL layer
cy.get('button[value="Les_quartiers_a_Montpellier"].btn-open-attribute-layer').click({ force: true })
Expand Down Expand Up @@ -194,6 +194,12 @@ describe('Attribute table', () => {
expect(interception.response.body)
.to.have.property('features')
expect(interception.response.body.features).to.have.length(7)
// the virtual field exists
expect(interception.response.body.features[1].properties).to.have.property('thumbnail')
// the content of the field is ok
expect(interception.response.body.features[1].properties.thumbnail).to.contain('img class="data-attr-thumbnail"');
// the 'onload' value is here (ie whole content is here)
expect(interception.response.body.features[1].properties.thumbnail).to.contain("BAD_CODE");
})
// Check that GetMap is requested without the filter token
cy.wait('@getMap').then((interception) => {
Expand All @@ -207,6 +213,10 @@ describe('Attribute table', () => {

// Check table lines
cy.get('#attribute-layer-table-Les_quartiers_a_Montpellier tbody tr').should('have.length', 7)
// the virtual field is here with good attribute (data-src)
cy.get('#attribute-layer-table-Les_quartiers_a_Montpellier tbody tr:nth-child(1) td:nth-child(7) img[data-src]').should('exist')
// the onload attribute have disappeared
cy.get('#attribute-layer-table-Les_quartiers_a_Montpellier tbody tr:nth-child(1) td:nth-child(7) img[onload]').should('not.exist')

// select feature 2,4,6
// click to select 2
Expand Down
31 changes: 29 additions & 2 deletions tests/qgis-projects/tests/attribute_table.qgs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,9 @@
<vectorjoins></vectorjoins>
<layerDependencies></layerDependencies>
<dataDependencies></dataDependencies>
<expressionfields></expressionfields>
<expressionfields>
<field expression="concat(&#xd;&#xa; '&lt;img class=&quot;data-attr-thumbnail&quot; data-src=&quot;',&#xd;&#xa; &quot;photo&quot; ,&#xd;&#xa;'&quot; foo=&quot;bar&quot; src=&quot;/themes/default/css/img/logo_footer.png&quot; style=&quot;height:60px;&quot;&#xd;&#xa; onload=&quot;BAD_CODE_TO_REMOVE&quot;>'&#xd;&#xa; &#xd;&#xa;)" type="10" name="thumbnail" precision="0" length="0" typeName="string" subType="0" comment=""/>
</expressionfields>
<map-layer-style-manager current="défaut">
<map-layer-style name="défaut"></map-layer-style>
</map-layer-style-manager>
Expand Down Expand Up @@ -313,34 +315,45 @@
</config>
</editWidget>
</field>
<field configurationFlags="None" name="thumbnail">
<editWidget type="">
<config>
<Option></Option>
</config>
</editWidget>
</field>
</fieldConfiguration>
<aliases>
<alias field="quartier" index="0" name=""></alias>
<alias field="quartmno" index="1" name=""></alias>
<alias field="libquart" index="2" name=""></alias>
<alias field="photo" index="3" name=""></alias>
<alias field="url" index="4" name=""></alias>
<alias field="thumbnail" index="5" name=""></alias>
</aliases>
<defaults>
<default applyOnUpdate="0" expression="" field="quartier"></default>
<default applyOnUpdate="0" expression="" field="quartmno"></default>
<default applyOnUpdate="0" expression="" field="libquart"></default>
<default applyOnUpdate="0" expression="" field="photo"></default>
<default applyOnUpdate="0" expression="" field="url"></default>
<default applyOnUpdate="0" expression="" field="thumbnail"></default>
</defaults>
<constraints>
<constraint constraints="0" exp_strength="0" field="quartier" notnull_strength="0" unique_strength="0"></constraint>
<constraint constraints="0" exp_strength="0" field="quartmno" notnull_strength="0" unique_strength="0"></constraint>
<constraint constraints="0" exp_strength="0" field="libquart" notnull_strength="0" unique_strength="0"></constraint>
<constraint constraints="0" exp_strength="0" field="photo" notnull_strength="0" unique_strength="0"></constraint>
<constraint constraints="0" exp_strength="0" field="url" notnull_strength="0" unique_strength="0"></constraint>
<constraint constraints="0" exp_strength="0" field="thumbnail" notnull_strength="0" unique_strength="0"></constraint>
</constraints>
<constraintExpressions>
<constraint desc="" exp="" field="quartier"></constraint>
<constraint desc="" exp="" field="quartmno"></constraint>
<constraint desc="" exp="" field="libquart"></constraint>
<constraint desc="" exp="" field="photo"></constraint>
<constraint desc="" exp="" field="url"></constraint>
<constraint desc="" exp="" field="thumbnail"></constraint>
</constraintExpressions>
<expressionfields></expressionfields>
<attributeactions>
Expand Down Expand Up @@ -448,7 +461,9 @@
<vectorjoins></vectorjoins>
<layerDependencies></layerDependencies>
<dataDependencies></dataDependencies>
<expressionfields></expressionfields>
<expressionfields>
<field expression="concat(&#xd;&#xa; '&lt;img class=&quot;data-attr-thumbnail&quot; data-src=&quot;',&#xd;&#xa; &quot;photo&quot; ,&#xd;&#xa;'&quot; foo=&quot;bar&quot; src=&quot;/themes/default/css/img/logo_footer.png&quot; style=&quot;height:60px;&quot;&#xd;&#xa; onload=&quot;BAD_CODE_TO_REMOVE&quot;>'&#xd;&#xa; &#xd;&#xa;)" type="10" name="thumbnail" precision="0" length="0" typeName="string" subType="0" comment=""/>
</expressionfields>
<map-layer-style-manager current="défaut">
<map-layer-style name="défaut"></map-layer-style>
</map-layer-style-manager>
Expand Down Expand Up @@ -665,34 +680,45 @@
</config>
</editWidget>
</field>
<field configurationFlags="None" name="thumbnail">
<editWidget type="TextEdit">
<config>
<Option></Option>
</config>
</editWidget>
</field>
</fieldConfiguration>
<aliases>
<alias field="quartier" index="0" name=""></alias>
<alias field="quartmno" index="1" name=""></alias>
<alias field="libquart" index="2" name=""></alias>
<alias field="photo" index="3" name=""></alias>
<alias field="url" index="4" name=""></alias>
<alias field="thumbnail" index="5" name=""></alias>
</aliases>
<defaults>
<default applyOnUpdate="0" expression="" field="quartier"></default>
<default applyOnUpdate="0" expression="" field="quartmno"></default>
<default applyOnUpdate="0" expression="" field="libquart"></default>
<default applyOnUpdate="0" expression="" field="photo"></default>
<default applyOnUpdate="0" expression="" field="url"></default>
<default applyOnUpdate="0" expression="" field="thumbnail"></default>
</defaults>
<constraints>
<constraint constraints="3" exp_strength="0" field="quartier" notnull_strength="1" unique_strength="1"></constraint>
<constraint constraints="0" exp_strength="0" field="quartmno" notnull_strength="0" unique_strength="0"></constraint>
<constraint constraints="0" exp_strength="0" field="libquart" notnull_strength="0" unique_strength="0"></constraint>
<constraint constraints="0" exp_strength="0" field="photo" notnull_strength="0" unique_strength="0"></constraint>
<constraint constraints="0" exp_strength="0" field="url" notnull_strength="0" unique_strength="0"></constraint>
<constraint constraints="0" exp_strength="0" field="thumbnail" notnull_strength="0" unique_strength="0"></constraint>
</constraints>
<constraintExpressions>
<constraint desc="" exp="" field="quartier"></constraint>
<constraint desc="" exp="" field="quartmno"></constraint>
<constraint desc="" exp="" field="libquart"></constraint>
<constraint desc="" exp="" field="photo"></constraint>
<constraint desc="" exp="" field="url"></constraint>
<constraint desc="" exp="" field="thumbnail"></constraint>
</constraintExpressions>
<expressionfields></expressionfields>
<attributeactions>
Expand All @@ -705,6 +731,7 @@
<column hidden="0" name="libquart" type="field" width="-1"></column>
<column hidden="0" name="photo" type="field" width="348"></column>
<column hidden="0" name="url" type="field" width="305"></column>
<column hidden="0" name="thumbnail" type="field" width="348"></column>
<column hidden="1" type="actions" width="-1"></column>
</columns>
</attributetableconfig>
Expand Down

0 comments on commit 25eb33d

Please sign in to comment.