Xterm.js: Поддержка переходов по гиперссылкам

Созданный на 28 нояб. 2017  ·  29Комментарии  ·  Источник: xtermjs/xterm.js

Эмуляторы терминала начинают поддерживать гиперссылки . Хотя многие терминалы уже давно обнаруживают URL-адреса и связывают их, позволяя вам щелкнуть их, удерживая Command или Control, чтобы открыть браузер, вы были вынуждены печатать длинные неприглядные URL-адреса на экране. С весны 2017 года несколько терминалов начали поддерживать HTML-подобные ссылки, где текст ссылки и место назначения можно было указывать отдельно.

Пример из iTerm2 3.1:
screen shot 2017-11-28 at 12 08 20

areapi arelinks help wanted typenhancement

Самый полезный комментарий

iTerm2 показывает URL-адрес следующим образом:

screen shot 2017-11-28 at 14 50 20

Это также похоже на то, как Chrome показывает URL-адрес при наведении курсора на ссылки.

Все 29 Комментарий

Хорошая идея, пиар приветствуется!

Это может стать стандартом и упростить синтаксический анализ.
Связанная проблема: https://github.com/xtermjs/xterm.js/issues/583

Самым большим преимуществом является то, что мы можем связать текст без необходимости спамить терминал длинным URL-адресом. Например, можно ссылаться на документацию в сообщениях об ошибках, не делая их слишком подробными.

Это должно быть реализовано с осторожностью, вы должны иметь возможность навести ссылку, чтобы увидеть, куда она ведет, иначе вы можете бессознательно связывать пользователей с вредоносными сайтами. Это уже серьезная проблема электронного фишинга.

Например, вы можете создать ссылку с заголовком «login.facebook.com», но фактически связать ее с login.faceboook.com, имея страницу, которая выглядит точно так же, но сохраняет пароль пользователя при входе в систему.

iTerm2 показывает URL-адрес следующим образом:

screen shot 2017-11-28 at 14 50 20

Это также похоже на то, как Chrome показывает URL-адрес при наведении курсора на ссылки.

Если / когда это будет реализовано, отправьте сообщение о проблеме или PR в supports-hyperlinks , которое предназначено для обнаружения поддержки этой возможности.

@jamestalmage, это, вероятно, нужно оставить на усмотрение разработчиков xterm.js, прямо сейчас окружение принадлежит эмуляторам терминала, которые используют xterm.js. Например, Hyper и VS Code индивидуально устанавливают TERM_PROGRAM .

@Tyriar - в этом случае, возможно, просто supports-hyperlinks в коммит, который вызывает это, и в примечания к выпуску, когда он расширяется. Я не уверен, есть ли эквиваленты supports-hyperlinks для других языков, но если да, то, вероятно, стоит упомянуть и о них.

У меня есть экспериментальная реализация:

links.txt

Существует фундаментальная проблема в том, что эти ссылки никаким образом не сохраняются в буфере, поэтому они исчезают при изменении размера окна. Вместо этого информация о ссылке хранится в MouseZoneManager который очищается _mouseZoneManager.clearAll .

Я считаю, что настоящее исправление должно подождать, пока не будет выполнена повторная реализация буфера. Нам нужен механизм аннотирования ячеек и / или диапазонов ячеек, который будет стабильным при изменении размера.

(Или, может быть, я просто что-то упускаю из-за того, что новичок в этой кодовой базе.)

Я считаю, что настоящее исправление должно подождать, пока не будет выполнена повторная реализация буфера. Нам нужен механизм аннотирования ячеек и / или диапазонов ячеек, который будет стабильным при изменении размера.

@PerBothner да, наверное, ты прав. Еще одна вещь, о которой нам нужно подумать, прежде чем это будет отправлено, - это как сделать так, чтобы базовый URL-адрес был открыт из xterm.js, чтобы встраивающие устройства могли отображать его в пользовательском интерфейсе. Вероятно, мы также захотим отключить его по умолчанию из соображений безопасности (поскольку URL-адрес не будет отображаться по умолчанию).

Я обновил свой патч и поместил его в ветку: https://github.com/PerBothner/xterm.js/tree/hyperlinks

Однако не готов для запроса на перенос - различные проблемы, упомянутые ранее, не были решены.

Предложение по использованию API:

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 отзывы о форме API? Я не могу найти эту ветку, в которой говорится о их форме, но, возможно, это должно быть set вместо add поскольку имеет смысл иметь только 1.

Также может быть лучше использовать что-то вроде 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;
}

Другая альтернатива:

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

@Tyriar IMO нет смысла создавать для этого отдельный обработчик. Вероятным потребителем этого API будет наш модуль визуализации, который отображает URL-адрес во всплывающей подсказке, если мы наведем курсор на связанный текст, не так ли? Может быть, имеет смысл расширить наш линковщик с помощью вышеупомянутых хуков для onLinkHover и onLinkLeave , и обрабатывать эти гиперссылки ansi, как мы сейчас делаем с веб-ссылками?

