Xterm.js: Mendukung hyperlink ansi escapes

Dibuat pada 28 Nov 2017  ·  29Komentar  ·  Sumber: xtermjs/xterm.js

Emulator terminal mulai mendukung hyperlink . Sementara banyak terminal telah lama mendeteksi URL dan menautkannya, memungkinkan Anda untuk Command-Click atau Control-Click mereka untuk membuka browser, Anda terpaksa mencetak URL panjang yang tidak sedap dipandang itu di layar. Mulai musim semi 2017, beberapa terminal mulai mendukung HTML seperti tautan, di mana teks tautan dan tujuan dapat ditentukan secara terpisah.

Contoh dari iTerm2 3.1:
screen shot 2017-11-28 at 12 08 20

areapi arelinks help wanted typenhancement

Komentar yang paling membantu

iTerm2 menunjukkan URL seperti ini:

screen shot 2017-11-28 at 14 50 20

Ini juga mirip dengan cara Chrome menampilkan URL saat Anda mengarahkan kursor ke tautan.

Semua 29 komentar

Ide bagus, sambutan hangat!

Ini bisa menjadi standar dan mempermudah penguraian.
Masalah terkait: https://github.com/xtermjs/xterm.js/issues/583

Manfaat terbesar adalah kita dapat menautkan teks tanpa harus mengirim spam ke terminal dengan URL yang panjang. Misalnya, seseorang dapat menautkan ke dokumentasi dalam pesan kesalahan tanpa membuatnya menjadi sangat bertele-tele.

Ini harus diterapkan dengan hati-hati, Anda harus dapat mengarahkan tautan untuk melihat ke mana arahnya, jika tidak, Anda dapat menautkan pengguna tanpa sadar ke situs berbahaya. Ini sudah menjadi masalah besar dalam phishing email.

Misalnya Anda dapat membuat link yang memiliki judul "login.facebook.com" tetapi sebenarnya menautkannya ke login.faceboook.com, memiliki halaman yang terlihat persis sama, tetapi menyimpan sandi pengguna saat login.

iTerm2 menunjukkan URL seperti ini:

screen shot 2017-11-28 at 14 50 20

Ini juga mirip dengan cara Chrome menampilkan URL saat Anda mengarahkan kursor ke tautan.

Jika / saat ini diterapkan, kirimkan masalah atau PR ke supports-hyperlinks , yang dimaksudkan untuk mendeteksi dukungan untuk kemampuan ini.

@jamestalmage ini mungkin perlu diserahkan ke embedders xterm.js, saat ini lingkungan dimiliki oleh emulator terminal yang menggunakan xterm.js. Misalnya Hyper dan VS Code masing-masing menetapkan TERM_PROGRAM .

@Tyriar - Dalam hal ini, mungkin hanya menyertakan referensi ke supports-hyperlinks dalam komit yang mendaratkan ini, dan di catatan rilis saat meluas. Saya tidak yakin apakah ada supports-hyperlinks setara untuk bahasa lain, tetapi jika demikian, mungkin layak untuk disebutkan juga.

Saya memiliki implementasi bukti konsep:

links.txt

Ada masalah mendasar di mana tautan ini tidak disimpan di buffer dengan cara apa pun, jadi mereka akan hilang jika ukuran jendela diubah. Sebagai gantinya, informasi tautan disimpan di MouseZoneManager yang dihapus oleh _mouseZoneManager.clearAll .

Saya yakin perbaikan nyata harus menunggu sampai implementasi ulang Buffer selesai. Kami membutuhkan mekanisme untuk membuat anotasi sel dan / atau rentang sel, yang stabil saat diubah ukurannya.

(Atau mungkin saya hanya melewatkan sesuatu, karena masih baru dalam basis kode ini.)

Saya yakin perbaikan nyata harus menunggu sampai implementasi ulang Buffer selesai. Kami membutuhkan mekanisme untuk membuat anotasi sel dan / atau rentang sel, yang stabil saat diubah ukurannya.

@ PerBothner ya Anda mungkin benar. Hal lain yang perlu kita pikirkan sebelum ini dapat dikirim adalah bagaimana URL yang mendasarinya diekspos dari xterm.js sehingga embedder dapat menampilkannya di UI. Kami mungkin juga ingin menonaktifkannya secara default untuk alasan keamanan (karena URL tidak akan muncul secara default).

