はらへり日記

腹に弾丸

ファイルサイズをチェックするfslint作りました

なぜ作ったのか

会社でフロントサイドJSを書く時、Browserifyとnpmでいろいろモジュール入れてゴリゴリやってたのだがファイルサイズがでかくなってしまうことが多々あった。

ファイルが1個ならいいが、吐き出すファイルが1個ではなかったしみんなが修正する度にファイルサイズチェックするのも非常に面倒だったのでeslintみたいなノリでファイルサイズをチェックできる何かが欲しいなと思ったので作った。

fslint

github.com

lint系をパクってfslintとした。

やってくれるのは本当にシンプルで、指定したファイルが指定したサイズをオーバーしてるかどうかをチェックするだけ。

使用方法はこんな感じ。

本当にこれだけ!

チェックがこけるとexit(1)するのでCIに組み込んでファイルサイズがでかすぎたら弾く、なんてこともできます。

作ってみて

npmライブラリはこれまでもいくつか作ってたんですこのfslintは作るのに全然時間がかかりませんでした。

というのも欲しい機能はだいたいnpmに落ちていたのでそれらをガッチャンコして見やすくしたくらいしか実装してないです。

ES2015で書いて公開ってのも初めてやったのでよい勉強になりました。(こちらを参考にしました!)

まとめ

気軽にファイルサイズチェックしたい人はぜひ使ってね!

node.jsでprocess.env.HOGEを書き換えようとしてハマった

nodeのコード中で環境変数を書き換えたい

そう思って以下の様なことをしてみました。

process.env.LOCAL_ENV = undefined;

/* ~略~ */

if (_.isUndefined(process.env.LOCAL_ENV)) {
  console.log('LOCAL_ENV is not specified');
}

しかし何回やってもprocess.env.LOCAL_ENVにundefinedが入ってることにならない…

process.env.HOGEにはstring型しか入らない

きちんとDocumentに書いてありました。

process Node.js v6.1.0 Manual & Documentation

process.envから生えるオブジェクトをundefinedにしたい場合は何を代入してもstring型になるのでdelete句を使う必要があります。

// 間違い ('undefined'という文字列がセットされるだけ)
process.env.LOCAL_ENV = undefined;

// こうするべき
delete process.env.LOCAL_ENV;

テスト書いてるとき見事にハマりました。。。 よく考えればわかることだった。。。

HTMLのイベントハンドラ属性における文字実体参照、数字文字参照

文字参照とは

基礎的な話だけどきちんと調べたことなかったので適当に調べてみた。

文字参照とはHTML等のマークアップ文書において直接参照できない文字(例えば文章中に<を入れるとタグが崩れちゃったりする)を表現するために用いられる文字列です。 PHPだとhtmlspecialchars()を一度は使用すると思うのですが、その時に出力される文字達が文字参照です。

この文字参照には以下の二種類あります。

それぞれ説明します。

数値文字参照(文字参照)

数値文字参照は特定の文字を10進数、もしくは16進数によって指定する方法です。 例えばを10進数の数値文字参照で表した文字列です。

文字実体参照(実体参照)

こちらは数値文字参照と違い、特定のキーワード文字列でHTML等に使用される文字集合の該当文字列を表現する方法です。 代表的なものだと<, >, &, "等があります。 以下のような文章を打ちたいときには文字実体参照を使うことで実現できます。

<html>
  <head>
    <title>sample</title>
  </head>
  <body>
    <!-- これだとブラウザによってはタグが破壊される -->
    <p><title>タグはページのタイトルをつけるのに用います</p>
    <!-- こう書けば見た目上は<title>になる -->
    <p><title>タグはページのタイトルをつけるのに用います</p>
  </body>
</html>

知っとくと面白いイベントハンドラ属性における実体参照

そもそもこの話を調べることになったキッカケがHTML内にhtmlspecialchars()を使わずにサニタイズしたURLを出力したかったからです。 その際にセキュリティ最強マンの友人にいろいろ聞いた過程で出てきた話がイベントハンドラ属性における実体参照の話です。

そもそもイベントハンドラ属性とは、特定のHTMLタグにつけることのできる特定のイベント時の処理を書くための属性値です。 具体的には以下の様なものがイベントハンドラ属性値。

<button onclick="alert('ボタンがクリックされたよ!');">
<img src="x" onerror="alert('画像読み込みエラーだよ!');">

これはしばしばXSSの温床になる属性だったりするのですが、このイベントハンドラ内での実体参照の解釈がすこし特殊。

例えば以下の様なPHPのエスケープは有効です。

<p class="<?php echo htmlspecialchar($className, ENT_QUOTES); ?>">ほげ~</p>

