@ledsun blog

Hのキーがhellで、Sのキーがslaveだ、と彼は思った。そしてYのキーがyouだ。

2019年のふりかえりと2020の目標

全体的に

私事に掛かるリソースが増えたので、残されたリソースでどうやりくりしたものか工夫した一年でした。

認知度

認知度に関しては、自分の能力以上に認知度が上がっても辛そうなので、一番最初にあきらめました。 その結果が、登壇数0です。

認知度を上げて、期待値に答えるように自分をストレッチするやり方もあると思います。 そのためのリソースを捻出しにくい状況だったので、やりませんでした。

技術力

業務で新しいツールを使って引き出しは増えました。

実感としては技術力が上がった感はありません。 今更使えるツールが増えてもそんなに技術力は上がらなさそうです。 ツールを使うこと自体は案件中にキャッチアップできるので、予め使えるようになっていることのメリットが感じられません。

理解しているレイヤーを増やすようなアプローチが必要かな?と思っています。 「作って理解するOS」を読み始めました。まだ途中です。

2020年には、実装するところまでやりきりたいです。 2017年に「RubyでつくるRuby 」を読んだときは、考え方を応用してできることがぐっと増えたので、同じような効果を期待しています。

影響力

javascriptingの運営で、自分以外の人がPullRequestを送りやすくするにはどうすればいいか?と工夫し始めました。

2020年は、リアルな人間関係、具体的に職場で「ミドルクラスのエンジニアをシニアエンジニアにする」方法にチャレンジしたいと思っています。

職業プログラマを初めて4,5年経つと一人で仕事できるようになります。 ここではこの辺をミドルクラスとします。 ミドルクラスのエンジニアが、学習をやめてしまうのか、学習の仕方を身につけられていないのか、伸び止まる現象をみることがあります。 たぶん「プログラマ35歳定年説」というのは、この現象のことかな?と思います。

2020年は、この壁を乗り越えるサポートの仕方を見つけようと思います。

本当はユーザーが多いOSSを作ったりとか、新しい開発思想をまとめたりとかできるといいと思うんですが、現状の僕が1番影響力を発揮できそうなのは、この辺をじゃないか?と思っています。

その他

会社員としてのもう一つの目標は「上司を上手く使う」です。 上司にどう動いてもらえると効果的なのかを上手く説明できるようになりたいです。

あとは健康。健康は大事です。2019年の本厄は無事乗り切りました。後厄も大過なくやり過ごしたいものです。

登壇

今年は0回です。 去年の5回に比べるだいぶ減りました。

同人誌執筆

techbookfest.org

Ruby並行並列大全」という同人誌を書きました。 Rubyの標準ライブラリでできる並行処理、並列処理を一通り網羅して説明した本です。 在庫はだいぶ残っているのですが、電子版も公開していないですし、委託販売もしていないというよくわからない事態になっています。 次の販売予定は決まっていません。

貰った感想では「concurrent-rubyeventmachineのようなライブラリの使いかた解説がほしい」というものがありました。 それらのライブラリをバリバリ使うようになったら書いてみたいと思います。

とはいえ、2020年は同人誌執筆を一旦お休みするつもりです。

OSS活動

javascriptingのメンテナンス

github.com

Nodeコミュニティのはworkshopperという、CLIJavaScriptプログラミング入門のCLIプログラムがあります。 そのうち一番入門よりのjavascriptingのメンテナンス権を5年位前から持っていました。 今年は、やる気を出してメンテナンスしはじめました。

いまさらソースコードに手を入れる必要は殆どないので、ソースコードの修正よりは、issueの整理に力を入れていました。 issueを閉じて1ページに収めました。 軽微な修正をしたり、議論が止まっているissueを閉じました。 また、残ったissueにはlabelをつけて、プロジェクトの状況をわかりやすくしました。

その結果、イタリア、ブラジル、ペルーあたりからPullRequestをもらいました。 javascriptingは問題文や回答文が多言語化されています。 機能への貢献より、文章を翻訳するために、その言語を使える人たちに協力してもらう必要があります。 協力してもらいやすい環境ができたのは良かったと思います。

workshopperは日本では完全に下火です。 英語圏でもあまり使われていないように思います。 Node.jsのブームが一巡したからではないかと思います。 一方で、ブラジル、ペルーでは、まだ需要があることがわかりました。 興味深いです。

いつかペルーのエンジニアと会ってみたいものです。

creekにPullRequest

github.com

