Skip to content

Commit 9e19a37

Browse files
authored
Merge pull request #53 from iFixit/fix/security-hardening
Security Hardening
2 parents 64b9602 + 84dbe41 commit 9e19a37

11 files changed

Lines changed: 74 additions & 38 deletions

File tree

app/Http/Controllers/GroupController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ public function postSendInvite(Request $request): RedirectResponse
376376

377377
// Don't log to Sentry - legitimate user error.
378378
return redirect()->back()->with('warning', __('groups.invite_success_apart_from', [
379-
'emails' => rtrim(implode(', ', $not_sent))
379+
'emails' => e(rtrim(implode(', ', $not_sent)))
380380
]));
381381
}
382382

app/Http/Controllers/PartyController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ public function postSendInvite(Request $request): RedirectResponse
704704

705705
// Don't log to Sentry - legitimate user error.
706706
return redirect()->back()->with('warning', __('events.invite_invalid_emails', [
707-
'emails' => implode(', ', $not_sent)
707+
'emails' => e(implode(', ', $not_sent))
708708
]));
709709
}
710710

app/Models/Alert.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Support\Facades\Lang;
99
use Illuminate\Support\Facades\Log;
1010
use OwenIt\Auditing\Contracts\Auditable;
11+
use Stevebauman\Purify\Facades\Purify;
1112

1213
class Alert extends Model implements Auditable
1314
{
@@ -32,4 +33,9 @@ class Alert extends Model implements Auditable
3233
'end',
3334
'variant'
3435
];
36+
37+
public function setHtmlAttribute($value)
38+
{
39+
$this->attributes['html'] = $value === null ? null : Purify::clean((string) $value);
40+
}
3541
}

config/purify.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
'http' => true,
5050
'https' => true,
5151
'mailto' => true,
52+
'tel' => true,
5253
],
5354
'AutoFormat.AutoParagraph' => false,
5455
'AutoFormat.RemoveEmpty' => false,

package-lock.json

Lines changed: 47 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818
"@playwright/test": "^1.14.1",
1919
"@vue/test-utils": "^1.3.6",
2020
"@vue/vue2-jest": "^28.1.0",
21-
"axios": "^1.6.4",
21+
"axios": "^1.15.2",
2222
"babel-jest": "^28.1.0",
2323
"bootstrap": "^4.6.1",
2424
"browser-sync": "^2.27.11",
2525
"browser-sync-webpack-plugin": "^2.3.0",
26+
"concurrently": "^9.0.1",
2627
"faker": "^5.5.3",
2728
"jest": "^28.1.0",
2829
"jest-environment-jsdom": "^28.1.0",
@@ -44,7 +45,6 @@
4445
"vue": "^2.7.14",
4546
"vue-loader": "^15.10.1",
4647
"vue-template-compiler": "^2.7.14",
47-
"concurrently": "^9.0.1",
4848
"webpack-shell-plugin-next": "^2.3.1"
4949
},
5050
"dependencies": {

resources/js/components/AlertBanner.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<!-- <span class='badge badge-warning'>NEW!</span> -->
1111
<strong>{{ alert.title }}</strong>
1212
</div>
13-
<div v-html="alert.html" />
13+
<div v-html="sanitize(alert.html)" />
1414
</div>
1515
</div>
1616

@@ -24,6 +24,7 @@
2424
</template>
2525
<script>
2626
import moment from 'moment'
27+
import DOMPurify from 'dompurify'
2728
2829
export default {
2930
computed: {
@@ -53,6 +54,9 @@ export default {
5354
await this.$store.dispatch('alerts/fetch')
5455
},
5556
methods: {
57+
sanitize(html) {
58+
return DOMPurify.sanitize(html)
59+
},
5660
dismissed(id) {
5761
try {
5862
localStorage.setItem('alert-' + id, true)

resources/js/components/GroupActions.vue

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
<script>
6767
import group from '../mixins/group'
6868
import ConfirmModal from './ConfirmModal'
69+
import { escapeHtml } from '../helpers/escapeHtml'
6970
7071
export default {
7172
components: { ConfirmModal },
@@ -100,11 +101,7 @@ export default {
100101
}
101102
},
102103
methods: {
103-
escapeHtml(str) {
104-
const el = document.createElement('span')
105-
el.textContent = str
106-
return el.innerHTML
107-
},
104+
escapeHtml,
108105
leaveGroup() {
109106
this.$refs.confirmLeave.show()
110107
},

resources/js/components/GroupPage.vue

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import GroupDevicesMostRepaired from './GroupDevicesMostRepaired'
6060
import GroupDevicesBreakdown from './GroupDevicesBreakdown'
6161
import AlertBanner from './AlertBanner'
6262
import auth from '../mixins/auth'
63+
import { escapeHtml } from '../helpers/escapeHtml'
6364
6465
export default {
6566
components: {
@@ -160,11 +161,7 @@ export default {
160161
}
161162
},
162163
methods: {
163-
escapeHtml(str) {
164-
const el = document.createElement('span')
165-
el.textContent = str
166-
return el.innerHTML
167-
},
164+
escapeHtml,
168165
},
169166
computed: {
170167
group() {

resources/js/components/ReadMore.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export default {
6969
val_container = val_container.substring(0, this.maxChars) + "...";
7070
}
7171
72-
return val_container;
72+
return DOMPurify.sanitize(val_container);
7373
},
7474
sanitizedHtml() {
7575
return this.html ? DOMPurify.sanitize(this.html) : null
@@ -84,7 +84,7 @@ export default {
8484
return this.truncatedHTML ? DOMPurify.sanitize(this.truncatedHTML) : null
8585
},
8686
needsTruncating() {
87-
if (this.text && (text.length > maxChars)) {
87+
if (this.text && (this.text.length > this.maxChars)) {
8888
return true
8989
}
9090

0 commit comments

Comments
 (0)