Skip to content

Commit

Permalink
PB-577: Sanitize kml content
Browse files Browse the repository at this point in the history
  • Loading branch information
sommerfe committed Jan 29, 2025
1 parent 1658eeb commit 1994386
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 21 deletions.
7 changes: 7 additions & 0 deletions src/config/staging.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,10 @@ export const REPORT_PROBLEM_HOSTNAMES = [
* @type {String[]}
*/
export const WHITELISTED_HOSTNAMES = ['test.map.geo.admin.ch', 'map.geo.admin.ch']

/**
* List of blocked file extensions
*
* @type {String[]}
*/
export const BLOCKED_EXTENSIONS = ['exe', 'bat', 'cmd', 'sh', 'msi', 'scr', 'vbs', 'dll']
1 change: 1 addition & 0 deletions src/modules/i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"bg_toggle": "Zeige Hintergrundauswahl an",
"big_size": "Gross",
"black": "Schwarz",
"blocked_external_content": "[BLOCKIERTE EXTERNE INHALTE]",
"blue": "Blau",
"blw": "BLW",
"blw_service_link_href": "mailto:[email protected]",
Expand Down
1 change: 1 addition & 0 deletions src/modules/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"bg_toggle": "Toggle the list of backgrounds",
"big_size": "Large",
"black": "black",
"blocked_external_content": "[BLOCKED EXTERNAL CONTENT]",
"blue": "blue",
"blw": "FOAG",
"blw_service_link_href": "mailto:[email protected]",
Expand Down
1 change: 1 addition & 0 deletions src/modules/i18n/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"bg_toggle": "Afficher/masquer la liste des fonds de plan",
"big_size": "Grande",
"black": "noir",
"blocked_external_content": "[CONTENU EXTERNE BLOQUÉ]",
"blue": "bleu",
"blw": "OFAG",
"blw_service_link_href": "mailto:[email protected]",
Expand Down
1 change: 1 addition & 0 deletions src/modules/i18n/locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"bg_toggle": "Attiva la lista degli sfondi",
"big_size": "Grandi",
"black": "nero",
"blocked_external_content": "[CONTENUTO ESTERNO BLOCCATO]",
"blue": "blu",
"blw": "UFAG",
"blw_service_link_href": "mailto:[email protected]",
Expand Down
1 change: 1 addition & 0 deletions src/modules/i18n/locales/rm.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"bg_toggle": "Mussar il fund tschernì",
"big_size": "Grond",
"black": "nair",
"blocked_external_content": "[CUNTEGN EXTERIUR BLOCCÀ]",
"blue": "blau",
"blw": "UFAG",
"blw_service_link_href": "mailto:[email protected]",
Expand Down
66 changes: 46 additions & 20 deletions src/modules/infobox/components/FeatureDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useI18n } from 'vue-i18n'
import { useStore } from 'vuex'
import SelectableFeature from '@/api/features/SelectableFeature.class.js'
import { WHITELISTED_HOSTNAMES } from '@/config/staging.config'
import { BLOCKED_EXTENSIONS, WHITELISTED_HOSTNAMES } from '@/config/staging.config'
import FeatureAreaInfo from '@/modules/infobox/components/FeatureAreaInfo.vue'
import FeatureDetailDisclaimer from '@/modules/infobox/components/FeatureDetailDisclaimer.vue'
import CoordinateCopySlot from '@/utils/components/CoordinateCopySlot.vue'
Expand Down Expand Up @@ -35,27 +35,51 @@ const sanitizedFeatureDataEntries = computed(() => {
return []
}
return Object.entries(feature.value.data)
.filter(([_, value]) => value) // filtering out null values
.filter(([_, value]) => value) // Filtering out null values
.map(([key, value]) => [
key,
sanitizeHtml(value, key === 'description'),
getIframeHosts(value),
key === 'description' ? getIframeHosts(value) : [],
])
})
function sanitizeHtml(htmlText, withIframe = false) {
const blockedExternalContentString = i18n.t('blocked_external_content')
DOMPurify.addHook('afterSanitizeAttributes', function (node) {
// set all elements owning target to target=_blank
if ('target' in node) {
// Replacing possibly malicious code instead of removing with node.remove()
if (node.tagName === 'A') {
node.setAttribute('target', '_blank')
node.setAttribute('rel', 'noopener')
node.setAttribute('rel', 'noopener noreferrer')
try {
const url = new URL(node.getAttribute('href'))
const ext = url.pathname.split('.').pop().toLowerCase()
if (BLOCKED_EXTENSIONS.includes(ext)) {
node.outerHTML = blockedExternalContentString
return
}
} catch (error) {
node.outerHTML = blockedExternalContentString
return
}
}
if (node.tagName === 'IFRAME') {
try {
const src = new URL(node.getAttribute('src'))
const ext = src.pathname.split('.').pop().toLowerCase()
if (BLOCKED_EXTENSIONS.includes(ext)) {
node.outerHTML = blockedExternalContentString
return
}
} catch (error) {
node.outerHTML = blockedExternalContentString
return
}
}
})
let response = null
if (withIframe) {
response = DOMPurify.sanitize(htmlText, { ADD_TAGS: ['iframe'] })
} else {
response = DOMPurify.sanitize(htmlText)
const config = {
ADD_TAGS: withIframe ? ['iframe'] : [],
ALLOWED_URI_REGEXP: /^(https?|mailto|tel):/i, // Blocks file://, javascript:
}
let response = DOMPurify.sanitize(htmlText, config)
DOMPurify.removeHook('afterSanitizeAttributes')
return response
}
Expand All @@ -64,15 +88,17 @@ function getIframeHosts(value) {
let parser = new DOMParser()
let dom = parser.parseFromString(value, 'text/html')
const hosts = Array.from(dom.getElementsByTagName('iframe')).map((iframe) => {
try {
return new URL(iframe.src).hostname
} catch (error) {
log.error(`Invalid iframe source "${iframe.src}" cannot get hostname`)
return iframe.src
}
})
return hosts.filter((host) => !WHITELISTED_HOSTNAMES.includes(host))
return Array.from(dom.getElementsByTagName('iframe'))
.map((iframe) => {
if (!iframe.src) return null
try {
return new URL(iframe.src).hostname
} catch {
log.error(`Invalid iframe source "${iframe.src}" - cannot get hostname`)
return iframe.src
}
})
.filter((host) => host && !WHITELISTED_HOSTNAMES.includes(host))
}
</script>
Expand Down
2 changes: 1 addition & 1 deletion src/utils/components/AppVersion.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function openGithubRepoLink() {

<template>
<div class="app-version" :class="{ 'app-version-prod': isProd }" data-cy="app-version">
<span @click="openGithubRepoLink" class="githubIcon"
<span class="githubIcon" @click="openGithubRepoLink"
><font-awesome-icon :icon="['fab', 'github']"
/></span>
<span class="app-version-link" @click="openGithubReleaseLink"> {{ appVersion }}</span>
Expand Down

0 comments on commit 1994386

Please sign in to comment.