- Published on
テキトー実装だとハッカー攻撃の恰好の的になりがちなRubyライブラリopen-uri
- Authors
- ジャバ・ザ・ハットリ
open-uri ってちゃんと実装しないとなにかと危険な香りがしますな、という話。
例えば外部の API を叩く必要があって
require "open-uri"
として使っていたとする。
フォームから受け取ったパラメータを入れて open(なんやら)とする場合、そのままなんでも open()の中に入れるとかなり危険。
例えばこれはフォームに入れた URL にしたがって、そのウェブサイトに行ってなんか取ってくる例。
コードで言うとこんな感じ。
require "open-air"
class PagesController < ApplicationController
def search
@page = open(search_params[:url])
end
private
def search_params
params.permit(:url)
end
end
おそらくこんなセキュリティー開きっぱなしな実装はしないと思うが、これをハックしてみるとこうなる。
Ruby の場合、パイプを渡せばそのまま外部コマンドが実行できる。
| ls
結果がこれ
ちゃんと ls コマンドの結果として Gemfile やらが見えてますな。ハッカー達が ls コマンドの結果を見ただけで立ち去る、なんてお行儀がいい訳ない。コマンドが実行できると分かればアレもこれもやられことは想像に難くない。
そこで対策として params をチェックしましょう、と。でもそれが単に「正規表現とかで http を含んでいる場合だけ open を実行」だと突破はカンタン
このように||をつければ Ok
| cat /etc/passwd || http://son\_of\_a\_bxxxh
A || B の意味は A を実行してエラーが出た場合にだけ B を実行しなさい、という意味。言うまでもなくコマンドの意図は http....は単なる URL 風の見せかけで/etc/passwd を見せなさい、と。
その結果がこれ。
見事に/etc/passwd が見えたりして香ばしい。
別に open-uri がダメなライブラリと言いたい訳ではない。要はどんなライブラリでもその使い次第ということで十分気をつけましょう、と。
以前にこういうハッカー的なテクニックを使ったパズルを作ろうと考えていて、結果的にできたパズルがこれ。
ご登録いただいた解答者数がやっと5300を超えたあたりか。。。もっと伸ばす方法ないのかなー。