Skip to content

Commit 0356b4c

Browse files
authored
Merge pull request #3222 from Roardom/bbcode-improvements
(Update) Remove XSS cleaner and remove XSS vulnerabilities
2 parents 32cec5a + ad716d7 commit 0356b4c

18 files changed

+152
-127
lines changed

Diff for: app/Helpers/Bbcode.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ class Bbcode
153153
'block' => true,
154154
],
155155
'namedquote' => [
156-
'openBbcode' => '/^\[quote=([^<>"]*?)\]/i',
156+
'openBbcode' => '/^\[quote=(.*?)\]/i',
157157
'closeBbcode' => '[/quote]',
158158
'openHtml' => '<blockquote><i class="fas fa-quote-left"></i> <cite>Quoting $1:</cite><p>',
159159
'closeHtml' => '</p></blockquote>',
@@ -278,6 +278,9 @@ class Bbcode
278278
*/
279279
public function parse(?string $source, bool $replaceLineBreaks = true): string
280280
{
281+
$source ??= '';
282+
$source = htmlspecialchars($source, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
283+
281284
// Replace all void elements since they don't have closing tags
282285
$source = str_replace('[*]', '<li>', (string) $source);
283286
$source = str_replace('[hr]', '<hr>', $source);
@@ -320,7 +323,7 @@ public function parse(?string $source, bool $replaceLineBreaks = true): string
320323
$source ?? ''
321324
);
322325
$source = preg_replace_callback(
323-
'/\[video="youtube"]([a-z0-9_-]{11})\[\/video]/i',
326+
'/\[video=&quot;youtube&quot;]([a-z0-9_-]{11})\[\/video]/i',
324327
static fn ($matches) => '<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/'.$matches[1].'?rel=0" allow="autoplay; encrypted-media" allowfullscreen></iframe>',
325328
$source ?? ''
326329
);

Diff for: app/Helpers/Linkify.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@ public function linky(string $text): string
2727
$validator = new Validator(
2828
false, // bool - if should use top level domain to match urls without scheme
2929
[], // string[] - array of blacklisted schemes
30-
[], // string[] - array of whitelisted schemes
30+
[
31+
'http',
32+
'https',
33+
'irc',
34+
'ftp',
35+
'sftp',
36+
'magnet',
37+
], // string[] - array of whitelisted schemes
3138
true // bool - if should match emails (if match by TLD set to "false" - will match only "mailto" urls)
3239
);
3340

Diff for: app/Http/Livewire/BbcodeInput.php

+2-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
use App\Helpers\Bbcode;
2020
use Livewire\Component;
21-
use voku\helper\AntiXSS;
2221

2322
class BbcodeInput extends Component
2423
{
@@ -39,13 +38,13 @@ final public function mount(string $name, string $label, bool $required = false,
3938
$this->name = $name;
4039
$this->label = $label;
4140
$this->isRequired = $required;
42-
$this->contentBbcode = $content === null ? (old($name) ?? '') : htmlspecialchars_decode($content);
41+
$this->contentBbcode = $content ?? old($name) ?? '';
4342
}
4443

4544
final public function updatedIsPreviewEnabled(): void
4645
{
4746
if ($this->isPreviewEnabled) {
48-
$this->contentHtml = (new Bbcode())->parse(htmlspecialchars((new AntiXSS())->xss_clean($this->contentBbcode), ENT_NOQUOTES));
47+
$this->contentHtml = (new Bbcode())->parse($this->contentBbcode);
4948
}
5049
}
5150

Diff for: app/Http/Resources/ChatMessageResource.php

+4-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use App\Helpers\Bbcode;
2020
use hdvinnie\LaravelJoyPixels\LaravelJoyPixels;
2121
use Illuminate\Http\Resources\Json\JsonResource;
22-
use voku\helper\AntiXSS;
2322

2423
/**
2524
* @mixin \App\Models\Message
@@ -33,17 +32,14 @@ class ChatMessageResource extends JsonResource
3332
*/
3433
public function toArray($request): array
3534
{
36-
$emojiOne = app()->make(LaravelJoyPixels::class);
35+
$emojiOne = new LaravelJoyPixels();
3736

3837
$bbcode = new Bbcode();
38+
$logger = $bbcode->parse($this->message);
39+
$logger = $emojiOne->toImage($logger);
3940

4041
if ($this->user_id == 1) {
41-
$logger = $bbcode->parse('<div class="align-left"><div class="chatTriggers">'.$this->message.'</div></div>');
42-
$logger = $emojiOne->toImage($logger);
4342
$logger = str_replace('a href="/#', 'a trigger="bot" class="chatTrigger" href="/#', $logger);
44-
} else {
45-
$logger = $bbcode->parse('<div class="align-left">'.$this->message.'</div>');
46-
$logger = $emojiOne->toImage($logger);
4743
}
4844

4945
return [
@@ -52,7 +48,7 @@ public function toArray($request): array
5248
'user' => new ChatUserResource($this->whenLoaded('user')),
5349
'receiver' => new ChatUserResource($this->whenLoaded('receiver')),
5450
'chatroom' => new ChatRoomResource($this->whenLoaded('chatroom')),
55-
'message' => (new AntiXSS())->xss_clean($logger),
51+
'message' => $logger,
5652
'created_at' => $this->created_at->toIso8601String(),
5753
'updated_at' => $this->updated_at->toIso8601String(),
5854
];

Diff for: app/Models/Article.php

-9
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use App\Traits\Auditable;
2222
use Illuminate\Database\Eloquent\Factories\HasFactory;
2323
use Illuminate\Database\Eloquent\Model;
24-
use voku\helper\AntiXSS;
2524

2625
/**
2726
* App\Models\Article.
@@ -69,14 +68,6 @@ public function comments(): \Illuminate\Database\Eloquent\Relations\MorphMany
6968
return $this->morphMany(Comment::class, 'commentable');
7069
}
7170

72-
/**
73-
* Set The Articles Content After Its Been Purified.
74-
*/
75-
public function setContentAttribute(?string $value): void
76-
{
77-
$this->attributes['content'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
78-
}
79-
8071
/**
8172
* Parse Content And Return Valid HTML.
8273
*/

Diff for: app/Models/Comment.php

-9
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
use Illuminate\Database\Eloquent\Builder;
2424
use Illuminate\Database\Eloquent\Factories\HasFactory;
2525
use Illuminate\Database\Eloquent\Model;
26-
use voku\helper\AntiXSS;
2726

2827
/**
2928
* App\Models\Comment.
@@ -111,14 +110,6 @@ public function scopeParent(Builder $builder): void
111110
$builder->whereNull('parent_id');
112111
}
113112

114-
/**
115-
* Set The Articles Content After Its Been Purified.
116-
*/
117-
public function setContentAttribute(?string $value): void
118-
{
119-
$this->attributes['content'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
120-
}
121-
122113
/**
123114
* Parse Content And Return Valid HTML.
124115
*/

Diff for: app/Models/Message.php

-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use App\Helpers\Bbcode;
2020
use Illuminate\Database\Eloquent\Factories\HasFactory;
2121
use Illuminate\Database\Eloquent\Model;
22-
use voku\helper\AntiXSS;
2322

2423
/**
2524
* App\Models\Message.
@@ -91,14 +90,6 @@ public function chatroom(): \Illuminate\Database\Eloquent\Relations\BelongsTo
9190
return $this->belongsTo(Chatroom::class);
9291
}
9392

94-
/**
95-
* Set The Chat Message After Its Been Purified.
96-
*/
97-
public function setMessageAttribute(string $value): void
98-
{
99-
$this->attributes['message'] = htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
100-
}
101-
10293
/**
10394
* Parse Content And Return Valid HTML.
10495
*/

Diff for: app/Models/Note.php

-9
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use App\Traits\Auditable;
2121
use Illuminate\Database\Eloquent\Factories\HasFactory;
2222
use Illuminate\Database\Eloquent\Model;
23-
use voku\helper\AntiXSS;
2423

2524
/**
2625
* App\Models\Note.
@@ -79,14 +78,6 @@ public function staffuser(): \Illuminate\Database\Eloquent\Relations\BelongsTo
7978
]);
8079
}
8180

82-
/**
83-
* Set Message After It's Been Purified.
84-
*/
85-
public function setMessageAttribute(?string $value): void
86-
{
87-
$this->attributes['message'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
88-
}
89-
9081
/**
9182
* Parse Message And Return Valid HTML.
9283
*/

Diff for: app/Models/Playlist.php

-9
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use App\Traits\Auditable;
2222
use Illuminate\Database\Eloquent\Factories\HasFactory;
2323
use Illuminate\Database\Eloquent\Model;
24-
use voku\helper\AntiXSS;
2524

2625
/**
2726
* App\Models\Playlist.
@@ -78,14 +77,6 @@ public function comments(): \Illuminate\Database\Eloquent\Relations\MorphMany
7877
return $this->morphMany(Comment::class, 'commentable');
7978
}
8079

81-
/**
82-
* Set The Playlists Description After It's Been Purified.
83-
*/
84-
public function setDescriptionAttribute(?string $value): void
85-
{
86-
$this->attributes['description'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
87-
}
88-
8980
/**
9081
* Parse Description And Return Valid HTML.
9182
*/

Diff for: app/Models/Post.php

-9
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use App\Traits\Auditable;
2222
use Illuminate\Database\Eloquent\Factories\HasFactory;
2323
use Illuminate\Database\Eloquent\Model;
24-
use voku\helper\AntiXSS;
2524

2625
/**
2726
* App\Models\Post.
@@ -156,14 +155,6 @@ public function scopeAuthorized(
156155
);
157156
}
158157

159-
/**
160-
* Set The Posts Content After Its Been Purified.
161-
*/
162-
public function setContentAttribute(?string $value): void
163-
{
164-
$this->attributes['content'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
165-
}
166-
167158
/**
168159
* Parse Content And Return Valid HTML.
169160
*/

Diff for: app/Models/PrivateMessage.php

-9
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use App\Helpers\Linkify;
2121
use Illuminate\Database\Eloquent\Factories\HasFactory;
2222
use Illuminate\Database\Eloquent\Model;
23-
use voku\helper\AntiXSS;
2423

2524
/**
2625
* App\Models\PrivateMessage.
@@ -64,14 +63,6 @@ public function conversation(): \Illuminate\Database\Eloquent\Relations\BelongsT
6463
return $this->belongsTo(Conversation::class);
6564
}
6665

67-
/**
68-
* Set The PM Message After Its Been Purified.
69-
*/
70-
public function setMessageAttribute(string $value): void
71-
{
72-
$this->attributes['message'] = htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
73-
}
74-
7566
/**
7667
* Parse Content And Return Valid HTML.
7768
*/

Diff for: app/Models/TicketNote.php

-9
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
use App\Helpers\Linkify;
2020
use Illuminate\Database\Eloquent\Model;
21-
use voku\helper\AntiXSS;
2221

2322
/**
2423
* App\Models\TicketNote.
@@ -59,14 +58,6 @@ public function ticket(): \Illuminate\Database\Eloquent\Relations\BelongsTo
5958
return $this->belongsTo(Ticket::class);
6059
}
6160

62-
/**
63-
* Set Message After It's Been Purified.
64-
*/
65-
public function setMessageAttribute(?string $value): void
66-
{
67-
$this->attributes['message'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
68-
}
69-
7061
/**
7162
* Parse Message And Return Valid HTML.
7263
*/

Diff for: app/Models/Torrent.php

-9
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
use Illuminate\Database\Eloquent\Model;
3030
use Illuminate\Database\Eloquent\SoftDeletes;
3131
use Laravel\Scout\Searchable;
32-
use voku\helper\AntiXSS;
3332

3433
/**
3534
* App\Models\Torrent.
@@ -751,14 +750,6 @@ public function trump(): \Illuminate\Database\Eloquent\Relations\HasOne
751750
return $this->hasOne(TorrentTrump::class);
752751
}
753752

754-
/**
755-
* Set The Torrents Description After Its Been Purified.
756-
*/
757-
public function setDescriptionAttribute(?string $value): void
758-
{
759-
$this->attributes['description'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
760-
}
761-
762753
/**
763754
* Parse Description And Return Valid HTML.
764755
*/

Diff for: app/Models/TorrentRequest.php

-9
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use App\Traits\Auditable;
2222
use Illuminate\Database\Eloquent\Factories\HasFactory;
2323
use Illuminate\Database\Eloquent\Model;
24-
use voku\helper\AntiXSS;
2524

2625
/**
2726
* App\Models\TorrentRequest.
@@ -215,14 +214,6 @@ public function claim(): \Illuminate\Database\Eloquent\Relations\HasOne
215214
return $this->hasOne(TorrentRequestClaim::class, 'request_id');
216215
}
217216

218-
/**
219-
* Set The Requests Description After Its Been Purified.
220-
*/
221-
public function setDescriptionAttribute(?string $value): void
222-
{
223-
$this->attributes['description'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
224-
}
225-
226217
/**
227218
* Parse Description And Return Valid HTML.
228219
*/

Diff for: app/Models/User.php

-17
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
use Illuminate\Foundation\Auth\User as Authenticatable;
2929
use Illuminate\Notifications\Notifiable;
3030
use Laravel\Fortify\TwoFactorAuthenticatable;
31-
use voku\helper\AntiXSS;
3231

3332
/**
3433
* App\Models\User.
@@ -1181,14 +1180,6 @@ public function getFormattedBufferAttribute(): string
11811180
return StringHelper::formatBytes($bytes);
11821181
}
11831182

1184-
/**
1185-
* Set The Users Signature After It's Been Purified.
1186-
*/
1187-
public function setSignatureAttribute(?string $value): void
1188-
{
1189-
$this->attributes['signature'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
1190-
}
1191-
11921183
/**
11931184
* Returns the HTML of the user's signature.
11941185
*/
@@ -1199,14 +1190,6 @@ public function getSignatureHtmlAttribute(): string
11991190
return (new Linkify())->linky($bbcode->parse($this->signature));
12001191
}
12011192

1202-
/**
1203-
* Set The Users About Me After It's Been Purified.
1204-
*/
1205-
public function setAboutAttribute(?string $value): void
1206-
{
1207-
$this->attributes['about'] = $value === null ? null : htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
1208-
}
1209-
12101193
/**
12111194
* Parse About Me And Return Valid HTML.
12121195
*/

Diff for: composer.json

-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
"spatie/ssl-certificate": "^2.6.8",
4242
"symfony/dom-crawler": "^6.4.16",
4343
"theodorejb/polycast": "dev-master",
44-
"voku/anti-xss": "^4.1.42",
4544
"vstelmakh/url-highlight": "^3.1.1"
4645
},
4746
"require-dev": {

0 commit comments

Comments
 (0)