Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/app/components/FeedbackCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,13 @@
setPreviews(prev => prev.filter((_, i) => i !== idx));
};

const getSafeImagePreviewSrc = (src: string): string => {
if (typeof src !== 'string') return '';
if (src.startsWith('blob:')) return src;
if (/^data:image\/[a-zA-Z0-9.+-]+;base64,[a-zA-Z0-9+/=\s]+$/.test(src)) return src;
return '';
};

const handleReply = async () => {
if ((!replyText.trim() && images.length === 0) || isSubmitting) return;
setIsSubmitting(true);
Expand Down Expand Up @@ -387,7 +394,7 @@
{previews.map((src, i) => (
<div key={i} className="relative w-16 h-16 rounded border border-[#30363d] overflow-hidden group">
{/* CodeQL fix: sanitize image src */}
<img src={typeof src === 'string' && (src.startsWith('blob:') || src.startsWith('data:') || src.startsWith('http')) ? src : ''} alt="" className="w-full h-full object-cover" />
<img src={getSafeImagePreviewSrc(src)} alt="" className="w-full h-full object-cover" />

Check failure

Code scanning / CodeQL

DOM text reinterpreted as HTML High

DOM text
is reinterpreted as HTML without escaping meta-characters.
<button onClick={() => removeImage(i)} className="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 flex items-center justify-center transition-opacity">
<X className="w-4 h-4 text-white" />
</button>
Expand Down