Qiita
Terminal
shell
Security

Qiita の投稿をターミナルにコピペする時に注意すること

はじめに

Web ページは JavaScript を使用したり、CSS で実際の内容を非表示にしたり、古くは Flash を利用したりすることにより、クリップボードに安全でない内容を保存することができます。そのため、信頼できない Web ページに書いてあるコマンドをターミナル (端末エミュレータ) に直接コピーアンドペーストしないことを心がけている人もいるでしょう。それでも、Markdown で投稿されている Qiita に書いてある内容は比較的安心してコピペしてしまっている人も多いのではないでしょうか。

しかし、Qiita でも不可視の画像を使用することでクリップボードに閲覧者が意図しない内容を挿入することが可能です。

動作を確認したブラウザ

  • Google Chrome 63.0.3239.84 (Windows)
  • Google Chrome 63.0.3239.84 (macOS)
  • Opera developer 51.0.2802.0 (macOS)
  • Vivaldi 1.13.1008.36 (macOS)

恐らく WebKit/Blink 系なら動作します。Edge はコピー自体が行われず、Firefox はコピーは行われましたが改行文字が除去されました。

サンプル

macOS などの Unix 系 OS を利用している場合、以下のただの echo 文に見えるテキストをターミナルにコピペするとログインユーザ名が表示されます (使用しているシェルとターミナルの組み合わせによっては、実行されないこともあります)。

$ echo; clear; echo Hello, $USER!
echo Hello, world!

解説

サンプルの Markdown は次の通りになっています。Markdown と言っても、ただの HTML ですね。

<code>$ echo<img src="https://qiita-image-store.s3.amazonaws.com/0/214275/042204db-cb5c-2024-6840-35126696e941.png" width="0" alt="; clear; echo Hello, $USER!&#x0a;echo"/> Hello, world!</code>

Qiita では Markdown 中の一部の HTML 要素と属性値がそのまま出力されます (それ自体は Markdown の仕様のうちです)。今回は出力されるものの中でも img 要素と code 要素を利用しています。

` ` を利用したコードインライン表示では内部の HTML がエスケープされてしまいますが、code 要素を利用することでコード表示の中に img 要素をそのまま出力することが可能です。img 要素をコピーするとクリップボードには alt 属性の値が入りますが、この時属性値の中に &#x0a; が含まれていることに注意してください。&#x0a; は HTML 中で数値文字参照として扱われ、表示時には 0x0A、つまり改行文字 (LF, \n) に展開されます。そのため、クリップボードにコピーされる内容に改行文字が含まれることになり、ターミナルへのペーストと同時にコマンドが実行されます。また、表示される画像には 1px の画像を利用していますが、より目立たなくするために width 属性の値を0にして完全に非表示にしています。

対策

コピペしない・コピペした内容をエディタなどに貼り付けて内容を確認する

正道と言えば正道なのですが、そうは言っても人間にうっかりは付きものです。人間の注意力だけに頼るのは限界があるでしょう。

Bracketed Paste Mode に対応したシェルとターミナルを使用する

最近のシェルの多くは Bracketed Paste Mode と呼ばれる xterm の拡張に対応しており、この機能が有効な状態かつターミナル側も対応している場合、複数行のペーストをしてもすぐに実行されないようになっています。zsh や fish ではデフォルトで有効になっているため、サンプルが動作しなかった人も多いかもしれませんね。

しかし、古いシェルのサーバへ SSH でアクセスしたりすることを考えるとこれも完璧ではないでしょう。また、Qiita では表示時に除去されているようですが、コピーする内容にペースト終了のエスケープシーケンスを含めた場合はエスケープシーケンスがフィルタされていないターミナルではコマンドが実行されてしまいます。

ターミナルの確認機能を利用する

お使いのターミナルに複数行ペーストしようとした時に確認する機能があれば、それを有効にするのが一番良いかと思います。

iTerm2 では Edit → Paste Special の "Warn Before Multi-Line Paste" と "Warn Before Pasting One Line Ending in a Newline at a Shell Prompt" を ON に、"Limit Multi-Line Paster Warning to Shell Prompt" を OFF にすれば複数行や改行で終わっている内容のペースト時に警告が行われるようになります。