Skip to content

Commit

Permalink
Merge pull request from GHSA-2f2w-349x-vrqm
Browse files Browse the repository at this point in the history
[3.5.7] `v-html` security fixes
  • Loading branch information
bastianallgeier authored Jul 2, 2021
2 parents 7ff4afd + a86e751 commit f5ead62
Show file tree
Hide file tree
Showing 46 changed files with 228 additions and 129 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"core"
],
"homepage": "https://getkirby.com",
"version": "3.5.7-rc.1",
"version": "3.5.7",
"license": "proprietary",
"authors": [
{
Expand Down
12 changes: 6 additions & 6 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion config/sections/files.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Kirby\Cms\File;
use Kirby\Toolkit\Escape;
use Kirby\Toolkit\I18n;

return [
Expand Down Expand Up @@ -116,6 +117,13 @@
foreach ($this->files as $file) {
$image = $file->panelImage($this->image);

// escape the default text
// TODO: no longer needed in 3.6
$text = $file->toString($this->text);
if ($this->text === '{{ file.filename }}') {
$text = Escape::html($text);
}

$data[] = [
'dragText' => $file->dragText('auto', $dragTextAbsolute),
'extension' => $file->extension(),
Expand All @@ -127,7 +135,7 @@
'link' => $file->panelUrl(true),
'mime' => $file->mime(),
'parent' => $file->parent()->panelPath(),
'text' => $file->toString($this->text),
'text' => $text,
'url' => $file->url(),
];
}
Expand Down
10 changes: 9 additions & 1 deletion config/sections/pages.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use Kirby\Cms\Blueprint;
use Kirby\Toolkit\A;
use Kirby\Toolkit\Escape;
use Kirby\Toolkit\I18n;

return [
Expand Down Expand Up @@ -153,10 +154,17 @@
$permissions = $item->permissions();
$image = $item->panelImage($this->image);

// escape the default text
// TODO: no longer needed in 3.6
$text = $item->toString($this->text);
if ($this->text === '{{ page.title }}') {
$text = Escape::html($text);
}

$data[] = [
'id' => $item->id(),
'dragText' => $item->dragText(),
'text' => $item->toString($this->text),
'text' => $text,
'info' => $item->toString($this->info ?? false),
'parent' => $item->parentId(),
'icon' => $item->panelIcon($image),
Expand Down
14 changes: 7 additions & 7 deletions i18n/translations/sv_SE.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
"error.page.duplicate.permission": "Du har inte behörighet att duplicera \"{slug}\"",
"error.page.notFound": "Sidan \"{slug}\" kan inte hittas",
"error.page.num.invalid": "Ange ett giltigt nummer för sortering. Numret får inte vara negativt.",
"error.page.slug.invalid": "Please enter a valid URL appendix",
"error.page.slug.invalid": "Ange en giltig URL-appendix",
"error.page.slug.maxlength": "Permalänkens längd måste vara kortare än \"{length}\" tecken",
"error.page.sort.permission": "Sidan \"{slug}\" kan inte sorteras",
"error.page.status.invalid": "Sätt en giltig status för sidan",
Expand Down Expand Up @@ -163,7 +163,7 @@
"error.user.password.invalid": "Ange ett giltigt lösenord. Lösenordet måste vara minst 8 tecken långt.",
"error.user.password.notSame": "Lösenorden matchar inte",
"error.user.password.undefined": "Användaren har inget lösenord",
"error.user.password.wrong": "Wrong password",
"error.user.password.wrong": "Fel lösenord",
"error.user.role.invalid": "Ange en giltig roll",
"error.user.update.permission": "Du har inte behörighet att uppdatera användaren \"{name}\"",

Expand Down Expand Up @@ -372,11 +372,11 @@
"more": "Mer",
"name": "Namn",
"next": "Nästa",
"no": "no",
"no": "nej",
"off": "av",
"on": "",
"open": "Öppna",
"open.newWindow": "Open in new window",
"open.newWindow": "Öppna i nytt fönster",
"options": "Alternativ",
"options.none": "Inga alternativ",

Expand Down Expand Up @@ -468,9 +468,9 @@
"toolbar.button.file.select": "Välj en fil",
"toolbar.button.file.upload": "Ladda upp en fil",
"toolbar.button.link": "L\u00e4nk",
"toolbar.button.strike": "Strike-through",
"toolbar.button.strike": "Genomstruken",
"toolbar.button.ol": "Sorterad lista",
"toolbar.button.underline": "Underline",
"toolbar.button.underline": "Understruken",
"toolbar.button.ul": "Punktlista",

"translation.author": "Kirby-teamet, Ola Christensson",
Expand Down Expand Up @@ -523,5 +523,5 @@

"welcome": "Välkommen",
"year": "År",
"yes": "yes"
"yes": "ja"
}
2 changes: 1 addition & 1 deletion panel/dist/css/app.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion panel/dist/js/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion panel/src/components/Dialogs/FileRemoveDialog.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<k-remove-dialog
ref="dialog"
:text="$t('file.delete.confirm', { filename: filename })"
:text="$t('file.delete.confirm', { filename: $esc(filename) })"
@submit="submit"
/>
</template>
Expand Down
2 changes: 1 addition & 1 deletion panel/src/components/Dialogs/FilesDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@submit="submit"
>
<template v-if="issue">
<k-box :text="issue" theme="negative" />
<k-box :text="issue" :html="false" theme="negative" />
</template>

<template v-else>
Expand Down
2 changes: 1 addition & 1 deletion panel/src/components/Dialogs/LanguageRemoveDialog.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<k-remove-dialog
ref="dialog"
:text="$t('language.delete.confirm', { name: language.name })"
:text="$t('language.delete.confirm', { name: $esc(language.name) })"
@submit="submit"
/>
</template>
Expand Down
4 changes: 2 additions & 2 deletions panel/src/components/Dialogs/PageRemoveDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
>
<template v-if="page.hasChildren || page.hasDrafts">
<!-- eslint-disable-next-line vue/no-v-html -->
<k-text v-html="$t('page.delete.confirm', { title: page.title })" />
<k-text v-html="$t('page.delete.confirm', { title: $esc(page.title) })" />
<div class="k-page-remove-warning">
<!-- eslint-disable-next-line vue/no-v-html -->
<k-box theme="negative" v-html="$t('page.delete.confirm.subpages')" />
Expand All @@ -21,7 +21,7 @@
</template>
<template v-else>
<!-- eslint-disable-next-line vue/no-v-html -->
<k-text @keydown.enter="submit" v-html="$t('page.delete.confirm', { title: page.title })" />
<k-text @keydown.enter="submit" v-html="$t('page.delete.confirm', { title: $esc(page.title) })" />
</template>
</k-remove-dialog>
</template>
Expand Down
2 changes: 1 addition & 1 deletion panel/src/components/Dialogs/PagesDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@submit="submit"
>
<template v-if="issue">
<k-box :text="issue" theme="negative" />
<k-box :text="issue" :html="false" theme="negative" />
</template>
<template v-else>
<header v-if="model" class="k-pages-dialog-navbar">
Expand Down
2 changes: 1 addition & 1 deletion panel/src/components/Dialogs/UserRemoveDialog.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<k-remove-dialog
ref="dialog"
:text="$t('user.delete.confirm', { email: user.email })"
:text="$t('user.delete.confirm', { email: $esc(user.email) })"
@submit="submit"
/>
</template>
Expand Down
2 changes: 1 addition & 1 deletion panel/src/components/Dialogs/UsersDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@submit="submit"
>
<template v-if="issue">
<k-box :text="issue" theme="negative" />
<k-box :text="issue" :html="false" theme="negative" />
</template>

<template v-else>
Expand Down
18 changes: 13 additions & 5 deletions panel/src/components/Forms/Autocomplete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
@keydown.backspace.prevent="close"
@keydown.delete.prevent="close"
>
{{ item.text }}
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="html ? item.text : $esc(item.text)" />
</k-dropdown-item>
</k-dropdown-content>
{{ query }}
Expand All @@ -27,6 +28,13 @@
*/
export default {
props: {
/**
* If set to `true`, the text of the options is rendered as HTML
*/
html: {
type: Boolean,
default: false
},
/**
* Maximum number of displayed results
*/
Expand All @@ -44,10 +52,10 @@ export default {
}
},
/**
* Options for the autocomplete dropdown must be passed as an array of
* objects. Each object can have as many items as you like, but a text
* Options for the autocomplete dropdown must be passed as an array of
* objects. Each object can have as many items as you like, but a text
* item is required to match agains the query
*
*
* @example [ { text: "this will be searched", id: "anything else is optional" }, ];
*/
options: Array,
Expand Down Expand Up @@ -119,4 +127,4 @@ export default {
}
}
}
</script>
</script>
2 changes: 1 addition & 1 deletion panel/src/components/Forms/FormButtons.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<p class="k-form-lock-info">
<k-icon type="lock" />
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="$t('lock.isLocked', { email: form.lock.email })" />
<span v-html="$t('lock.isLocked', { email: $esc(form.lock.email) })" />
</p>

<k-icon
Expand Down
3 changes: 2 additions & 1 deletion panel/src/components/Forms/Input/MultiselectInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
@keydown.native.right="navigate('next')"
@keydown.native.down="$refs.dropdown.open"
>
{{ tag.text }}
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="tag.text" />
</k-tag>

<k-dropdown-content
Expand Down
17 changes: 9 additions & 8 deletions panel/src/components/Forms/Input/RadioInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
class="k-radio-input-native"
@change="onInput(option.value)"
>
<label :for="id + '-' + index">
<template v-if="option.info">
<span class="k-radio-input-text">{{ option.text }}</span>
<span class="k-radio-input-info">{{ option.info }}</span>
</template>
<template v-else>
{{ option.text }}
</template>

<!-- eslint-disable vue/no-v-html -->
<label v-if="option.info" :for="id + '-' + index">
<span class="k-radio-input-text" v-html="option.text" />
<!-- @todo support (escaped) HTML in the info prop in 3.6.0 -->
<span class="k-radio-input-info">{{ option.info }}</span>
</label>
<label v-else :for="id + '-' + index" v-html="option.text" />
<!-- eslint-enable vue/no-v-html -->

<k-icon v-if="option.icon" :type="option.icon" />
</li>
</ul>
Expand Down
13 changes: 8 additions & 5 deletions panel/src/components/Forms/Input/TagsInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
@dblclick.native="edit(tag)"
@remove="remove(tag)"
>
{{ tag.text }}
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="tag.text" />
</k-tag>

<span slot="footer" class="k-tags-input-element">
<k-autocomplete
ref="autocomplete"
:html="true"
:options="options"
:skip="skip"
@select="addTag"
Expand Down Expand Up @@ -73,9 +76,9 @@ export default {
},
id: [Number, String],
/**
* You can set the layout to `list` to extend the width of each tag
* to 100% and show them in a list. This is handy in narrow columns
* or when a list is a more appropriate design choice for the input
* You can set the layout to `list` to extend the width of each tag
* to 100% and show them in a list. This is handy in narrow columns
* or when a list is a more appropriate design choice for the input
* in general.
*/
layout: String,
Expand All @@ -89,7 +92,7 @@ export default {
min: Number,
name: [Number, String],
/**
* Options will be shown in the autocomplete dropdown
* Options will be shown in the autocomplete dropdown
* as soon as you start typing.
*/
options: {
Expand Down
15 changes: 13 additions & 2 deletions panel/src/components/Layout/Box.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
<!-- @slot Use instead of `text` prop -->
<slot>
<!-- eslint-disable-next-line vue/no-v-html -->
<k-text v-html="text" />
<k-text v-if="html" v-html="text" />
<k-text v-else>
{{ text }}
</k-text>
</slot>
</div>
</template>
Expand All @@ -27,7 +30,15 @@ export default {
/**
* Text to display inside the box
*/
text: String
text: String,
/**
* If set to `false`, the `text` is rendered as text only
* @todo Switch default value to `false` in 3.6.0
*/
html: {
type: Boolean,
default: true
}
}
};
</script>
Expand Down
3 changes: 2 additions & 1 deletion panel/src/components/Layout/Card.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
<k-icon v-bind="icon" />
</span>
<figcaption class="k-card-content">
<span :data-noinfo="!info" class="k-card-text">{{ text }}</span>
<!-- eslint-disable-next-line vue/no-v-html -->
<span :data-noinfo="!info" class="k-card-text" v-html="text" />
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-if="info" class="k-card-info" v-html="info" />
</figcaption>
Expand Down
Loading

0 comments on commit f5ead62

Please sign in to comment.