Xterm.js: Supporte l'hyperlien ansi s'échappe

Créé le 28 nov. 2017  ·  29Commentaires  ·  Source: xtermjs/xterm.js

Les émulateurs de terminaux commencent à prendre en charge les hyperliens . Alors que de nombreux terminaux ont depuis longtemps détecté des URL et les ont liées, vous permettant de faire un clic ou un contrôle-clic dessus pour ouvrir un navigateur, vous avez été obligé d'imprimer les longues URL disgracieuses à l'écran. Au printemps 2017, quelques terminaux ont commencé à prendre en charge les liens de type HTML, où le texte du lien et la destination pouvaient être spécifiés séparément.

Exemple d'iTerm2 3.1:
screen shot 2017-11-28 at 12 08 20

areapi arelinks help wanted typenhancement

Commentaire le plus utile

iTerm2 affiche l'URL comme ceci:

screen shot 2017-11-28 at 14 50 20

Ceci est également similaire à la façon dont Chrome affiche l'URL lorsque vous survolez des liens.

Tous les 29 commentaires

Bonne idée, PR bienvenue!

Cela pourrait devenir un standard et faciliter l'analyse.
Problème lié: https://github.com/xtermjs/xterm.js/issues/583

Le plus grand avantage est que nous pouvons lier du texte sans avoir à spammer le terminal avec une longue URL. Par exemple, on pourrait créer un lien vers la documentation dans des messages d'erreur sans la rendre super verbeuse.

Cela doit être mis en œuvre avec précaution, vous devez pouvoir survoler le lien pour voir où il mène, sinon vous pourriez relier les utilisateurs sans le savoir à des sites malveillants. C'est déjà un énorme problème de phishing par e-mail.

Par exemple, vous pouvez créer un lien qui avait le titre "login.facebook.com" mais en fait le lier à login.faceboook.com, en ayant une page qui ressemble exactement à la même chose, mais en enregistrant le mot de passe des utilisateurs lors de la connexion.

iTerm2 affiche l'URL comme ceci:

screen shot 2017-11-28 at 14 50 20

Ceci est également similaire à la façon dont Chrome affiche l'URL lorsque vous survolez des liens.

Si / quand cela est implémenté, veuillez soumettre un problème ou un PR à supports-hyperlinks , qui est destiné à détecter la prise en charge de cette fonctionnalité.

@jamestalmage cela devra probablement être laissé aux intégrateurs de xterm.js, pour le moment, l'environnement appartient aux émulateurs de terminaux qui utilisent xterm.js. Par exemple, Hyper et VS Code sont chacun définis individuellement TERM_PROGRAM .

@Tyriar - Dans ce cas, peut-être simplement inclure une référence à supports-hyperlinks dans le commit qui aboutit à cela, et dans les notes de publication quand cela va au loin. Je ne sais pas s'il existe des équivalents supports-hyperlinks pour d'autres langues, mais si c'est le cas, cela vaut probablement la peine de les mentionner également.

J'ai une implémentation de preuve de concept:

links.txt

Il y a un problème fondamental en ce que ces liens ne sont pas stockés dans le tampon de manière réelle, donc ils disparaissent si la fenêtre est redimensionnée. Au lieu de cela, les informations de lien sont stockées dans le MouseZoneManager qui est effacé par _mouseZoneManager.clearAll .

Je crois qu'un vrai correctif doit attendre que la réimplémentation de Buffer soit terminée. Nous avons besoin d'un mécanisme pour annoter les cellules et / ou les plages de cellules, qui est stable lors du redimensionnement.

(Ou peut-être que je manque juste quelque chose, étant nouveau dans cette base de code.)

Je crois qu'un vrai correctif doit attendre que la réimplémentation de Buffer soit terminée. Nous avons besoin d'un mécanisme pour annoter les cellules et / ou les plages de cellules, qui est stable lors du redimensionnement.

@PerBothner ouais vous avez probablement raison. Une autre chose à laquelle nous devons penser avant que cela ne soit expédiable est de savoir comment l'URL sous-jacente est exposée à partir de xterm.js afin que les intégrateurs puissent l'afficher dans l'interface utilisateur. Nous voudrions probablement aussi le désactiver par défaut pour des raisons de sécurité (puisque l'URL ne serait pas surfacée par défaut).