Saya memperbarui tambalan saya dan mendorongnya ke cabang: https://github.com/PerBothner/xterm.js/tree/hyperlinks

Belum siap untuk permintaan tarik, meskipun - berbagai masalah yang disebutkan sebelumnya belum ditangani.

Proposal untuk API untuk menggunakan ini:

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 masukan tentang bentuk API? Saya tidak dapat menemukan utas yang berbicara tentang bentuk ini, tetapi mungkin ini seharusnya set daripada add karena hanya masuk akal untuk memiliki 1.

Juga mungkin lebih baik menggunakan sesuatu seperti 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;
}

Alternatif lain:

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

@Tyriar IMO tidak masuk akal untuk membuat penangan terpisah untuk ini. Kemungkinan konsumen API ini adalah perender kami yang merender url di tooltip jika kami mengarahkan kursor ke teks yang ditautkan, bukan? Mungkin akan masuk akal untuk memperluas linkifier kita dengan hook yang disebutkan di atas untuk onLinkHover dan onLinkLeave , dan menangani hyperlink ansi seperti yang kita lakukan dengan link web sekarang?

Kemungkinan konsumen API ini adalah perender kami yang merender url dalam keterangan alat

@mofux Saya berpikir lebih seperti addon pencarian, embedder menyediakan UI dalam gaya apa pun yang mereka inginkan, kami hanya menyediakan callback untuk melakukannya. Poin bagus bahwa ini belum memungkinkan Anda menangani sesuatu. Saya kira menggabungkan ke API tautan yang ada dan memiliki pengaturan ITerminalOptions.enableAnsiHyperlinks untuk ikut serta dan detail alasannya?

Saya kira menggabungkan ke API tautan yang ada dan memiliki pengaturan ITerminalOptions.enableAnsiHyperlinks untuk ikut serta dan detail alasannya?

Bagaimana cerita embedder untuk mendukung fitur ini? Membuka tautan (tidak terlihat) saat mengeklik teks tertaut berpotensi berbahaya - terutama jika kami tidak menampilkan URL tertaut di mana pun 🤔

Meskipun menampilkan target di muka memang bagus, saya rasa tidak ada masalah dalam membuka URL yang "tidak dikenal". Aspek keamanan telah dibahas dalam komentar di bawah spesifikasi. Browser membuka URL "tidak dikenal" sepanjang waktu, misalnya ketika ada kode JS yang mengubah target sebelum membukanya, sering kali untuk menampilkan URL yang "bagus" kepada pengguna, tetapi sebenarnya membukanya melalui redirector.

Ngomong-ngomong ... sesuatu yang belum terpikir olehku sejauh ini ...

Jika xterm.js berjalan di dalam browser yang sebenarnya, dan membuka tautan di katakanlah tab baru dari browser itu: Saya kira membocorkan URL xterm.js melalui bidang Referer adalah sesuatu yang perlu dikhawatirkan. Tidak yakin tentang dukungan saat ini untuk rel = "noreferrer", tapi sepertinya sesuatu yang harus digunakan.

Lihat diskusi terkait teks hover ini . Masalahnya adalah tentang memberi anotasi pada bagian output dengan "tool-top" dan popup mouse-over lainnya, yang tidak sama dengan menampilkan URL saat Anda mengarahkan kursor ke link. Namun, keduanya mungkin ingin menggunakan mekanisme yang sama untuk menampilkan teks hover yang sebenarnya. Keduanya mungkin akan menggunakan MouseZoneManager .

Apakah ada pakar XSS yang berkeliaran? Mungkin kita butuh audit, haha.

