-
Notifications
You must be signed in to change notification settings - Fork 280
chore: improve LK UI #295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
chore: improve LK UI #295
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
e7f34a2 to
9fd6637
Compare
90764e4 to
4ae8727
Compare
4ae8727 to
210591c
Compare
7835efb to
ec1479e
Compare
6df4f89 to
49e898e
Compare
1c3ffc3 to
7e5f614
Compare
ced8a7a to
cf3b619
Compare
cf3b619 to
d4247ed
Compare
d4247ed to
058c43e
Compare
058c43e to
81cd4bf
Compare
tweak jelly
4f9c2f7 to
cb4933e
Compare
cb4933e to
ea71b77
Compare
70eaa94 to
cd54234
Compare
| .sort((a, b) => a.localeCompare(b)) | ||
| .map((componentName) => ( | ||
| <Link | ||
| href={`/ui/components/${componentName}`} |
Check failure
Code scanning / CodeQL
Stored cross-site scripting High
stored value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 8 days ago
The best fix is to ensure that only valid, expected component names are used, and that they are sanitized before inclusion in URLs and as visible text. Specifically:
- Only allow component names that match safe slug/identifier patterns (e.g., only letters, numbers, hyphens, and underscores).
- Filter out unsafe component names when listing them.
- Sanitize each component name before creating the URL and rendering the link text.
A robust approach is to update getComponentNames() in lib/components.tsx so it only returns component names that match a safe pattern (e.g., /^[a-zA-Z0-9_-]+$/).
Make the change directly in lib/components.tsx.
No changes are needed in app/ui/components/page.tsx, as the source of truth will now be validated and only return safe values.
-
Copy modified lines R9-R11
| @@ -6,5 +6,7 @@ | ||
| const componentNames = fs.readdirSync(componentsDir); | ||
| return componentNames | ||
| .filter((file) => file.endsWith('.tsx')) | ||
| .map((file) => file.replace('.tsx', '')); | ||
| .map((file) => file.replace('.tsx', '')) | ||
| // Only allow component names containing [A-Za-z0-9_-] | ||
| .filter((name) => /^[a-zA-Z0-9_-]+$/.test(name)); | ||
| } |
| .map((componentName) => ( | ||
| <Link | ||
| href={`/ui/components/${componentName}`} | ||
| key={componentName} |
Check failure
Code scanning / CodeQL
Stored cross-site scripting High
stored value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 8 days ago
The best way to fix the problem is to ensure that all untrusted inputs rendered in the URL context are safely encoded. Specifically, when constructing the href for <Link>, componentName must be passed through encodeURIComponent() to prevent injection of slashes or special characters that could break the URL structure or enable attacks. Also, as a defense-in-depth, if rendering as HTML or if file names might contain suspicious Unicode, one could further escape text using a utility like escape-html, but in this case, React’s default escaping suffices for element children.
Files to change:
- app/ui/components/page.tsx:
Change{/ui/components/${componentName}}to{/ui/components/${encodeURIComponent(componentName)}}in thehrefprop.
ImportencodeURIComponentis not required since it is a global function.
No code changes necessary in lib/components.tsx because filtering occurs after file reading, but does not ensure file name “safety” -- the only thing needed is output encoding as above.
-
Copy modified line R21
| @@ -18,7 +18,7 @@ | ||
| .sort((a, b) => a.localeCompare(b)) | ||
| .map((componentName) => ( | ||
| <Link | ||
| href={`/ui/components/${componentName}`} | ||
| href={`/ui/components/${encodeURIComponent(componentName)}`} | ||
| key={componentName} | ||
| className="font-semibold underline-offset-4 hover:underline focus:underline" | ||
| > |
| .sort((a, b) => a.localeCompare(b)) | ||
| .map((componentName) => ( | ||
| <Link | ||
| href={`/ui/components/${componentName}`} |
Check failure
Code scanning / CodeQL
Stored cross-site scripting High documentation
stored value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 8 days ago
The best fix is to sanitize each value from componentNames before using it in any URL (such as the href prop of a Link). The most robust approach, without changing the data source, is to encode or restrict componentName so it cannot be interpreted as anything but a safe path segment. In this context, the standard method is to apply encodeURIComponent() to componentName when constructing URLs. This both prevents breaking out of the path context and blocks attempts to inject scripts via the href attribute.
Apply this change only within components/docs/side-nav.tsx, ensuring minimal impact and no loss of existing functionality. You only need to wrap componentName with encodeURIComponent in the relevant href construction, and can do this inline without additional dependencies.
-
Copy modified line R33
| @@ -30,7 +30,7 @@ | ||
| .sort((a, b) => a.localeCompare(b)) | ||
| .map((componentName) => ( | ||
| <Link | ||
| href={`/ui/components/${componentName}`} | ||
| href={`/ui/components/${encodeURIComponent(componentName)}`} | ||
| key={componentName} | ||
| className={cn( | ||
| 'text-sm font-semibold underline-offset-4 hover:underline focus:underline', |
| .map((componentName) => ( | ||
| <Link | ||
| href={`/ui/components/${componentName}`} | ||
| key={componentName} |
Check failure
Code scanning / CodeQL
Stored cross-site scripting High documentation
stored value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 8 days ago
To fix this issue, all component names (derived directly from file names via fs.readdirSync) should be sanitized to ensure that they do not contain dangerous or malformed characters before being used as React keys, display text, and URL path segments. The best approach is to explicitly restrict componentNames to a safe set of characters — e.g., alphanumeric characters, hyphens, and underscores only. This prevents injection attacks and also guards against weird edge cases (e.g., /, ., &, etc.).
The fix should be applied in the getComponentNames function in lib/components.tsx, where file names are first collected and transformed. We will add a filter that only allows component names that match a safe regular expression, e.g., /^[a-zA-Z0-9-_]+$/. This will ensure downstream consumers of the componentNames array will never see untrusted or dangerous values. Alternatively, for even stronger guarantees (if you need to retain more flexibility), encode the names as needed before using them, but filtering at the source is the safest.
No additional npm dependencies are needed, as JavaScript RegExp and array methods suffice.
-
Copy modified lines R9-R10
| @@ -6,5 +6,6 @@ | ||
| const componentNames = fs.readdirSync(componentsDir); | ||
| return componentNames | ||
| .filter((file) => file.endsWith('.tsx')) | ||
| .map((file) => file.replace('.tsx', '')); | ||
| .map((file) => file.replace('.tsx', '')) | ||
| .filter((name) => /^[a-zA-Z0-9_-]+$/.test(name)); | ||
| } |
1f0e02d to
319cd40
Compare
4a36ba0 to
5a2abe6
Compare
5a2abe6 to
e007697
Compare
https://sandbox-voice-assistant-git-ty-visualizer.staging.livekit.io/ui/components/AudioBarVisualizer
https://sandbox-voice-assistant-git-ty-visualizer.staging.livekit.io/ui/components/AudioGridVisualizer
https://sandbox-voice-assistant-git-ty-visualizer.staging.livekit.io/ui/components/AudioRadialVisualizer
https://sandbox-voice-assistant-git-ty-visualizer.staging.livekit.io/ui/components/AudioShaderVisualizer
https://sandbox-voice-assistant-git-ty-visualizer.staging.livekit.io/ui/components/AudioOscilloscopeVisualizer