J'ai mis à jour mon patch et l'ai poussé dans une branche: https://github.com/PerBothner/xterm.js/tree/hyperlinks

Pas prêt pour une pull request, cependant - divers problèmes mentionnés précédemment n'ont pas été résolus.

Proposition pour l'API d'utiliser ceci:

export class Terminal {
    /**
     * Adds a handler for the ANSI hyperlink escape `\x1b]8;;url\alabel\x1b]8;;`, you should use
     * this API to display the full URL to the user. Note that ANSI hyperlinks will only work if
     * there is a handler for security reasons.
     * <strong i="6">@param</strong> onHover The callback that fires when the mouse enters a link's zone.
     * <strong i="7">@param</strong> onLeave The callback that fires when the mouse leaves a link's zone.
     * <strong i="8">@return</strong> An IDisposable which can be used to disable the handler.
     */
    addAnsiHyperlinkHandler(onHover: (event: MouseEvent, url: string) => void, onLeave: () => void): IDisposable;
}

@mofux @jerch des commentaires sur la forme de l'API? Je ne trouve pas que ce fil parle de la forme de ceux-ci, mais peut-être que cela devrait être set au lieu de add car cela n'a de sens que d'avoir 1.

Il peut également être préférable d'utiliser quelque chose comme ILinkHoverEvent :

interface ILinkHoverEvent {
  // Maybe the cell the mouse is under is also needed?
  x1: number;
  y1: number;
  x2: number;
  y2: number;
  url: string;
}

export class Terminal {
    addAnsiHyperlinkHandler(onHover: (event: ILinkHoverEvent) => void, onLeave: () => void): IDisposable;
}

Une autre alternative:

interface ILinkHoverEvent {
  linkStart: Cell;
  linkEnd: Cell;
  mousePosition: Cell;
  url: string
}

@Tyriar IMO cela n'a pas beaucoup de sens de créer un gestionnaire séparé pour cela. Le consommateur probable de cette API serait notre moteur de rendu qui restitue l'URL dans une info-bulle si nous survolons le texte lié, n'est-ce pas? Il serait peut-être logique d'étendre notre linkifier avec les hooks susmentionnés pour onLinkHover et onLinkLeave , et de gérer ces hyperliens ansi comme nous le faisons avec les liens Web en ce moment?

Le consommateur probable de cette API serait notre moteur de rendu qui restitue l'URL dans une info-bulle

@mofux Je pensais plus comme l'addon de recherche, l'embedder fournit l'interface utilisateur dans le style qu'ils veulent, nous fournissons juste les rappels pour le faire. Bon point que cela ne vous permet pas encore de gérer les choses. Je suppose que fusionner avec l'API de lien existante et avoir un paramètre ITerminalOptions.enableAnsiHyperlinks pour l'opt-in et détaille le pourquoi?

Je suppose que fusionner avec l'API de lien existante et avoir un paramètre ITerminalOptions.enableAnsiHyperlinks pour l'opt-in et détaille le pourquoi?

Quelle serait l'histoire pour les intégrateurs de prendre en charge cette fonctionnalité? Ouvrir le lien (invisible) en cliquant sur le texte lié est potentiellement dangereux - surtout si nous ne montrons l'URL liée nulle part 🤔

Bien que montrer la cible à l'avance soit vraiment agréable, je ne pense pas qu'il y ait de problème pour ouvrir des URL "inconnues". Les aspects de sécurité ont été discutés dans les commentaires sous les spécifications. Les navigateurs ouvrent des URL "inconnues" tout le temps, par exemple quand il y a un code JS qui modifie la cible juste avant de l'ouvrir, souvent pour montrer une "belle" URL à l'utilisateur, mais l'ouvrent en fait via un redirecteur.

En parlant de ça ... quelque chose qui ne m'est pas venu à l'esprit jusqu'à présent ...

Si xterm.js s'exécute dans un navigateur réel et ouvre le lien dans, disons, un nouvel onglet de ce navigateur: je suppose que la fuite de l'URL de xterm.js via le champ Referer est quelque chose à craindre. Je ne suis pas sûr du support actuel de rel = "noreferrer", mais semble être quelque chose qui devrait être utilisé.

Voir cette discussion connexe sur le texte de MouseZoneManager .

