Firefox のスクリーンショット機能を無効にする

Firefox 55 では試験的機能としてページのスクリーンショットを撮影する機能が導入された。ページ上で右クリックすると「スクリーンショットを撮る」というメニューが追加されている。

Make screenshots of webpages, and save them locally or upload them to the cloud. This feature will undergo A/B testing and will not be visible for some users.

https://www.mozilla.org/en-US/firefox/55.0/releasenotes/

f:id:scientre:20170921114252p:plain

私には必要ない機能なので、メニュー項目を占拠しているこの機能を無効にした。手順は次の通り

  1. アドレスバーに「about:config」と入力し Enter
  2. 次のような警告が出る場合は「危険性を承知の上で使用する」を選ぶ
    f:id:scientre:20170921114245p:plain:w500
  3. 設定名が「extensions.screenshots.disabled」のものを検索し、値を true に設定する
    f:id:scientre:20170921114249p:plain

以上の手順でコンテキストメニューから「スクリーンショットを撮る」を取り除くことができる。

Raspberry Pi をキヤノン EOS シリーズのリモコンにする

勉強会で Raspberry Pi で制御する赤外線リモコンを組んだ。その回路でキヤノン EOS シリーズのカメラのシャッターを切ることができたので記録しておく。

Raspberry Pi の動作に必要な OS である Raspbian と、赤外線の送受信を行うミドルウェア LIRC (Linux Infrared Remote Control) がすでにインストールされているパッケージをいただいたので、その辺りの手順については割愛する。

この記事では LIRC を使って制御信号をどのように送信するかについて記す。

赤外線送受信の回路図はこの記事が詳しい。

使用器具

リモコン制御専用機として Raspberry Pi Zero を用いることもできるようだ。必要に応じて課題とする。

今回カメラは EOS 60D を用いたが、理屈の上では 1987 年に発売された EOS 650 以降、EF マウントを備えた一眼レフでも使用できるはずだ。またリモコンの付属している「オートボーイ」シリーズのリモコンが EOS デジタルシリーズで使用できるので、コンパクトカメラでも使用できる機種があるかもしれない。

赤外線リモコン信号について

赤外線リモコン信号の規格については次のサイトがわかりやすい。

リモコンのひと続きの命令は、赤外線の点灯と消灯を繰り返すパルス信号として表現されている。命令の先頭にはリーダー信号と呼ばれる点灯・消灯時間の長い信号がつく。

続いてデータ部分は点灯・消灯時間の繰り返しで表現され、よく使われる NEC(家電製品協会)フォーマットでは点灯時間が一定で、消灯時間の違いで 1 と 0 のビットを表現している。

命令の最後にはストップ信号と呼ばれるパルスが一つ付加される。点灯時間はデータ部分と同じで、信号に比べて十分長い消灯時間が定められている。

ここまで点灯・消灯と書いてきたが、実際にはパルスの点灯部分は周波数変調がかかっている。変調のキャリア周波数は多くの場合 38 kHz が使用される。

既存のリモコンの信号を確認する

さてここまで理解したら、手元のリモコンがどのようなパルスを送っているか確認してみよう。

Rasberry Pi に SSH で接続し、mode2 コマンドを使って信号の確認を行う。/dev/lirc0 の部分はハードウェア構成によって読み換えてほしい。

mode2 -d /dev/lirc0

このコマンドを実行すると、次のような数字の羅列が表示される。

space 53385
pulse 3491
space 1699
pulse 443
space 1275
pulse 447
space 1271
pulse 442
space 417
pulse 440

これは赤外線の点灯(pulse)と消灯(space)マイクロ秒単位で表したものである。

昼間、屋外から光が入る場所などでは外光がリモコン信号だと誤認識して出力が流れっぱなしになることがある。その場合は反射率の低い板や布で覆うなど、リモコン以外の赤外線が入らないようにする。

リモコン信号の設定ファイルを記述する

次の内容を EOS.conf というファイルとして保存する。

# EOS IR Remote Control
begin remote

  name  EOS
  flags RAW_CODES
  eps            30
  aeps          100

  frequency 32700
  gap          100000
  toggle_bit_mask 0x0

      begin raw_codes

          name RELEASE
              500 7330 500

          name TIMER
              500 5360 500

      end raw_codes

end remote

各設定を簡単に解説すると

  • begin remote: 機器ごとの設定を記述するブロック
  • name: 機器の名前。送信コマンドで使用する
  • flags: 信号や記述形式の設定。ビット演算子の「|」を使って複数を組み合わせることができる
  • RAW_CODES: パルスの点灯と消灯の時間を μs 単位の数値で記述する
  • frequency: パルスの変調周波数 [Hz]。デフォルトは 38000。キヤノンの EOS シリーズおよび一部のコンパクトカメラでは 32.7 kHz が使用されているので変更している
  • gap: ストップ信号の消灯部の長さ [μs]
  • begin raw_codes: 信号の内容を記述するブロック
  • (raw_codes) name: 命令の名前