Вероятным потребителем этого API будет наш модуль рендеринга, который отображает URL во всплывающей подсказке.

@mofux Я больше думал о поисковом аддоне, ITerminalOptions.enableAnsiHyperlinks для подписки и подробное описание почему?

Я предполагаю, что слияние с существующим API ссылок и настройка ITerminalOptions.enableAnsiHyperlinks для подписки и подробное описание почему?

Какова была бы история поддержки этой функции встраивающими устройствами? Открытие (невидимой) ссылки при нажатии на связанный текст потенциально опасно, особенно если мы нигде не показываем связанный URL 🤔

Хотя показывать цель заранее - это действительно хорошо, я не думаю, что есть проблема с открытием «неизвестных» URL. Аспекты безопасности обсуждались в комментариях под спецификациями. Браузеры открывают «неизвестные» URL-адреса все время, например, когда есть JS-код, который изменяет целевой объект непосредственно перед его открытием, часто для того, чтобы показать пользователю «приятный» URL-адрес, но фактически открывает его через перенаправитель.

Кстати говоря ... кое-что, чего мне пока в голову не приходило ...

Если xterm.js работает в реальном браузере и открывает ссылку, скажем, в новой вкладке этого браузера: я думаю, утечка URL-адреса xterm.js через поле Referer - это то, о чем следует беспокоиться. Не уверен в текущей поддержке rel = "noreferrer", но похоже, что это следует использовать.

См. Это связанное обсуждение текста при MouseZoneManager .

Есть ли у нас какие-нибудь эксперты по XSS? Может нам нужен аудит, лол.

Из-за моих ограниченных знаний о безопасности браузера основной вектор атаки с xterm.js - это данные, пересекающие границу терминала / браузера:

  • XSS из браузера (JS) в терминал (данные)
    Это уже возможно, и, по-моему, интегратор несет ответственность за это (xterm.js не может это контролировать). Практическое правило - никогда не импортируйте сценарии из любого ненадежного источника на странице терминала или веб-сокета pty, и, таким образом, система, на которой размещен pty, будет потеряна. Не разрешайте вставлять нефильтрованный пользовательский контент на страницу и тому подобное - в основном все типичные вещи XSS, иначе элемент будет утерян.
  • XSS из терминала (данные) в браузер (JS)
    Это новое качество, которое мы могли бы ввести с URL-адресами, если не позаботимся о том, чтобы данные терминала никогда не доходили до JS-контекста страницы внедрения (следовательно, до самого терминального объекта). Если это возможно (предположим, что на секунду) злоумышленник может получить доступ к странице браузера и, таким образом, выполнить атаку терминал (данные) - браузер (JS) - терминал (данные). Предположим также, что xterm.js много работает на порталах служб облачной оркестрации, а администратор использует терминальные сеансы для разных машин. Outch. Как только злоумышленник получает доступ к странице встроенного браузера, все облачные сервисы, к которым имеет доступ администратор, оказываются в опасности.

Вопрос в том, есть ли возможность пересечь границу терминала (данных) и браузера (JS) с URL-адресами? Опять же, мои ограниченные знания о безопасности браузера здесь не очень помогают. Единственный сценарий, о котором я могу думать, - это букмарклеты, которые внедряются в JS страницы. Я понятия не имею, сможем ли мы этого избежать, всегда открывая материалы только в новом окне / вкладке (думаю, сеанс все равно будет протекать, если не httpOnly? А как насчет подключения к веб-сокету?) Что заставляет меня думать, что мы должны анализировать URL и удалите любой "JS-контент", о боже ...

Изменить: обратите внимание, что веб-сокеты пропускают большинство настроек безопасности браузера, у них даже нет надежной проверки того же происхождения (используйте длинный опрос ajax, если вам нужен этот lol). Хм ...

букмарклеты [...] удаляют любой "JS-контент"

Я считаю хорошей идеей занести в белый список только те URL, которые начинаются с «http: //», «https: //», возможно, «ftp: //», и отклонить все остальное. Или, по крайней мере, занесите в черный список отсутствие схемы и "javascript:".

В моей ветке гиперссылок я добавил патч https://github.com/PerBothner/xterm.js/commit/b2647b90d301c52229d01720800865a0d39f436f для настраиваемой функции обратного вызова по щелчку. Это позволяет изменить способ обработки ссылки. Например, если DomTerm настроен на использование моей ветки xterm.js после того, как ls --hyperlink=auto щелчок по большинству имен файлов откроет файл в emacs, но файлы html откроют файл в вашем браузере по умолчанию, в зависимости от ваших настроек .

(Имейте в виду, что в прототипе есть некоторая нестабильность. Я не знаю, характерно ли это для прототипа DomTerm.)

Браузеры открывают «неизвестные» URL-адреса все время, например, когда есть JS-код, который изменяет целевой объект непосредственно перед его открытием, часто для того, чтобы показать пользователю «приятный» URL-адрес, но фактически открывает его через перенаправитель.

