Xterm.js: 支持超链接ansi转义

创建于 2017-11-28  ·  29评论  ·  资料来源: xtermjs/xterm.js

终端仿真器开始支持超链接。 许多终端很早就检测到URL并将其链接起来,从而允许您通过Command-Click或Control-Click来打开浏览器,但您却不得不在屏幕上打印难看的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

最大的好处是,我们可以链接文本,而无需向终端发送垃圾邮件,而无需使用较长的URL。 例如,可以在错误消息中链接到文档,而不必使其变得冗长。

这应该谨慎实现,您需要能够将链接悬停以查看链接的方向,否则您可能会在不知不觉中将用户链接到恶意站点。 这已经是电子邮件网络钓鱼中的一个巨大问题。

例如,您可以创建一个标题为“ login.facebook.com”的链接,但实际上将其链接至login.faceboook.com,该页面的外观完全相同,但在登录时保存用户密码。

iTerm2显示如下URL:

screen shot 2017-11-28 at 14 50 20

这也类似于当您悬停链接时Chrome浏览器显示URL的方式。

如果/在实施此功能时,请向supports-hyperlinks提交问题或PR,以检测对此功能的支持。

@jamestalmage,这可能需要留给xterm.js嵌入程序使用,现在环境由使用xterm.js的终端仿真器拥有。 例如,Hyper和VS Code分别设置TERM_PROGRAM

@Tyriar-在这种情况下,也许只需在对它进行登陆的提交中以及对它进行扩展的发行说明中包含对supports-hyperlinks的引用即可。 我不确定其他语言是否有supports-hyperlinks等价物,但如果有,可能也值得一提。

我有概念验证的实现:

links.txt

存在一个基本问题,即这些链接没有以任何真实的方式存储在缓冲区中,因此如果调整窗口大小,它们将消失。 而是将链接信息存储在_mouseZoneManager.clearAll清除的MouseZoneManager中。

我相信真正的解决方法必须等到缓冲区重新实现后才能执行。 我们需要一种对单元格和/或单元格范围进行注释的机制,该机制在调整大小时是稳定的。

(或者也许我只是缺少一些东西,这是此代码库的新手。)

我相信真正的解决方法必须等到缓冲区重新实现后才能执行。 我们需要一种对单元格和/或单元格范围进行注释的机制,该机制在调整大小时是稳定的。

@PerBothner是的,您可能是对的。 我们需要考虑的另一件事是如何从xterm.js公开底层URL,以便嵌入程序可以在UI中显示它。 出于安全原因,我们可能还希望默认情况下将其关闭(因为默认情况下不会显示该URL)。

我更新了补丁并将其推送到一个分支中: https :

但是,还没有准备好接受拉取请求-前面提到的各种问题尚未解决。

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,不是吗? 也许用前面提到的onLinkHoveronLinkLeave钩子扩展我们的链接器是有意义的,并且那些ansi超链接是否像我们现在使用网络链接那样被处理?

该API的可能使用者将是我们的渲染器,它在工具提示中渲染url

@mofux我在想的更像是搜索插件,ITerminalOptions.enableAnsiHyperlinks用于选择加入,并详细说明原因?

我想合并到现有的链接API中,并设置ITerminalOptions.enableAnsiHyperlinks用于选择加入,并详细说明原因?

嵌入者支持该功能的故事如何? 单击链接的文本时打开(不可见的)链接有潜在的危险-特别是如果我们未在任何地方显示链接的URL🤔

虽然预先显示目标确实不错,但我认为打开“未知” URL没有问题。 在规范下的评论中讨论了安全性方面。 浏览器始终打开“未知” URL,例如,当有一个JS代码在打开目标之前更改目标时,通常向用户显示“不错”的URL,但实际上是通过重定向器打开的。

说到那...到目前为止我还没有发生过...

如果xterm.js在实际的浏览器中运行,并在该浏览器的新选项卡中打开链接:我猜想通过Referer字段泄漏xterm.js的URL是令人担心的事情。 不确定当前对rel =“ noreferrer”的支持,但似乎应该使用。

请参阅悬停文本的相关讨论。 问题在于用“工具顶部”和其他鼠标悬停弹出窗口注释输出的各个部分,这与将鼠标悬停在链接上时显示URL不同。 但是,两个都可能希望使用相同的机制来显示实际的悬停文本。 两者都可能会使用MouseZoneManager

我们有XSS专家吗? 也许我们需要审核,大声笑。

就我对浏览器安全性的有限了解而言,xterm.js的主要攻击媒介是数据越过终端/浏览器边界:

  • 从浏览器(JS)到终端(数据)的XSS
    那已经是可能的,敬请集成商负责(xterm.js不能以任何方式控制它)。 经验法则-永远不要从终端页面或pty websocket上的任何不受信任的源导入脚本,因此托管pty的系统会丢失。 请勿将未经过滤的用户内容插入页面等中-基本上所有典型的XSS东西,否则都会丢失。
  • 从终端(数据)到浏览器(JS)的XSS
    如果我们不确保终端数据永远不会到达嵌入页面的JS上下文(因此终端对象本身),那么我们可以使用URL输入这是一种新的品质。 如果这是可能的(假设是一秒钟),则攻击者可以访问浏览器页面,从而进行终端(数据)-浏览器(JS)-终端(数据)攻击。 让我们进一步假设xterm.js在云编排服务门户中大量运行,并且管理员使用到不同计算机的终端会话。 出路一旦攻击者获得对嵌入式浏览器页面的访问权限,管理员可以访问的所有云服务都将处于危险之中。