Avons-nous des experts XSS qui traînent? Peut-être avons-nous besoin d'un audit, lol.

Pour mes connaissances limitées sur la sécurité du navigateur, le principal vecteur d'attaque avec xterm.js est les données traversant la frontière terminal / navigateur:

  • XSS du navigateur (JS) dans le terminal (données)
    C'est déjà possible et sous la responsabilité de l'intégrateur (xterm.js ne peut en aucun cas contrôler cela). Règle générale - n'importez jamais de scripts à partir d'une source non fiable sur la page du terminal ou sur le pty websocket et ainsi le système qui héberge le pty est perdu. N'autorisez pas l'insertion de contenu utilisateur non filtré dans la page et autres - en gros, toutes les choses XSS typiques, ou le pty est perdu.
  • XSS du terminal (données) dans le navigateur (JS)
    C'est une nouvelle qualité que nous pourrions entrer avec les URL, si nous ne nous assurons pas que les données du terminal n'atteindront jamais le contexte JS de la page d'intégration (donc l'objet terminal lui-même). Si cela est possible (supposons que pendant une seconde) un attaquant peut accéder à la page du navigateur, et ainsi effectuer une attaque terminal (données) - navigateur (JS) - terminal (données). Supposons en outre que xterm.js s'exécute beaucoup dans les portails de services d'orchestration du cloud et que l'administrateur utilise des sessions de terminal sur différentes machines. Outch. Une fois que l'attaquant a accédé à la page d'intégration du navigateur, tous les services cloud auxquels l'administrateur a accès sont en danger.

La question est - y a-t-il des possibilités de franchir la frontière terminal (données) - navigateur (JS) avec les URL? Encore une fois, ma connaissance limitée de la sécurité du navigateur n'aide pas beaucoup ici. Le seul scénario auquel je peux penser sont des bookmarklets qui s'injectent dans le JS de la page. Je n'ai aucune idée si nous pouvons éviter cela en ouvrant toujours des éléments dans une nouvelle fenêtre / onglet uniquement (je suppose que la session continuera de fuir, sinon httpSeulement? Et la connexion websocket?) Ce qui me fait penser que nous devons analyser l'URL et dépouiller tout "contenu à la recherche de JS", oh cher ...

Edit: Notez que les websockets manquent la plupart des paramètres de sécurité du navigateur, ils n'ont même pas une vérification fiable de la même origine (optez pour une longue interrogation ajax si vous avez besoin de ce lol). Hum ...

les bookmarklets [...] suppriment tout "contenu JS"

Je pense que c'est une bonne idée de mettre sur liste blanche uniquement les URL commençant par "http: //", "https: //", peut-être "ftp: //" et de rejeter toute autre chose. Ou à tout le moins sur liste noire l'absence de schéma ainsi que "javascript:".

Dans ma branche hyperliens, j'ai ajouté un patch https://github.com/PerBothner/xterm.js/commit/b2647b90d301c52229d01720800865a0d39f436f pour une fonction de rappel réglable en un clic. Cela permet de changer la façon dont le lien est géré. Par exemple, lorsque DomTerm est configuré pour utiliser ma branche xterm.js après ls --hyperlink=auto cliquetis sur la plupart des noms de fichiers, le fichier ouvrira dans emacs, mais les fichiers html ouvriront le fichier dans votre navigateur par défaut, en fonction de vos paramètres .