Untuk pengetahuan saya yang terbatas tentang keamanan browser, vektor serangan utama dengan xterm.js adalah data yang melintasi batas terminal / browser:

  • XSS dari browser (JS) ke terminal (data)
    Itu sudah mungkin dan imho tanggung jawab integrator (xterm.js tidak dapat mengontrol ini dengan cara apa pun). Aturan praktis - jangan pernah mengimpor skrip dari sumber tidak tepercaya di halaman terminal atau websocket pty dan dengan demikian sistem yang menghosting pty akan hilang. Jangan izinkan konten pengguna yang tidak difilter untuk dimasukkan ke halaman dan semacamnya - pada dasarnya semua hal XSS yang khas, atau pty hilang.
  • XSS dari terminal (data) ke browser (JS)
    Itulah kualitas baru yang mungkin kami masukkan dengan URL, jika kami tidak memastikan bahwa data terminal tidak akan pernah mencapai konteks JS dari halaman embedding (dengan demikian objek terminal itu sendiri). Jika itu mungkin (mari kita asumsikan bahwa untuk satu detik) penyerang dapat memperoleh akses ke halaman browser, dan dengan demikian melakukan serangan terminal (data) - browser (JS) - terminal (data). Mari kita asumsikan lebih lanjut xterm.js berjalan banyak di portal layanan cloud orchestrating dan admin menggunakan sesi terminal ke mesin yang berbeda. Outch. Setelah penyerang mendapatkan akses ke halaman browser embedding, semua layanan cloud yang dapat diakses admin berada dalam bahaya.

Pertanyaannya adalah - apakah ada kemungkinan untuk melewati batas terminal (data) - browser (JS) dengan URL? Sekali lagi pengetahuan saya yang terbatas tentang keamanan browser tidak banyak membantu di sini. Satu-satunya skenario yang dapat saya pikirkan adalah bookmarklet yang menyuntikkan dirinya ke dalam JS halaman. Saya tidak tahu apakah kita dapat menghindari ini dengan selalu membuka item di jendela / tab baru saja (tebak sesi akan tetap bocor, jika bukan httpOnly? Bagaimana dengan koneksi websocket?) Yang membuat saya berpikir bahwa kita harus mengurai URL dan hapus semua "konten yang terlihat JS", ya ampun ...

Sunting: Perhatikan bahwa websockets melewatkan sebagian besar pengaturan keamanan browser, mereka bahkan tidak memiliki pemeriksaan asal yang sama (ikuti dengan polling panjang ajax jika Anda membutuhkan lol ini). Hmm ...

bookmarklet [...] menghapus "konten yang terlihat JS"

Menurut saya, sebaiknya hanya memasukkan URL yang diawali dengan "http: //", "https: //", mungkin "ftp: //" ke daftar putih dan menolak yang lainnya. Atau setidaknya daftar hitam kurangnya skema serta "javascript:".

Di cabang hyperlink saya, saya menambahkan tambalan https://github.com/PerBothner/xterm.js/commit/b2647b90d301c52229d01720800865a0d39f436f untuk fungsi panggilan balik yang dapat diatur dengan sekali klik. Ini memungkinkan mengubah cara penanganan tautan. Misalnya ketika DomTerm dikonfigurasi untuk menggunakan cabang xterm.js saya setelah ls --hyperlink=auto denting pada sebagian besar nama file akan membuka file di emacs, tetapi file html akan membuka file di browser default Anda, tergantung pada pengaturan Anda.

(Berhati-hatilah karena ada beberapa kelemahan dalam prototipe. Saya tidak tahu apakah itu khusus untuk prototipe DomTerm.)

Browser membuka URL "tidak dikenal" sepanjang waktu, misalnya ketika ada kode JS yang mengubah target sebelum membukanya, sering kali untuk menampilkan URL yang "bagus" kepada pengguna, tetapi sebenarnya membukanya melalui redirector.

@egmontkob di browser biasanya Anda mulai dari tempat yang aman seperti mesin pencari yang memberi tahu Anda dengan jelas kapan domainnya. Untuk terminal, Anda perlu mempercayai program (beberapa di antaranya mungkin mencetak konten jarak jauh), bahkan memasukkan file dapat menunjukkan tautan berbahaya. Sepertinya lebih baik aman secara default dan memiliki pengaturan yang hanya menjelaskan risiko dan menawarkan mitigasi.

Di cabang hyperlink saya, saya menambahkan patch PerBothner @ b2647b9 untuk fungsi callback yang dapat

@PerBothner sudah ada penangan di sini di webLinks addon: https://github.com/xtermjs/xterm.js/blob/509ce5fa3a698ee7847419117e9dd6b979b105bf/src/addons/webLinks/webLinks.ts#L37 , tampaknya agak jelek perlu siapkan 2 penangan tautan web yang berbeda.

(Maaf atas tanggapan yang terlambat - saya dilacak ke samping.)