问题是-是否有可能跨越终端(数据)-浏览器(JS)与URL边界? 同样,我对浏览器安全性的有限了解在这里无济于事。 我能想到的唯一方案是将自己注入到页面JS中的书签。 我不知道是否可以通过始终仅在新窗口/选项卡中打开内容来避免这种情况(猜测会话仍会泄漏,如果不是httpOnly的话,那么websocket连接又如何呢?)这使我认为我们必须解析URL并删除所有“ JS外观内容”,哦,亲爱的...

编辑:请注意,websockets缺少大多数浏览器的安全设置,它们甚至没有可靠的相同来源检查(如果需要此哈哈,请进行ajax长轮询)。 嗯...

小书签会删除所有“看起来很像JS的内容”

我认为最好只将以“ http://”,“ https://”(也许是“ ftp://”)开头的URL列入白名单,然后拒绝其他任何内容。 或者至少在黑名单中缺少方案以及“ javascript:”。

在我的超链接分支中,我添加了一个修补程序https://github.com/PerBothner/xterm.js/commit/b2647b90d301c52229d01720800865a0d39f436f,用于单击时可设置的回调函数。 这允许更改链接的处理方式。 例如,当DomTerm配置为在大多数文件名上进行ls --hyperlink=auto链接设置

(请注意,原型中有些脆弱。我不知道这是否特定于DomTerm原型。)

浏览器始终打开“未知” URL,例如,当有一个JS代码在打开目标之前更改目标时,通常向用户显示“不错”的URL,但实际上是通过重定向器打开的。

在浏览器中, @ egmontkob通常从安全的地方开始,例如搜索引擎,它可以很清楚地告诉您域的时间。 对于终端,您将需要信任程序(其中某些程序可能会打印远程内容),即使为文件添加目录也会显示恶意链接。 似乎最好在默认情况下是安全的,并且有一个仅描述风险并提供缓解措施的设置。

在我的超链接分支中,我添加了一个PerBothner @ b2647b9补丁,用于单击时可设置的回调函数。

@PerBothnerhttps :

(对迟来的回应表示抱歉-我被跟踪了。)

@Tyriar写道“ WebLinks插件中已经有一个处理程序了”。 问题在于,webLinksInit创建一个ILinkMatcher,并将给定的处理程序与特定的ILinkMatcher关联,该ILinkMatcher包含一组与之匹配的正则表达式。 但是,我们如何为转义序列创建的超链接指定链接处理程序,因此不是正则表达式匹配的结果? 从不与任何ILinkMatcher或正则表达式关联的意义上讲,该处理程序需要“全局”。 使用webLinksInit或Terminal.registerLinkMatcher设置该全局/默认处理程序不起作用。

在我看来,我们需要在T​​erminal中创建一个linkHandler字段-在ILinkMatcher仅拥有一个handler字段是不够的。 而且,如果在Terminal确实有一个linkHandler字段,则使该处理程序成为registerLinkMatcher的默认设置是有意义的。 这就是我的补丁程序所做的。

如果有人想帮忙,这是需要做的事情:

  • 弄清楚如何处理链接不显示为URL的安全隐患,这可能是为了使该功能启用并公开一个钩子,以便消费者可以显示弹出窗口
  • 找出一个不错的API来打开链接,我们已经有了与链接匹配器API非常相似的东西,可以概括一下吗?
  • 将逻辑添加到解析器并将链接存储在某处,也许作为IMarker s?

我的超链接分支https://github.com/PerBothner/xterm.js/tree/hyperlinks可以作为起点。 (尽管它有点旧,所以可能不再起作用。)

上述分支机构的状态如何? 有人为此工作吗?
@Tyriar很好地列出了所需的步骤。 这些步骤都完成了吗?

@ Jma353我认为没有人在积极地进行这项工作,因此可以随意实现所需的位。

@Tyriar我还没有阅读所有细节的规范,但是似乎要实现它会涉及一些解析器处理程序,尤其是。 类似于临时的InputHandler.print超载。 Kinda很奇怪,它是这样子的(它把终端状态拉到了解析器中,这是到目前为止没有其他转义序列的事实),但是应该可以通过在两者之间替换打印处理程序来做到这一点。

@jerch是的,它需要一些解析器更改。 调整包装的链接的大小是一种情况,我们也需要确保其工作正常。

VS Code现在支持显示链接的详细悬停,因此将其挂钩可以解决问题:

image

很遗憾,因为解析器的钩子没有覆盖它,所以序列有些奇怪。 如果他们这样做,则可以完全使用解析器挂钩,标记和链接提供程序API作为附加组件来完成。

@Tyriar同样在#2751中,扩展的attr存储可用于将URL内容注释到缓冲单元中。

很遗憾,因为解析器的钩子没有覆盖它,所以序列有些奇怪。 如果他们这样做,则可以完全使用解析器挂钩,标记和链接提供程序API作为附加组件来完成。

是的,这是一个问题,即使我们公开了打印处理程序挂钩,也无法在插件级别解决恕我直言。 我认为,这必须直接进入代码库,再加上一些特殊条件(例如,在确认终结器之前的任何非打印操作都应破坏单元格的URL标记等)。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

tandatle picture tandatle  ·  3评论

Tyriar picture Tyriar  ·  4评论

chris-tse picture chris-tse  ·  4评论

johnpoth picture johnpoth  ·  3评论

circuitry2 picture circuitry2  ·  4评论