設定ファイルを lircd に読み込ませる

作成した設定ファイルの内容を /etc/lirc/lircd.conf にコピーして使う。既存の lircd.conf が空なら単純にファイル自体をコピーしてもよい。

LIRC のデーモンである lircd が起動していない場合は次のコマンドで起動する。

sudo lircd -d /dev/lirc0

lircd がすでに起動している場合や設定ファイルを再読み込みさせたい場合、次のコマンドで lircd を再起動する。

sudo killall lircd && sudo lircd -d /dev/lirc0

もし設定ファイルに不備がある場合は /var/log/syslog に記録される。うまく送信されない場合はここを確認してみよう

リモコン信号を送信する

リモコン信号を送信するには irsend コマンドを使う。代表的な使い方は次の通り。

コマンド 内容
irsend LIST "" "" 機器の一覧を表示する
irsend LIST <機器名> "" 指定した機器の命令一覧を表示する
irsend SEND_ONCE <機器名> <命令名> 指定した命令の信号を送信する

先ほど作成した EOS.conf の場合、次のように使用する。RELEASE が即時撮影、TIMER がタイマー撮影となる。

irsend SEND_ONCE EOS RELEASE
irsend SEND_ONCE EOS TIMER

このコマンドを送信する前に、最近の EOS シリーズではドライブ設定を10秒または2秒のタイマーにする必要がある。また赤外線受光部がグリップ部分に配置されているので指で遮らないよう注意する。


さくらのレンタルサーバで Let’s Encrypt を使う

無料で SSL 証明書を発行できる認証局 Let’s Encrypt を使用して、さくらのレンタルサーバの Web 領域を HTTPS に対応させたメモ。

環境

前準備

Let’s Encrypt の証明書を生成する Certbot というソフトを HomeBrew を使ってインストールする必要があるが、HomeBrew が古いことと、macOSSierra にアップグレードしたことでインストールに失敗した。まずは HomeBrew の修復から始める。

ディレクトリ /usr/local の権限が my_user_name:admin でない場合、所有者の再設定を行う。

% sudo chown -R my_user_name:admin /usr/local

HomeBrew 自身とパッケージの更新を行う。

% brew update
% brew upgrade formula

ついでに古いパッケージを削除した。

% brew cleanup

証明書の発行

HomeBrew から Certbot をインストールする。

% brew install certbot

次のコマンドで suzume.cc に対する証明書を発行する。セキュリティアラートを送信するメールアドレスの入力、利用規約への同意、IP アドレス記録への同意などメッセージに応じて答える。

% sudo certbot certonly --manual -d suzume.cc

進めていくと
http://suzume.cc/.well-known/acme-challenge/SUrappQZ2Q89r3O6mcQzY339-MsHxVf
のような URL にファイルを配置するよう指示される。指示された内容のファイルを配置して Enter を押す。

すると Let’s Encrypt からその URL へアクセスがあり、認証されれば証明書が発行される。

さくらのレンタルサーバへの設定

サーバコントロールパネルから「ドメイン設定」を開く。

SSL を設定したいドメインの横にある「登録」を開く。

続いて秘密鍵をアップロードする。このとき証明書や鍵は /etc/letsencrypt/live 以下のスーパーユーザのみアクセスできるディレクトリに配置されているので、アップロードするために一時的にコピーする。

% sudo cp /etc/letsencrypt/live/suzume.cc/privkey.pem

秘密鍵をアップロードしたあと「証明書のインストール」を行う。 fullchain.pem の内容をコピーして貼り付ける。

% sudo cat /etc/letsencrypt/live/suzume.cc/fullchain.pem | pbcopy

このあと「中間証明書のインストール」を行う。 chain.pem の内容をコピーして貼り付ける。

% sudo cat /etc/letsencrypt/live/suzume.cc/chain.pem | pbcopy

そして最後にドメインの設定から SNI SSL を有効にすればよい。

HTTP→HTTPS リダイレクトの設定

さくらのレンタルサーバの場合、HTTPS で接続すると内部でプロキシが動作しているようで、通常のサーバとは設定方法が異なる。

.htaccess を使用して静的コンテンツに設定する場合、通常は RewriteCond %{HTTPS} off とするところだが、次のように記述する。

RewriteEngine On

# 指定したドメインのみに適用する
RewriteCond %{HTTP_HOST} suzume.cc

# さくらのレンタルサーバ独自の設定
RewriteCond %{ENV:HTTPS} !^on$
RewriteCond %{HTTP:X-SAKURA-FORWARDED-FOR} ^$

RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

PHP でルーティングを行う場合、初めに呼ばれる index.php などに次のように記述する。

<?php
if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI']) &&
	$_SERVER['HTTP_HOST'] === 'suzume.cc') {
	if (!isset($_SERVER['HTTP_X_SAKURA_FORWARDED_FOR'])) {
		header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
	}
}

xyzzy ファイラの標準の圧縮形式を ZIP にする

xyzzy の二画面ファイラで圧縮ファイルを作ろうとしたとき、拡張子を入力しないと LHA で圧縮され拡張子 lzh が付与される。

毎回 .zip と打つのは面倒だし、LHA はサポートが終了しており、なおかつ脆弱性が残されたままなので変更したい。

ファイラの動作は lisp/filer.l で定義されており、この中の filer-get-archive-name という関数を .xyzzy で上書きすることで動作を変更する。

具体的には lisp/filer.l の filer-get-archive-name の関数定義を丸ごと .xyzzy にコピーしてきて一部を書き換える。

;; ファイラのデフォルト圧縮形式をZIPにする (lisp/filer.l を上書き)
(in-package "editor")
(defun filer-get-archive-name ()
   ;   :   
   ;   :
   ; (ここは filer.l そのまま)
   ;   :
   ;   :
		      (t (concat file ".zip"))) ;; ここを .zip に書き換える
		(merge-pathnames (cdr (assoc 'base data))
				 (filer-get-directory)))))))
(in-package "user")

M-x load-file で .xyzzy を読み込みなおすと変更が反映される。

SiteGuard Lite の機能レビュー

最近使用したレンタルサーバSiteGuard Lite というウェブアプリケーションファイアウォール(WAF)が導入されていたので評価する。

SiteGuard Lite は株式会社ジェイピー・セキュア(神奈川県川崎市、代表:菅原 修)が提供する WAF で、同社が独自で定義したブラックリストによりアクセスを遮断する仕組みになっている。

SiteGuard Lite がアクセスをブロックした際のメッセージ

同社によれば日経SYSTEMの2009年3月号では高く評価されているというが、そこから8年の月日が経ち、数多くの機能が Web にもたらされた。今日の Web においても SiteGuard Lite は有用なのか検証する。

結論からいうと、SiteGuard Lite は簡単な XSS (Cross site scripting) すら防げない。おまけに過剰検出により正常なアプリケーションの動作を妨害してしまう根本的な問題がある

SiteGuard Lite はごく簡単な XSS を防げない

まずは簡単なフォームを作り、XSS脆弱性を突くときに送信されるであろう文字列を送信できるか試してみた。

すると次のような、セキュリティの教科書にでも載っていそうな基本的な文字列を通してしまった。

このコードは、もしアプリケーションに XSS 脆弱性があった場合に、タッチデバイスにおいて任意の JavaScript を実行できる

対して、古くからある onclick, onmouseover, onkeydown, onsubmit などはブロックされた。8年前ならこれで十分と判断されたのだろう。

最も影響の大きな過剰検出

こちらは実際にアプリケーションを作成する際に発見したもの。

最も短い例としては次の文字列でアクセスがブロックされてしまった。

いろいろなパターンを試してみると、次の値を含むデータは GET または POST メソッドで送信できないことが分かった。

  1. ダブルクォーテーション " で囲まれた文字列が 2 の条件を満たす
  2. 「and」または「or」という単語(大文字小文字問わず)を含み、かつ 3 または 4 の条件を満たす
  3. 2 の直後に英数字以外の文字があり、その後ろに「<」または「>」を含む
  4. 2 の前後両方に「<>」または「<」と「>」で囲まれた文字列を含む

たとえば非同期通信で下書き保存などを行う CMS (Contents management system) が JSON を使ってデータをやり取りしていたとすると、データ中に HTML が含まれ、かつ and や or といった単語が <p>~</p> の中に出現することがある。すると、内容に and や or が含まれる場合だけデータが保存できない問題として発現する。たとえ HTML でなくても、 and のあとに不等号を使う可能性は無視できるほど低くはない。

JSON は、現在のブラウザでは標準で扱えるため、 JavaScript のオブジェクトをシリアライズやその逆をするために非常にポピュラーな形式となっている。そのことを考えると、この過剰検出は大いに問題になると考えられる。

結論

SiteGuard Lite はごく簡単な XSS すら防げず、モダンなアプリケーションでは過剰検出の問題に悩まされる可能性がある。

「優秀」なブラックリストがあるのなら、そのリストを使って Web アプリケーションにアタックしその結果をレポートするテストツールを提供してほしい。そしてリソースはアプリケーション側の脆弱性を塞ぐことに注ぐべきだ。