@Tyriar menulis "sudah ada penangan di sini di addon webLinks". Masalahnya adalah webLinksInit membuat ILinkMatcher, dan mengaitkan handler yang diberikan dengan ILinkMatcher tertentu, yang berisi sekumpulan ekspresi reguler untuk dicocokkan. Tetapi bagaimana kita menentukan penangan tautan untuk hyperlink yang dibuat oleh urutan pelolosan dan dengan demikian bukan merupakan hasil dari pencocokan ekspresi reguler? Penangan itu harus "global", dalam arti tidak dikaitkan dengan ILinkMatcher atau regex. Menyetel penangan global / default menggunakan webLinksInit atau Terminal.registerLinkMatcher tidak berfungsi.

Menurut saya, kita membutuhkan kolom ILinkMatcher linkHandler di Terminal - memiliki kolom ILinkMatcher handler di kolom ILinkMatcher tidaklah cukup. Dan jika kita memiliki field linkHandler di Terminal , masuk akal untuk menjadikan handler tersebut sebagai default yang digunakan oleh registerLinkMatcher. Inilah yang dilakukan patch saya.

Jika seseorang ingin membantu dalam hal ini, inilah yang perlu dilakukan:

  • Cari tahu bagaimana menangani implikasi keamanan karena tautan tidak ditampilkan sebagai URL, ini mungkin untuk membuat fitur ikut serta dan mengekspos pengait sehingga konsumen dapat menampilkan munculan
  • Temukan API yang bagus untuk membuka tautan, kita sudah memiliki sesuatu yang sangat mirip dengan API pencocok tautan, dapatkah ini digeneralisasikan?
  • Tambahkan logika ke parser dan simpan tautan di suatu tempat, mungkin sebagai IMarker s?

Cabang hyperlink saya https://github.com/PerBothner/xterm.js/tree/hyperlinks dapat menjadi titik awal. (Meskipun agak tua jadi mungkin tidak berfungsi lagi.)

Bagaimana status cabang di atas? Apakah seseorang sedang mengerjakan ini?
@Tyriar dengan baik mencantumkan langkah-langkah yang diperlukan. Apakah ada dari langkah-langkah ini yang dilakukan?

@ Jma353 Saya tidak berpikir bahwa ada orang yang secara aktif mengerjakan ini, jadi silakan mengimplementasikan bit yang diperlukan.

@Tyriar Saya belum membaca spesifikasi untuk semua detail, tetapi tampaknya menerapkannya akan melibatkan beberapa penyulingan penangan parser, khususnya. sesuatu seperti kelebihan muatan sementara InputHandler.print . Agak aneh karena dibuat seperti ini (ini agak menarik status terminal ke dalam parser, fakta yang sejauh ini tidak ada urutan escape lain), tetapi harus dapat dilakukan dengan mengganti penangan cetak di antaranya.

@ Jerch ya itu akan membutuhkan beberapa perubahan parser. Mengubah ukuran tautan terbungkus adalah kasus yang perlu kami pastikan berfungsi juga.

VS Code sekarang memiliki dukungan untuk menampilkan hover mendetail untuk tautan, jadi menghubungkannya dengan ini akan menyelesaikan masalah:

image

Sayang sekali ini adalah urutan yang agak aneh karena pengait pengurai kami tidak menutupinya. Jika mereka melakukannya, ini dapat dilakukan sepenuhnya sebagai addon menggunakan pengait parser, penanda, dan API penyedia tautan.

@Tyriar Juga dengan # 2751 penyimpanan attr yang diperluas dapat digunakan untuk memberi keterangan hal-hal URL ke sel penyangga.

Sayang sekali ini adalah urutan yang agak aneh karena pengait pengurai kami tidak menutupinya. Jika mereka melakukannya, ini dapat dilakukan sepenuhnya sebagai addon menggunakan pengait parser, penanda, dan API penyedia tautan.

Ya itu masalah dan imho tidak bisa diselesaikan pada tingkat tambahan, bahkan jika kita mengekspos pengait penangan cetak. Saya pikir ini harus masuk langsung ke basis kode ditambah beberapa kondisi luar biasa (seperti tindakan non-cetak apa pun sebelum finalizer diakui harus merusak penandaan URL sel dan semacamnya).

Apakah halaman ini membantu?
0 / 5 - 0 peringkat