security: implement deceptive URL detection and Punycode disclosure#19287
security: implement deceptive URL detection and Punycode disclosure#19287ehedlund wants to merge 4 commits intogoogle-gemini:mainfrom
Conversation
Summary of ChangesHello @ehedlund, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly bolsters the security of tool confirmations by introducing comprehensive mechanisms to detect and clearly disclose deceptive URLs, protecting users from homograph attacks. It ensures that potentially malicious links are highlighted with their true Punycode form, while also improving the general readability of legitimate Unicode URLs. Additionally, the changes enhance command clarity by adding source labels to descriptions, providing users with better context about where commands originate. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a valuable security feature to detect and warn about deceptive URLs (homograph attacks) in tool confirmations, enhancing user safety. The implementation includes a new utility for URL analysis, integrates warnings into the UI, and correctly adjusts the layout to accommodate these warnings. The PR also refactors command loading to include source labels in descriptions. My review focuses on the completeness of the new security feature. I've identified that the URL scanning is not applied to all relevant confirmation types, which could leave some attack vectors open. The suggestion to extend the scanning to edit and ask_user confirmations for more robust protection aligns with the principle of treating all external data as untrusted and applying validation at the point of use.
| const deceptiveUrlWarnings = useMemo(() => { | ||
| const urls: string[] = []; | ||
| if (confirmationDetails.type === 'info' && confirmationDetails.urls) { | ||
| urls.push(...confirmationDetails.urls); | ||
| } else if (confirmationDetails.type === 'exec') { | ||
| const commands = | ||
| confirmationDetails.commands && confirmationDetails.commands.length > 0 | ||
| ? confirmationDetails.commands | ||
| : [confirmationDetails.command]; | ||
| for (const cmd of commands) { | ||
| const matches = cmd.match(/https?:\/\/[^\s"'`<>]+/g); | ||
| if (matches) urls.push(...matches); | ||
| } | ||
| } | ||
|
|
||
| const uniqueUrls = Array.from(new Set(urls)); | ||
| return uniqueUrls | ||
| .map(getDeceptiveUrlDetails) | ||
| .filter((d): d is DeceptiveUrlDetails => d !== null); | ||
| }, [confirmationDetails]); |
There was a problem hiding this comment.
The deceptive URL detection currently only covers info and exec confirmation types. However, other types like edit and ask_user can also display model-generated content that might contain deceptive URLs (e.g., in a file diff or a user prompt). To ensure comprehensive security, the detection should be extended to these types as well.
const deceptiveUrlWarnings = useMemo(() => {
const URL_REGEX = /https?:\/\/[^\s"'`<>]+/g;
const urls: string[] = [];
if (confirmationDetails.type === 'info' && confirmationDetails.urls) {
urls.push(...confirmationDetails.urls);
} else if (confirmationDetails.type === 'exec') {
const commands =
confirmationDetails.commands && confirmationDetails.commands.length > 0
? confirmationDetails.commands
: [confirmationDetails.command];
for (const cmd of commands) {
const matches = cmd.match(URL_REGEX);
if (matches) urls.push(...matches);
}
} else if (
confirmationDetails.type === 'edit' &&
confirmationDetails.fileDiff
) {
const matches = confirmationDetails.fileDiff.match(URL_REGEX);
if (matches) urls.push(...matches);
} else if (
confirmationDetails.type === 'ask_user' &&
confirmationDetails.questions
) {
for (const q of confirmationDetails.questions) {
const matches = q.question.match(URL_REGEX);
if (matches) urls.push(...matches);
}
}
const uniqueUrls = Array.from(new Set(urls));
return uniqueUrls
.map(getDeceptiveUrlDetails)
.filter((d): d is DeceptiveUrlDetails => d !== null);
}, [confirmationDetails]);
References
- This suggestion aligns with the principle of defense-in-depth by treating model-generated content and user prompts as untrusted data, requiring proper validation (deceptive URL detection) at the point of use, even if it's believed to be filtered upstream.
|
Closing in favor of #19288 which is based on main and excludes unrelated commits. |
Summary
This PR implements security protections against deceptive URLs (homograph attacks) in tool confirmations.
Details
urlSecurityUtils.tsprovidingisDeceptiveUrlandgetDeceptiveUrlDetailsusing WHATWG URL parsing.ToolConfirmationMessage.tsxthat reveals the Punycode (actual) identity of suspicious URLs.calculateWrappedHeightto ensure security warnings are always fully visible and correctly sized within the confirmation dialog.Related Issues
Addresses URL security and homograph protection.
How to Validate
npm test -w @google/gemini-cli -- src/ui/utils/urlSecurityUtils.test.tsnpm test -w @google/gemini-cli -- src/ui/components/messages/ToolConfirmationMessage.test.tsx