@egmontkob в браузерах обычно начинается с безопасного места, например из поисковой системы, которая очень четко сообщает вам, где находится домен. Для терминалов вам нужно будет доверять программам (некоторые из которых могут печатать удаленный контент), даже просмотр файла может показать вредоносную ссылку. Похоже, было бы лучше по умолчанию быть в безопасности и иметь параметр, который просто описывает риски и предлагает меры по их устранению.

В моей ветке гиперссылок я добавил патч PerBothner @ b2647b9 для настраиваемой функции обратного вызова по щелчку.

@PerBothner здесь уже есть обработчик в аддоне webLinks: https://github.com/xtermjs/xterm.js/blob/509ce5fa3a698ee7847419117e9dd6b979b105bf/src/addons/webLinks/webLinks. Кажется, что нужно a настроить 2 разных обработчика веб-ссылок.

(Извините за запоздалый ответ - я отвлекся.)

@Tyriar написал: «В аддоне webLinks уже есть обработчик». Проблема в том, что webLinksInit создает ILinkMatcher и связывает данный обработчик с конкретным ILinkMatcher, который содержит набор регулярных выражений для сопоставления. Но как указать обработчик ссылок для гиперссылок, созданных с помощью escape-последовательности и, следовательно, не являющихся результатом совпадения регулярного выражения? Этот обработчик должен быть «глобальным» в том смысле, что он не связан ни с каким ILinkMatcher или регулярным выражением. Установка этого глобального обработчика / обработчика по умолчанию с помощью webLinksInit или Terminal.registerLinkMatcher не работает.

Мне кажется, нам нужно поле linkHandler в Терминале - наличия поля handler в ILinkMatcher недостаточно. И если у нас есть такое, как поле linkHandler в Terminal имеет смысл использовать этот обработчик по умолчанию для registerLinkMatcher. Это то, что делает мой патч.

Если кто-то хочет помочь с этим, вот что должно произойти:

  • Выясните, как бороться с последствиями безопасности, связанными с тем, что ссылки не отображаются как URL-адреса, вероятно, это сделано для того, чтобы функция включилась и выставила крючок, чтобы потребители могли отображать всплывающее окно
  • Придумайте хороший API для открытия ссылки, у нас уже есть что-то очень похожее с API сопоставления ссылок, можно ли это обобщить?
  • Добавьте логику в парсер и где-нибудь сохраните ссылки, может быть, как IMarker s?

Моя ветка гиперссылок https://github.com/PerBothner/xterm.js/tree/hyperlinks может быть отправной точкой. (Хотя он немного устарел, поэтому может больше не работать.)

Каков статус вышеуказанной ветки? Кто-то над этим работает?
@Tyriar красиво перечислил необходимые шаги. Сделаны ли какие-либо из этих шагов?

@ Jma353 Я не думаю, что кто-то активно работает над этим, поэтому не стесняйтесь внедрять необходимые биты.

@Tyriar Я не читал спецификацию до всех деталей, но похоже, что ее реализация потребует некоторого манипулирования обработчиком парсера, особенно. что-то вроде временной перегрузки InputHandler.print . Довольно странно, что это сделано таким образом (он несколько переносит состояние терминала в синтаксический анализатор, факт, который пока не делает ни одна другая escape-последовательность), но это можно сделать, заменив обработчик печати между ними.

@jerch да, потребуются некоторые изменения парсера. Изменение размера обернутых ссылок - это тот случай, в котором нам также нужно убедиться, что он работает.

VS Code теперь поддерживает отображение подробных наведений для ссылок, поэтому подключение к нему решит проблему:

image

Жаль, что это немного странные последовательности, поскольку наши перехватчики парсера не покрывают это. Если бы они это сделали, это можно было бы сделать полностью как надстройку с использованием обработчиков парсеров, маркеров и API-интерфейсов поставщика ссылок.

@Tyriar Также с # 2751 можно использовать расширенное хранилище attr для аннотирования содержимого URL-адресов в ячейках буфера.

Жаль, что это немного странные последовательности, поскольку наши перехватчики парсера не покрывают это. Если бы они это сделали, это можно было бы сделать полностью как надстройку с использованием обработчиков парсеров, маркеров и API-интерфейсов поставщика ссылок.

Да, это проблема, и imho не может быть решена на уровне аддона, даже если мы выставим обработчик печати. Я думаю, что это должно идти непосредственно в кодовую базу плюс несколько исключительных условий (например, любое действие без печати до подтверждения финализатора должно нарушить маркировку URL-адресов ячеек и т.д.).

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

johnpoth picture johnpoth  ·  3Комментарии

Tyriar picture Tyriar  ·  4Комментарии

pfitzseb picture pfitzseb  ·  3Комментарии

fabiospampinato picture fabiospampinato  ·  4Комментарии

albinekb picture albinekb  ·  4Комментарии