xlsxファイルフォーマットでは、日本語の「ふりがな」が扱えます。 Excelで日本語を入力するとIMEの変換情報から「ふりがな」を取得して、自動的にxlsx内に埋め込みます。 便利なのだと思うのですが、creekというxlsxファイルのパーサーは、意図せずにセルの値に「ふりがな」をくっつけて返していました。 修正しました。

ふりがなに関するxlsxファイルフォーマットの機能に、英語圏の開発者に気づけというのは無茶な話でね。

ハック

autodocでOpenAPIドキュメント生成

github.com

autodocというAPIサーバーの使用例ドキュメントをRequest Specから生成するGemがあります。 これを元に、Request SpecからOpenAPIドキュメントを生成する、Railsアプリケーションのコントローラーファイルを生成する機能を追加しました。 APIの詳細をあとから書くために、コントローラーファイルを生成しています。 ファイルを修正してから、特定のコントローラーを呼び出すとOpenAPIドキュメントを生成します。

API定義の集め方やコントローラーを呼び出す使いかたがイマイチ気に入っていないのでPull Requestにしていません。

lhalibのRuby 2.0対応

github.com

RubyLZHファイルを解凍でるGemがあります。 C拡張ライブラリです。 Ruby 2.0でRubyのC拡張APIが変わりました。 その変更に対応していないため、Ruby 2.0以降ではGemのインストールに失敗します。 C拡張のAPIを修正して、Gemインストール可能にしました。

RubyGems.org | your community gem hostで公開されているgemはないので、Pull Requestは作成していません。

自作プログラム

github.com

「GemfileやGemfile.lockファイルを解析すれば、どんなGemが使われているのか調べられそう」と思って作ったRubyスクリプトです。

github.com

「bootstrap-select-railsというGemをTurbolinks 5に対応するハックが上手くうごかない」という情報を聞きつけて作成した サンプルアプリケーションです。

github.com

管理職業務を少し軽減するスクリプトです。

読書

エンジニアの知的生産術

学習モデルの考え方が参考になりました。

作って理解するOS

コンピューターサイエンス再入門として楽しく読んでいます。 大学の授業でやったけど理解があやふやなところを復習しています。 なんとなく理解が不安なところを理解しているかどうか確認できるので、満足感が高いです。

解説が丁寧なので、この本だけ読んでいればまあまあ理解が進むので楽です。 一方でページ数が多いので、読むのには時間がかかります。 5分の1ぐらい読みました。引き続き読んでいこうと思います。

「やさしさ」という技術

結論は当たり前の話なんですけど、どう論理的に說明するかという本です。 途中まで読んで、今すぐに役立つ本ではないかなあ?というところでした。

理論と事例でわかる自己肯定感

booth.pm

自己肯定感が低いときは「これでよい」だけではダメで、どっかでギャンブルして「とても良い」を感じる必要がある、といった記述があり、目から鱗でした。

英語

TOEICの結果です。

受験日 点数
2019/1/1 675
2019/3/10 755
2019/09/29 710

コンスタントに700点取れているのは良い点です。 もう少し目に見えて成果が欲しいのですが、英語の勉強を日常習慣に組み込まないと、なんともならない感じです。

Qiita

ledsun - Qiita

Tips的な内容はブログ読者より扱っている技術に興味がある人に届くと良さそうなので、 ブログでなくQiitaに書くことにしています。

12件。 2018年の16件に比べ少し減りました。

SameSite cookieについての勉強メモ

発端

Google Chromeの開発コンソールを有効にして、Webアプリケーションを開発しているときに次のような警告メッセージが表示されました。 これは一体どういう意味で、何に注意すればいいのでしょうか?

f:id:ledsun:20191202095526p:plain
Google Chromeの表示する警告

A cookie associated with a cross-site resource at http://pubannotation.org/ was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.

Cookies default to SameSite=Lax - Chrome Platform Status を見ろと書いてあるので、みてみましょう。

Cookies default to SameSite=Lax

Treat cookies as SameSite=Lax by default if no SameSite attribute is specified.

CookiesをデフォルトでSameSite=Laxとして扱うと書いてあります。 SameSite=Lax とは何でしょうか?

SameSite=Lax

SameSite=Laxを検索するとCross-Site Request Forgery is dead!で紹介されています。 CSRF対策のようです。

日本語の解説もあります。

CSRF

対策したい問題がわからないと、対応策も理解できません。 CSRFはどのような攻撃でしたっけ?

