Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| return markdown | ||
| .replace(/^#+\s+/gm, "") // headings | ||
| .replace(/\*\*(.*?)\*\*/g, "$1") // bold | ||
| .replace(/\*(.*?)\*/g, "$1") // italic | ||
| .replace(/__(.*?)__/g, "$1") // bold | ||
| .replace(/_(.*?)_/g, "$1") // italic | ||
| .replace(/~~(.*?)~~/g, "$1") // strikethrough | ||
| .replace(/\[(.*?)\]\(.*?\)/g, "$1") // links | ||
| .replace(/!\[(.*?)\]\(.*?\)/g, "$1") // images | ||
| .replace(/`{1,3}.*?`{1,3}/gs, "") // code blocks | ||
| .replace(/^\s*[-*+]\s+/gm, "") // list items | ||
| .replace(/^\s*\d+\.\s+/gm, "") // numbered list items | ||
| .replace(/>\s+/gm, "") // blockquotes | ||
| // remove html tags but keep content | ||
| .replace(/<[^>]*>/g, "") |
Check failure
Code scanning / CodeQL
Incomplete multi-character sanitization High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 13 days ago
In general, to fix incomplete multi-character sanitization you either (1) delegate to a robust sanitization/escape library, or (2) ensure your transformation cannot reintroduce unsafe sequences by repeatedly applying it or simplifying the pattern to operate on single characters instead of whole constructs. Here, stripMarkdown is intended to return plain text, not HTML, so the simplest and safest fix is to make sure that no raw < or > characters remain that could be interpreted as HTML, regardless of whether they look like complete tags.
The single best fix, without changing existing visible functionality in benign cases, is to strengthen the HTML-removal step. Instead of only removing <...> patterns, we can remove all < and > characters after we’ve done the markdown stripping. This aligns with the examples in the background where rewriting the regex to match single characters /<|>/g avoids multi-character pitfalls. Concretely, in src/utils/markdown.jsx we will replace the .replace(/<[^>]*>/g, "") step and its comment with a more robust approach that strips both angle brackets. Since we are only allowed to modify shown code and not change imports, we won’t introduce an external sanitizer; we’ll just adjust the regex.
Specifically, within stripMarkdown we will: (1) update the HTML-related comment to reflect that we now remove angle brackets rather than attempt to preserve tag content; and (2) change the regex on line 22 from /<[^>]*>/g to /<|>/g. No new methods or imports are required.
| @@ -18,8 +18,8 @@ | ||
| .replace(/^\s*[-*+]\s+/gm, "") // list items | ||
| .replace(/^\s*\d+\.\s+/gm, "") // numbered list items | ||
| .replace(/>\s+/gm, "") // blockquotes | ||
| // remove html tags but keep content | ||
| .replace(/<[^>]*>/g, "") | ||
| // remove angle brackets to avoid residual HTML-like fragments | ||
| .replace(/<|>/g, "") | ||
| // remove more than 2 consecutive newlines | ||
| .replace(/\n{3,}/g, "\n\n") | ||
| .trim(); |
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Adds Markdown/MDX-based rendering and editing for club/event descriptions (and changelog content), plus a utility to derive plain-text descriptions for metadata and exports.
Changes:
- Introduces a server-side
MarkdownRendererusingnext-mdx-remote-client/rscwith GFM + emoji/emoticon support. - Adds a client-side Markdown editor modal powered by
@mdxeditor/editor, integrated into Club/Event forms. - Uses
stripMarkdownfor metadata and some export surfaces (calendar, PDF/DOCX) to avoid raw markdown in plain-text contexts.
Reviewed changes
Copilot reviewed 18 out of 19 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/markdown.jsx | Adds stripMarkdown helper for producing plain text from markdown. |
| src/components/markdown/MarkdownRenderer.jsx | New shared Markdown renderer (MDX evaluate + remark plugins). |
| src/components/markdown/MarkdownEditorModal.jsx | New modal wrapper for the editor (client-only). |
| src/components/markdown/MDXEditorComponent.jsx | MDXEditor configuration/plugins + styles. |
| src/components/events/report/EventpdfDownloads.jsx | Uses stripMarkdown for event description in PDF HTML output. |
| src/components/events/report/EventDocxDownloads.jsx | Uses stripMarkdown for budget item descriptions in DOCX. |
| src/components/events/EventForm.jsx | Replaces inline description editing with modal markdown editor. |
| src/components/events/EventDetails.jsx | Renders event description via MarkdownRenderer. |
| src/components/events/AddToCalendarBtn.jsx | Uses stripMarkdown for calendar description. |
| src/components/clubs/ClubInfo.jsx | Allows passing rendered JSX description (e.g., MarkdownRenderer output). |
| src/components/clubs/ClubForm.jsx | Replaces inline description editing with modal markdown editor. |
| src/app/student-bodies/[id]/page.jsx | Uses stripMarkdown for metadata description. |
| src/app/manage/events/[id]/page.jsx | Uses stripMarkdown for metadata description. |
| src/app/manage/clubs/[id]/page.jsx | Renders club description via MarkdownRenderer. |
| src/app/events/[id]/page.jsx | Uses stripMarkdown for metadata description. |
| src/app/clubs/[id]/page.jsx | Uses stripMarkdown for metadata; renders description via MarkdownRenderer. |
| src/app/changelog/page.jsx | Switches changelog rendering to shared MarkdownRenderer. |
| package.json | Adds editor + remark plugins dependencies. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <td>${ | ||
| (item?.description | ||
| ? item?.description.replace(/\n/g, "<br />") | ||
| : null) || "Unknown" | ||
| item?.description | ||
| ? item.description.replace(/\n/g, "<br />") | ||
| : "Unknown" | ||
| }</td> |
There was a problem hiding this comment.
Same issue as earlier budget table: item.description is interpolated into the HTML without markdown stripping/escaping. This can break the generated PDF HTML (and potentially allow unwanted tags/URLs). Consider running stripMarkdown (and/or HTML-escaping) on these item descriptions before inserting them.
| const [contentState, setContentState] = useState(content); | ||
|
|
||
| const handleSave = () => { | ||
| onSave(content); |
There was a problem hiding this comment.
handleSave is saving the original content prop instead of the edited contentState, so changes made in the editor won't be persisted. Use the current state value when calling onSave (and consider trimming there if needed).
| onSave(content); | |
| const trimmedContent = | |
| typeof contentState === "string" ? contentState.trim() : contentState; | |
| onSave(trimmedContent); |
| mdxOptions: { | ||
| disableImports: true, | ||
| disableExports: true, | ||
| remarkPlugins: [ | ||
| remarkMdxRemoveExpressions, | ||
| remarkGfm, | ||
| [remarkEmoji, { emoticon: true }], | ||
| ], | ||
| }, |
There was a problem hiding this comment.
The current MDX/Markdown pipeline doesn’t sanitize links or raw HTML. With remarkGfm, inputs like [x](javascript:alert(1)) will render an <a href="javascript:...">, and MDX can also embed raw tags; remark-mdx-remove-expressions won’t prevent these. Add a sanitization step (e.g., rehype-sanitize with a strict schema / allowed protocols, and/or a custom link component that blocks javascript:/data: URLs) before rendering user-provided content.
| item?.description?.replace(/\n/g, "<br />") || | ||
| "Unknown" | ||
| item?.description | ||
| ? item.description.replace(/\n/g, "<br />") |
There was a problem hiding this comment.
Budget item descriptions are interpolated into an HTML string without stripping markdown/HTML (only newlines are converted). Since stripMarkdown is already used for the main event description in this template, apply the same sanitization/escaping to item.description here to avoid HTML injection/broken PDF output and keep formatting consistent.
| ? item.description.replace(/\n/g, "<br />") | |
| ? stripMarkdown(item.description).replace( | |
| /\n/g, | |
| "<br />", | |
| ) |
Club & Event Descriptions
Supports GFM (github flavoured markdown), emoji codes & emoticons.
Strips away any unwanted JS calls for security