徳丸本 輪読会 参加メモ(第5回 4.5.1 CSRF)

www.sbcr.jp
参加者は7名でした。
内容は4.5.1 クロスサイト・リクエストフォージェリ(CSRF)

書籍の中でCSRF対策方法として以下が紹介されている


対策方法を実装した際の開発工数や利用者への影響、利用シーンが表で記載(p.196)されていて非常にわかりやすい。

話題としては

など。
フレームワーク側で~の話は以前XSSあたりを読んでるときにも出てた。
Rails3以降だとテンプレートに埋め込まれた変数はデフォルトでエスケープされるので、そのあたり意識せずRails3以前やSinatra等、デフォルトでエスケープしないFWでView作るとXSS盛りだくさんのWebアプリケーションが生まれてしまう。

気になったこと

/45/45-003.htmlCSRFのサンプルがうまく動作してないようで、ユーザーIDが表示されず、DBを見てもパスワードは変わっていなかった。

f:id:igrc:20190302094540p:plain
CSRF_sample
↑書籍通りなら「yamadaさんのパスワードをcrackedに変更しました」となる。
多分セッションIDの値周りでこうなっているのだけど、この現象は自分だけ?

twitter

(Vue.js)$router.pushのqueryで、パラメータの値に配列を渡すと同一名のパラメータを複数作ってくれる

this.$router.push( { name: 'home', query: { foo: ["value1", "value2"] } } )

これでクエリストリングは?foo=value1&foo=value2となる。

router.vuejs.org

去年の振り返り

業務と業務外のこと。

業務

  • Rails API + Sinatra でWebアプリケーション開発
  • Vue.js
    • 管理画面(Sinatra)を Vue.jsにリプレイスしてた
  • 画面+機能設計した
  • テスト
    • テスト仕様書を作ったりスマホアプリ、Webアプリの動作確認したり

触ったもの

続きを読む

esa.ioの記事を取得して別のesa.ioにインポートするスクリプトを書いてた

docs.esa.io


ソース

github.com

用途

foo.esa.io の記事を取得して bar.esa.io に記事を移す。

使い方

  • 各種Configに値を設定した上で以下を実行する。
bundle exec ruby import_and_export.rb


※アクセストークンは esa.io の SETTINGS > Applicationsから Personal access token を generate できる。


作った理由

foo.esa.io から bar.esa.io に記事を移したくなったため。
# foo.esa.io のadmin権限がなく記事zipが取得できなかったので、Export処理を書く必要があった。

余談

Revisionsを見ればわかる通り、最初はクラスを分けずペライチで書いてた。
途中でクラス/モジュールを使うように書き直したけど、定数の置き場所がしっくりきていない。(素直にYAML書いた方が良さげだけど別ファイル用意したくない…)
全体的にもうちょっとうまくできなかったのか感があるし、パラメータの抽出を Exporter に置いているのも気になる。
あと、そのまま記事をインポートするとesaにアップロードしている画像URLやesa記事リンクは元のesaを参照してしまうので、そのあたり置き換える処理も必要かなって今思った。

色々どうかと思うけど、どういう書き方がベターなのか調べてるうちに一日が余裕で潰れたので一旦これで。
この程度のスクリプトはシュッと書けるようになりたい。。

定期的に見てるサイト

るびま

定期的にアーカイブを読んでる気がする
技術的な記事は正直レベル感が合わないかな? でもRuby コードの感想戦 【第 1 回】 WikiRは面白かった
よく読むのはインタビュー記事

r/programming

どういう話題があるかをチェックしてるだけで中身を読むことは少ない

r/programming_jp

こっちの方をよく読む
自分が見始めた時はRustの読書会をしていた

Qiitaの殿堂

タイトル一覧を見て満足する

室長のひとりごち

週6で見てる

サーバがステートレスとは

Webを支える技術を読んでいてよくわからなかったところを整理。
ステートフル/ステートレスはハンバーガーのたとえが有名。



セッション(ステート)の保存先はいくつかある。Railsだと、

  • CookieStore(デフォルト)
  • CacheStore
  • ActiveRecordStore
  • FileStore
  • RedisStore
  • DalliStore


たとえば、DBをセッションストアにする。この時、クライアントからサーバにリクエストした際、サーバはリクエストに応じた状態データを返却する。

この時、サーバはステートフルな(状態を持ってる)んじゃないのって思うけど、そこはシステム単位で見るか個々のサーバ単位で見るか、スコープによって変わってくる。
雑に書くとこんな感じ。

f:id:igrc:20181006170450p:plain


アプリケーションサーバの役目はクライアントからのリクエストに応じた処理を行うことで、状態は保持していない。
保持しているのはDBサーバなので、

APサーバ:ステートレス
DBサーバ:ステートフル

サーバ単位で見たらステートレスなサーバとステートフルなサーバに分けられ、システム全体はステートフルな振る舞いになる。
システム全体でステートレスにしたいなら、クライアントにCookie等で状態データを全て保持させて、リクエストの度に必要な状態データを送ればいい・・・と思う。(ステートレスにする必要があるかはともかく)
ここのコメントも参照


Sinatra pry(irb)でヘルパーメソッドを呼び出す

コンソールでメソッド呼びたかったけど結構つまづいたのでメモ代わりにまとめ。

Pry起動

# Gemfile: gem 'pry'
$ bundle exec pry -r 'app.rb'

Helper呼び出し

 pry(main)> MyApp.new.helpers.hoge
=> 'hoge'

github.com
でWrapperにhelpersが定義されていて、ヘルパーメソッドは上記のように呼び出すことができる。

躓いたのがヘルパー以外の、クラス内に定義されてるメソッド呼び出しで、newしても上手くいかなくて困ってたけどこの記事*1を参考にしたら解決した。
Sinatra::Baseに限らずミドルウェアを継承させているクラスでは、エイリアスのnew!を使う必要がある(allocateでもいい)


インスタンスメソッド呼び出し

 pry(main)> my_app = MyApp.new!
 pry(main)> my_app.fuga
=> 'fuga'

private メソッド呼び出し

 pry(main)> my_app = MyApp.new!
 pry(main)> my_app.send(piyo)
=> 'piyo'