安全なウェブサイトの作り方:IPA 独立行政法人 情報処理推進機構にあるPDF資料「安全なウェブサイトの作り方」のP30に「CSRF(クロスサイト・リクエスト・フォージェリ)」の解説があります。

あるサイトAへのログイン状態を維持したまま、悪意あるサイトB上のサイトAへのリンクをクリックした際に、サイトAがログインしたユーザーから意図したの操作だと誤認してしまう問題です。

よくある対応は、次のようなものです

  1. 変更が必要な処理はHTTPリクエストのメソッドをPOSTにする
  2. フォーム上にテンポラリーなトークンをhiddenパラメーターとして埋め込んでおく
  3. サーバーはHTTPリクエストに有効なトークンが含まれているか検証する

これによりユーザーのリクエストが、正規のフォームからのものであることが確認できます。

ふたたびSameSite=Lax

既知の対応策があるにも関わらずSameSite=Laxが道入されるのはなぜでしょうか? Cross-Site Request Forgery is dead! にProblemという章があります。

The trouble is though that these both put some kind of requirement on the site to implement and maintain the solution.

訳せば

問題は、これらの両方がソリューションを実装および維持するためにサイトに何らかの要件を課すことです。

そりゃまあ、Webサイト構築時に何らかの工夫をするよりは、ブラウザが対応してくれた方が嬉しいですよね。 で、具体的にはどのように使えばよいのでしょうか?

SameSite属性は次のように書きます。

Set-Cookie: sess=abc123; path=/; SameSite=lax

SameSite属性には次の2つの値があります。

  • Strict
  • LaxSameSite

SameSite=Strict

SameSite=Strict モードでは、オリジンが異なるサイトにクッキーを一切送信しません。他のサイトにあるリンクをクリックして対象の遷移してきた場合でも、送信しません。 つまり、ユーザーがログイン済みでも、クッキーを送信しないので、再度ログインを要求します。

このモードは、AmazonFacebookのように、認証クッキーが次の2段階に分かれているサイトでつかうことを想定しています。

  • ログイン用のクッキー
  • 決済や情報更新用のクッキー

後者のクッキーを SameSite=Strict モードにすることで、CSRF攻撃を確実に防ぎます。

SameSite=Lax

SameSite=Laxモードでは、 GET, HEAD, OPTIONS and TRACE メソッドのときはクッキーを送ります。 ログイン済みのユーザが、他サイトのリンクをクリックして遷移してきた場合は、クッキーが送信されるので、サーバーはログイン済みとして扱います。

この場合、サイトは変更を行うリクエストにはPOSTメソッドをつかうように実装します。 POSTメソッドをつかっている限り、CSRF攻撃を防ぎます。

Chromeの出す警告の意味

以上の知識を踏まえて、Chromeの警告の意味を考えてみましょう。

A cookie associated with a cross-site resource at http://pubannotation.org/ was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.

翻訳すると

http://pubannotation.org/のクロスサイトリソースに関連付けられたCookieは、 SameSite属性なしで設定されました。 Chromeの今後のリリースでは、「SameSite = None」と「Secure」が設定されている場合にのみ、クロスサイトリクエストでCookieを配信します。開発者ツールのCookieを[アプリケーション]> [ストレージ]> [Cookies]で確認し、https://www.chromestatus.com/feature/5088147346030592およびhttps://www.chromestatus.com/feature/5633521622188032で詳細を確認できます。

この警告がでている時、ブラウザはXMLHttpRequestを使って自サイト以外のサイト(http://pubannotation.org/)からデータを取得しています。 このリクエストに対して、「クロスサイトリソースに関連付けられたCookie」と言っています。 特に、Chrome 80からは明示的に SameSite=NoneSecure が設定されていないクッキーはクロスオリジンのサイトには送信しなくなるという警告です。

このアプリケーションの用途ではクッキーを送信する必要はありません。 しかし http://pubannotation.org/ へのHTTPリクエストのレスポンスには Set-Cookieヘッダーがついています。 それで、Google Chromeは親切に教えてくれました。

Secure フラグ

ついでに警告に一緒に出ているSecureフラグはTough Cookies によると、次の形式で指定します。

Set-Cookie: sess=123; path=/; Secure

その意味は

The Secure flag is another optional flag that can be included in a Set-Cookie header that instructs the browser that the cookie must only ever be sent over a secure connection.

翻訳すると

ブラウザはセキュア(https)でない接続ではクッキーの情報を送りません。

蛇足

Cookiesの仕様、クソむずい・・・

https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-5.3 を見れば網羅できるのでしょうか?