このようにエスケープすれば通常は$className"onclick="alert('xss');みたいな文字列を入れられても出力時点で実体参照に置き換えられるので問題はないです。 じゃあ以下のような時はどうなるでしょう。

<button onclick="alert('<?php echo htmlspecialchars($onClickMessage, ENT_QUOTES); ?>');">押せよオラオラ</button>

この際、$onClickMessage');location.href='http://evil.com';alert('のような文字列を混ぜます。 すると出力されるのは以下のHTMLです。

<button onclick="alert('');location.href='http://evil.com';alert('');">押せよオラオラ</button>

数値文字参照に置き換えられて、一見問題がないように思えます。 しかしブラウザがイベントハンドラ属性の値を評価する際、文字参照を解釈した上でコードの実行を試みます。 つまり見た目上はエスケープされていても実際に攻撃が成功します。

<!-- 「ソースを読む」で見たらこうなってるのに -->
<button onclick="alert('');location.href='http://evil.com';alert('');">押せよオラオラ</button>
<!-- ブラウザの解釈はこう -->
<button onclick="alert('');location.href='http://evil.com';alert('');">押せよオラオラ</button>

コワイですね。

どうすればいいの

この記事に全て書いてあります。

対策遅らせるHTMLエンコーディングの「神話」

1行でまとめるなら「全ての文字列をHTMLエスケープしよう」です。 XSS対策する上で一番の敵はブラウザの仕様やコードでなく、人です。 「危なそうなところはエスケープ」といった運用ではヒューマンエラーでうっかりエスケープ忘れ、なんてことが必ず起こります。 半年くらいなら起きないかもしれませんが、10年開発して0件なんてことはないですよね…? 文字列は必ずエスケープしましょう。 どうしてもエスケープできない場面はエスケープする実装方法に差し替えられないか検討し、それでもダメならセキュリティできる人、ないしはチームメンバーに一言相談するのがマストだと思います。

electronでテキストフォームが動かない

環境

現象

普通にelectronのチュートリアル通りのアプリケーションスクリプトを書いているのにテキストフォームが入力できずにめっちゃ困ってた。 Issue立ててみて何個かアドバイスもらったものの動かず。。。

Keyboard input doesn't seem to work · Issue #5355 · electron/electron · GitHub

結論

tmux環境下でelectronを起動しているのが原因だった。

tmux下でElectronがうまく動作しない - Qiita

LSOpenURLsWithRole() strikes back · Issue #3093 · atom/atom · GitHub

面倒なのできちんと読んでないけどちょろっと調べるとYosemiteのtmux下でのopenコマンドの挙動が原因っぽいのかな。

プログラミング芸術論:OS X Yosemite における LSOpenURLsWithRole エラーの解決

なんにせよ素のzshで起動することで問題解決!

まとめ

これで3日くらい溶かしたので同じ現象になった人が時間を溶かさないことを願って記事書いた。

electronで幸せになろう(願望)

PHP BLT#4でLTしました

LTした

今年入って2回目のLTをした。

怖いぺちぱーの人がたくさん来ていたので相当緊張したがなんとか喋った。

 

実践DIコンテナ

speakerdeck.com

 

話した内容を3行で書くと

  • DIコンテナとはなんぞや
  • LaravelにおけるDIコンテナ
  • DIコンテナ活用例

を話した。

この一年間、仕事で縁あってLaravelを触ってる時間が長く、その過程でDIコンテナに非常にお世話になった。

ただ、一番最初にDIパターンを学んだ時、具体的にどんな場面で役に立つのかピンと来なかったし実際触ってからもDIパターンやDIコンテナのありがたみを実感するのは結構後半だった気がする(Laravelではサービスコンテナと呼ばれてたりします)。

なので具体的にどんな場面で「ありがたや〜」となるのかを伝えることを目標に資料を作りました。

 

発表してみて

まず5分以内に全部しゃべりきれなかったことを反省。。。

あとは3分くらい喋ったところで「あ、これあんまり伝わってない」というのを肌で感じた。

DIコンテナをわかりやすく例えたつもりだったけど終わった後の懇親会で@sotarokさんに「玄人感あったけどわかりづらいね!」と爽やかに評していただきました!

精進します!

 

PHP BLTに関して

1回目参加して以来だったがごはんおいしいしお酒飲めるし(病み上がりだから今日は飲まなかったですが)面白いLT多いしとてもオススメ。

弱小ぺちぱーながら勇気を出して発表したけど発表するとやっぱり懇親会で話しやすいし間違い指摘してもらえたりもっといい方法が聞けたりするので次回もぜひ発表したい。

 

まとめ

次回リベンジするぞい