node.js は基本的にはサーバーサイドで使うものなので、まともなホスティング業者のサービスを利用する限りは通信環境についてそこまでセキュリティリスクは高くないと思います。しかしナントカ API に https でアクセスしているから安全に違いないと信じ込むのは考え物で、HTTPS Node.js v0.8.15 Manual & Documentation - https.request(options, callback) を見ると分かりますが、node.js v0.8.15 時点で未だに rejectUnauthorized のデフォルト値が false なのでデフォルトのまま使うと中間者攻撃の余地があります。
証明書の検証をしない SSL なんて存在しない方がましだと思うので、きちんと検証できているかどうかを必ず確認しましょう。例えば https://www.l.google.com/ など接続はできて証明書の検証に失敗するアドレスにリクエストして、エラーになることを確認すると簡単だと思います。さらに心配性な方は node.js が正当なルート証明書を使っているかどうかも調べておきましょう。
hidekiy blog
Python, Perl, JavaScript, node.js, jQuery, Linux, 壊れた Windows の修理 などについて書いています。
2012-12-08
[windows] BitLocker を有効にしてみました
Windows 8 Pro にしたら一緒に付いてきた、保護されないアクセスからデータを守ってくれるらしい BitLocker を有効にしてみました。
保護されないアクセスとは例えば以下のようなアクセス許可が正常に適用されない状況です。
暗号化の処理について、作業を中断することなくバックグラウンドで処理が進行し、暗号化が途中まで完了しているという状態が許容されているようです (暗号化進行中にシャットダウンしても大丈夫)。暗号化も Low-Priority I/O でおしとやかに処理されるのでとても良くできている印象を受けました。
BitLocker による保護とは意図したとおりの OS のみがディスクにアクセスするよう制限することにあるので、TPM 付きのマシンなら同じマシンで起動していることを自動的に確認できるので起動時のパスワード入力は無しにできます (PIN も設定可能)。TPM 無しの場合でも USB メモリもしくはパスワードでも BitLocker を有効にできます (要ポリシー変更)
また起動時に起動用のパスワードを打ち込めば必ずフルアクセス出来るようになるのではなく、正常に保護されない恐れのあるアクセス (正規の Windows 以外からアクセスされる場合) の時は回復キー (数字48桁) を要求されます。この理由はフルコントロール可能な回復キーは管理者が管理し、標準ユーザー権限のユーザーは正規の認証を経ることになっているからだと思います。
この仕組みはデータが複数個に増えるわけではなく、データを暗号化する鍵を別々の方法で暗号化して保管することで実現されています。内部で実際にデータを暗号化しているマスターキーは目に見える形では表示されません。
WinRE を使いたい時も回復キーを要求され少しめんどくさいですが、あらかじめ Windows 内で「保護の中断」を管理者権限で実行しておくと回復キー不要でアクセスできます。BIOS のアップデートも回復キーを要求されるはずなので、行う際は同様に保護の中断を行っておくとスムーズに行えると思います。
「保護の中断」と「BitLocker を無効にする」の違いは、保護の中断の場合はディスクの暗号化はそのままで、鍵が誰でも使用可能な状態で書き込まれるということで、次の Windows 起動時に自動的にパスワード不要の鍵は削除され保護が再開します。BitLocker を無効にするを行った場合は全てのセクタの暗号化が解除され BitLocker を有効にする前の何も保護されていない状態に戻ります。解除には使用中の領域全体への読み取りと書き込みアクセスを伴うので少し時間がかかります。
スリープ状態の場合は BitLocker では保護されませんが休止状態ならば保護されます。スリープ状態のパソコンからメモリダンプを取ることができれば鍵を盗むことができるかもしれません。休止状態の場合は保護されるので、自動的に休止状態に移行するように設定することもより安全性を高めるために役に立つかもしれません。
BitLocker ドライブ暗号化でファイルを保護する
BitLocker に関してよく寄せられる質問 (FAQ)
保護されないアクセスとは例えば以下のようなアクセス許可が正常に適用されない状況です。
- LiveCD で起動して USB メモリにデータをコピーして持って帰る
- HDD を取り外して持ち出し、別の OS からアクセス許可を無視してオフラインアクセスする
- オフラインで OS にルートキットを秘密裏に書き込んでおきパスワードを盗む
暗号化の処理について、作業を中断することなくバックグラウンドで処理が進行し、暗号化が途中まで完了しているという状態が許容されているようです (暗号化進行中にシャットダウンしても大丈夫)。暗号化も Low-Priority I/O でおしとやかに処理されるのでとても良くできている印象を受けました。
BitLocker による保護とは意図したとおりの OS のみがディスクにアクセスするよう制限することにあるので、TPM 付きのマシンなら同じマシンで起動していることを自動的に確認できるので起動時のパスワード入力は無しにできます (PIN も設定可能)。TPM 無しの場合でも USB メモリもしくはパスワードでも BitLocker を有効にできます (要ポリシー変更)
また起動時に起動用のパスワードを打ち込めば必ずフルアクセス出来るようになるのではなく、正常に保護されない恐れのあるアクセス (正規の Windows 以外からアクセスされる場合) の時は回復キー (数字48桁) を要求されます。この理由はフルコントロール可能な回復キーは管理者が管理し、標準ユーザー権限のユーザーは正規の認証を経ることになっているからだと思います。
この仕組みはデータが複数個に増えるわけではなく、データを暗号化する鍵を別々の方法で暗号化して保管することで実現されています。内部で実際にデータを暗号化しているマスターキーは目に見える形では表示されません。
WinRE を使いたい時も回復キーを要求され少しめんどくさいですが、あらかじめ Windows 内で「保護の中断」を管理者権限で実行しておくと回復キー不要でアクセスできます。BIOS のアップデートも回復キーを要求されるはずなので、行う際は同様に保護の中断を行っておくとスムーズに行えると思います。
「保護の中断」と「BitLocker を無効にする」の違いは、保護の中断の場合はディスクの暗号化はそのままで、鍵が誰でも使用可能な状態で書き込まれるということで、次の Windows 起動時に自動的にパスワード不要の鍵は削除され保護が再開します。BitLocker を無効にするを行った場合は全てのセクタの暗号化が解除され BitLocker を有効にする前の何も保護されていない状態に戻ります。解除には使用中の領域全体への読み取りと書き込みアクセスを伴うので少し時間がかかります。
スリープ状態の場合は BitLocker では保護されませんが休止状態ならば保護されます。スリープ状態のパソコンからメモリダンプを取ることができれば鍵を盗むことができるかもしれません。休止状態の場合は保護されるので、自動的に休止状態に移行するように設定することもより安全性を高めるために役に立つかもしれません。
BitLocker ドライブ暗号化でファイルを保護する
BitLocker に関してよく寄せられる質問 (FAQ)
[windows] Windows 回復環境 (WinRE) を修理する
Windows 本体が起動しない場合は WinRE もしくはインストールメディアから利用可能なスタートアップ修復によって自動修復することができます。しかしインストール済みの WinRE 自体が起動しなくなった場合は自分で修理する必要があるようです。
winre.win の入ったパーティーションの開始位置をずらした場合や、BCD (ブート構成データ) から WinRE 自体のエントリをうっかり消去してしまった場合は、bootrec /rebuildbcd を使っても自動修復できません。そこでちまちま再設定するのではなく reagentc を使うと以下の手順で簡単に再設定出来ることが分かりました。
壊れる原因について
Windows において MBR 経由の従来型のブート方式ではパーティーションごとの UUID 的な何かではなく、ディスク内でのパーティーションの開始位置によってどの OS を起動するべきかを BCD 内で指定しています。
よって gparted などで C:\Windows の入った領域の開始位置をずらす操作 (右側への拡張と縮小ではなく、左側への移動) を行うとブート不能になり、スタートアップ修復が必要になります。
スタートアップ修復を行おうにも何もブートしない場合はインストールメディアから起動すればスタートアップ修復が行えます。
スタートアップ修復に頼らずに BCD を修復するには
Windows に関しては WinRE 内に収録されている bootrec /rebuildbcd でおそらく復活します。
手動で直したい場合には BCD を bcdedit で更新すると直ります。具体的には以下の手順で行えます。
リンク
スタートアップ修復 - Microsoft Windows
GParted FAQ - 14: After resizing my Windows 7 or Vista partition, my computer won't boot. How can I fix this?
win7 システムの修復
Installing WinRE to hard disk - MSFN Forum
winre.win の入ったパーティーションの開始位置をずらした場合や、BCD (ブート構成データ) から WinRE 自体のエントリをうっかり消去してしまった場合は、bootrec /rebuildbcd を使っても自動修復できません。そこでちまちま再設定するのではなく reagentc を使うと以下の手順で簡単に再設定出来ることが分かりました。
- winre.win というイメージをインストールディスクから抽出するか設置先から救出してきて、C:\Windows\System32\Recovery に戻します
- reagentc /enable というコマンドで BCD エントリとディスクイメージの設置 (winre.win のコピーではなく移動w) が完了します
- 内部状態 ReAgent.xml には設定していると記録されていて、実際には BCD エントリが存在していない矛盾した状態になっているとエラーが出ます。その場合は ReAgent.xml を初期化すると無事動きます。
初期状態の ReAgent.xml は C:\Windows\WinSxS 内のどこかにあるようなので検索してみてください。手元の Windows 8 では C:\Windows\WinSxS\x86_microsoft-windows-winre-recoveryagent_... みたいな所にありました。
壊れる原因について
Windows において MBR 経由の従来型のブート方式ではパーティーションごとの UUID 的な何かではなく、ディスク内でのパーティーションの開始位置によってどの OS を起動するべきかを BCD 内で指定しています。
よって gparted などで C:\Windows の入った領域の開始位置をずらす操作 (右側への拡張と縮小ではなく、左側への移動) を行うとブート不能になり、スタートアップ修復が必要になります。
スタートアップ修復を行おうにも何もブートしない場合はインストールメディアから起動すればスタートアップ修復が行えます。
スタートアップ修復に頼らずに BCD を修復するには
Windows に関しては WinRE 内に収録されている bootrec /rebuildbcd でおそらく復活します。
手動で直したい場合には BCD を bcdedit で更新すると直ります。具体的には以下の手順で行えます。
- WinRE のコンソールを開きます。
- bcdedit /enum osloader で identifier を確認します。device の所が Unknown になっているエントリが壊れています。
- diskpart を使って list volume などでドライブレターを確認し、dir /a c:\ などで内容を確認します。
- bcdedit {identifier} /set device partition=C: などと OS の入っているドライブを指定して正しいパーティーション開始位置をセットします
リンク
スタートアップ修復 - Microsoft Windows
GParted FAQ - 14: After resizing my Windows 7 or Vista partition, my computer won't boot. How can I fix this?
win7 システムの修復
Installing WinRE to hard disk - MSFN Forum
2012-12-07
[express.js] req.next は場合により壊れている
express.js で何か作る際に、探検好きな人はレスポンスオブジェクト res には リクエストオブジェクト req が入っていて、req には次に呼び出すべき関数に goto する関数 next が入っていることをご存知かと思います。
この req.next について、値はミドルウェア中では正しくてもリクエストルーター中ではちょっと間違っている (リクエストルーター自体を skip する next になっている) ように見えるので、保守的な方は常に引数として渡される方の next を使うようにしましょう。
この req.next について、値はミドルウェア中では正しくてもリクエストルーター中ではちょっと間違っている (リクエストルーター自体を skip する next になっている) ように見えるので、保守的な方は常に引数として渡される方の next を使うようにしましょう。
var express = require('express'), app = express(); app.use(function (req, res, next) { console.log('middleware:', req.next === next, res.req.next === next); next(); }); app.get('/', function (req, res, next) { console.log('router:', req.next === next, res.req.next === next); // req.next(); doesn't work correctly. next(); }, function (req, res, next) { res.send('ok'); }); app.listen(3000); /* middleware: true true router: false false */
[express.js] エラーの伝搬と処理について
express.js でリクエストを処理しているとき、発生したエラーを適切に処理する仕組みについてドキュメントではあまり詳しく取り扱われていませんが、少し理解しておくともっと楽しくコードが書けると思います。
express において設定するコールバック関数は受け取る引数の数で勝手に分類され、3個以下の場合は正常系、4個の場合は異常系となります。正常系のとき引数リストは req, res, next で、異常系のときは err, req, res, next です。
正確には connect の範疇となるミドルウェアも、express に内蔵されているリクエストルーターと同じような振る舞いをするように作られています。
正常系でエラーが発生した場合はコールバック関数と同期的に発生したエラーは throw でも良いですが非同期的に発生したエラーは next(err) として伝搬させる必要があります。区別が面倒な方はすべて next(err) と書くことにしてもよいと思います。
異常系のコールバック関数は必ずエラーに対処しないといけないわけではなく、next(err) を呼び出してエラーを伝搬することもできます。
全てのミドルウエアを処理してもエラーを処理しきれなかったとき connect によりデフォルトのエラー画面が表示されます。あらかじめミドルウェアの最後の方に errorHandler を入れておくと素敵なエラーページを出せます。connect のモジュールを使っているのにタイトルが Express となる理由は express の lib/express.js を見ると分かります。
以下のコードで色々試してみてください。
リンク
node.js - Error handling principles for NodeJS + Express apps? - Stack Overflow
express/test/app.routes.error.js
express において設定するコールバック関数は受け取る引数の数で勝手に分類され、3個以下の場合は正常系、4個の場合は異常系となります。正常系のとき引数リストは req, res, next で、異常系のときは err, req, res, next です。
正確には connect の範疇となるミドルウェアも、express に内蔵されているリクエストルーターと同じような振る舞いをするように作られています。
正常系でエラーが発生した場合はコールバック関数と同期的に発生したエラーは throw でも良いですが非同期的に発生したエラーは next(err) として伝搬させる必要があります。区別が面倒な方はすべて next(err) と書くことにしてもよいと思います。
異常系のコールバック関数は必ずエラーに対処しないといけないわけではなく、next(err) を呼び出してエラーを伝搬することもできます。
全てのミドルウエアを処理してもエラーを処理しきれなかったとき connect によりデフォルトのエラー画面が表示されます。あらかじめミドルウェアの最後の方に errorHandler を入れておくと素敵なエラーページを出せます。connect のモジュールを使っているのにタイトルが Express となる理由は express の lib/express.js を見ると分かります。
以下のコードで色々試してみてください。
/* Q. 以下のアドレスのレスポンスはどうなるでしょうか http://localhost:3000/ http://localhost:3000/?error=1 http://localhost:3000/?error=1&catch=1 http://localhost:3000/?pass=1 */ process.env.DEBUG = '*'; var express = require('express'), app = express(); // middleware app.use(express.logger()); app.use(function middlewareA(req, res, next) { req.trace = [0]; next(); }); app.use(app.router); app.use(function middlewareB(err, req, res, next) { req.trace.push(5); res.send({msg:'final: error', trace: req.trace, error: String(err)}); }); app.use(function middlewareC(req, res, next) { req.trace.push(6); res.send({msg:'final: not error', trace: req.trace}); }); // request router app.get('/', function (req, res, next) { req.trace.push(1); next(); }); app.get('/', function (req, res, next) { req.trace.push(2); if (req.param('error')) { next(new Error('something happened')); } else { next(); } }, function (req, res, next) { req.trace.push(3); if (req.param('pass')) { next(); } else { res.send({msg:'ok', trace: req.trace}); } }, function (err, req, res, next) { req.trace.push(4); if (req.param('catch')) { res.send({msg:'caught error', trace: req.trace, error: String(err)}); } else { next(err); } }); app.listen(3000);
リンク
node.js - Error handling principles for NodeJS + Express apps? - Stack Overflow
express/test/app.routes.error.js
登録:
投稿 (Atom)