Allow heading tags (h1-h6) in ContentSanitizer so news editor headings render
This commit is contained in:
@@ -53,7 +53,12 @@ class LinkPreviewController extends Controller
|
||||
return response()->json(['error' => 'Invalid URL.'], 422);
|
||||
}
|
||||
|
||||
// Resolve hostname and block private/loopback IPs (SSRF protection)
|
||||
// Resolve hostname and block private/loopback IPs (SSRF protection).
|
||||
// NOTE: This check is not atomic with Guzzle's own DNS resolution — a
|
||||
// DNS rebinding attack could theoretically pass this check and then
|
||||
// resolve to an internal IP when Guzzle makes the actual request.
|
||||
// Risk is low (requires attacker-controlled DNS with very short TTL),
|
||||
// but this is a known limitation of the current approach.
|
||||
$resolved = gethostbyname($host);
|
||||
if ($this->isBlockedIp($resolved)) {
|
||||
return response()->json(['error' => 'URL not allowed.'], 422);
|
||||
|
||||
@@ -47,7 +47,9 @@ use App\Uploads\Exceptions\DraftQuotaException;
|
||||
use App\Models\Artwork;
|
||||
use App\Models\Group;
|
||||
use App\Services\GroupArtworkReviewService;
|
||||
use App\Support\ArtworkDescriptionContentValidator;
|
||||
use App\Services\Worlds\WorldSubmissionService;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
final class UploadController extends Controller
|
||||
@@ -534,6 +536,8 @@ final class UploadController extends Controller
|
||||
'nsfw' => ['nullable', 'boolean'],
|
||||
]);
|
||||
|
||||
$this->ensureValidArtworkDescription($validated);
|
||||
|
||||
$updates = [];
|
||||
foreach (['title', 'category_id', 'description', 'tags', 'license', 'nsfw'] as $field) {
|
||||
if (array_key_exists($field, $validated)) {
|
||||
@@ -635,6 +639,8 @@ final class UploadController extends Controller
|
||||
'world_submissions.*.source_surface' => ['nullable', 'string', 'max:80'],
|
||||
]);
|
||||
|
||||
$this->ensureValidArtworkDescription($validated);
|
||||
|
||||
$mode = $validated['mode'] ?? 'now';
|
||||
$visibility = $validated['visibility'] ?? 'public';
|
||||
|
||||
@@ -814,6 +820,8 @@ final class UploadController extends Controller
|
||||
'world_submissions.*.source_surface' => ['nullable', 'string', 'max:80'],
|
||||
]);
|
||||
|
||||
$this->ensureValidArtworkDescription($validated);
|
||||
|
||||
if (! ctype_digit($id)) {
|
||||
return response()->json(['message' => 'Artwork review submission requires an artwork draft id.'], Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
@@ -842,4 +850,13 @@ final class UploadController extends Controller
|
||||
'group_review_status' => (string) $artwork->group_review_status,
|
||||
], Response::HTTP_OK);
|
||||
}
|
||||
|
||||
private function ensureValidArtworkDescription(array $validated): void
|
||||
{
|
||||
foreach (ArtworkDescriptionContentValidator::errors($validated['description'] ?? null) as $message) {
|
||||
throw ValidationException::withMessages([
|
||||
'description' => [$message],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user