(Attention, il y a des flocons dans le prototype. Je ne sais pas si c'est spécifique au prototype DomTerm.)

Les navigateurs ouvrent des URL "inconnues" tout le temps, par exemple quand il y a un code JS qui modifie la cible juste avant de l'ouvrir, souvent pour montrer une "belle" URL à l'utilisateur, mais l'ouvrent en fait via un redirecteur.

@egmontkob dans les navigateurs, vous commencez généralement par un endroit sûr, comme un moteur de recherche qui vous indique très clairement quand le domaine est. Pour les terminaux, vous devrez faire confiance aux programmes (dont certains peuvent imprimer du contenu distant), même la capture d'un fichier pourrait afficher un lien malveillant. Il semble qu'il serait préférable d'être sécurisé par défaut et d'avoir un paramètre qui décrit simplement les risques et offre des atténuations.

Dans ma branche hyperliens j'ai ajouté un patch PerBothner @ b2647b9 pour une fonction de rappel paramétrable en un clic.

@PerBothner il y a déjà un gestionnaire ici dans l'addon webLinks: https://github.com/xtermjs/xterm.js/blob/509ce5fa3a698ee7847419117e9dd6b979b105bf/src/addons/webLinks/webLinks.ts#Lgly a besoin de bit configurer 2 gestionnaires de liens Web différents.

(Désolé pour la réponse tardive - j'ai été écarté.)

@Tyriar a écrit "il y a déjà un gestionnaire ici dans l'addon webLinks". Le problème est que webLinksInit crée un ILinkMatcher et associe le gestionnaire donné à un ILinkMatcher spécifique, qui contient un ensemble d'expressions régulières avec lesquelles correspondre. Mais comment spécifier le gestionnaire de liens pour les hyperliens créés par une séquence d'échappement et ne sont donc

Il me semble que nous avons besoin d'un champ linkHandler dans le terminal - avoir un champ handler dans le ILinkMatcher ne suffit pas. Et si nous avons un champ linkHandler dans Terminal il est logique que ce gestionnaire soit le gestionnaire par défaut utilisé par registerLinkMatcher. C'est ce que fait mon patch.

Si quelqu'un veut vous aider, voici ce qui doit se passer:

  • Déterminez comment gérer les implications de sécurité liées au fait que les liens ne s'affichent pas en tant qu'URL, c'est probablement pour activer la fonctionnalité et exposer un hook afin que les consommateurs puissent afficher un popup
  • Trouvez une belle API pour ouvrir un lien, nous avons déjà quelque chose de très similaire avec l'API Link Matcher, cela peut-il être généralisé?
  • Ajoutez la logique à l'analyseur et stockez les liens quelque part, peut-être sous la forme IMarker s?

Ma branche d'hyperliens https://github.com/PerBothner/xterm.js/tree/hyperlinks peut être un point de départ. (Bien qu'il soit un peu vieux, il ne fonctionnera peut-être plus.)

Quel est le statut de la branche ci-dessus? Quelqu'un travaille-t-il là-dessus?
@Tyriar a bien répertorié les étapes nécessaires. L'une de ces étapes est-elle terminée?

@ Jma353 Je ne pense pas que quiconque travaille activement à cela, alors n'hésitez pas à implémenter les bits nécessaires.

@Tyriar Je n'ai pas lu la spécification dans tous les détails, mais il semble que sa mise en œuvre impliquerait de jongler avec un gestionnaire d'analyseur, en particulier. quelque chose comme une surcharge temporaire InputHandler.print . Un peu bizarre que cela soit fait comme ça (cela tire un peu l'état terminal dans l'analyseur, un fait qu'aucune autre séquence d'échappement ne le fait jusqu'à présent), mais cela devrait être faisable en remplaçant le gestionnaire d'impression entre les deux.

@jerch ouais il aurait besoin de quelques changements d'analyseur. Le redimensionnement des liens encapsulés est un cas dont nous aurions besoin pour nous assurer qu'ils fonctionnent également.

VS Code prend désormais en charge l'affichage des survols détaillés des liens, donc le fait de connecter cela à cela résoudra le problème:

image

C'est dommage que ce soit des séquences un peu bizarres car nos crochets d'analyseur ne le couvrent pas. S'ils le faisaient, cela pourrait être fait entièrement en tant qu'addon en utilisant des crochets d'analyseur, des marqueurs et les API du fournisseur de liens.

@Tyriar De plus, avec # 2751, le stockage attr étendu peut être utilisé pour annoter des éléments d'URL dans les cellules tampons.

C'est dommage que ce soit des séquences un peu bizarres car nos crochets d'analyseur ne le couvrent pas. S'ils le faisaient, cela pourrait être fait entièrement en tant qu'addon en utilisant des crochets d'analyseur, des marqueurs et les API du fournisseur de liens.

Ouais c'est un problème et à mon humble avis ne peut pas être résolu au niveau de l'addon, même si nous exposerions un hook de gestionnaire d'impression. Je pense que cela doit aller directement dans la base de code plus quelques conditions exceptionnelles (comme toute action non imprimée avant que le finaliseur ne soit reconnu, devrait casser le marquage URL des cellules et autres).

Cette page vous a été utile?
0 / 5 - 0 notes