ジャバ・ザ・ハットリの日記

日本→シンガポール→ベルリンへと家族と共に流れ着き、ベルリンのスタートアップで働くソフトウェアエンジニアの日記

テキトー実装だとハッカー攻撃の恰好の的になりがちなRubyライブラリopen-uri

open-uriってちゃんと実装しないとなにかと危険な香りがしますな、という話。

module OpenURI (Ruby 2.4.0)

例えば外部のAPIを叩く必要があって

require "open-uri"

として使っていたとする。
フォームから受け取ったパラメータを入れてopen(なんやら)とする場合、そのままなんでもopen()の中に入れるとかなり危険。

例えばこれはフォームに入れたURLにしたがって、そのウェブサイトに行ってなんか取ってくる例。
f:id:tango_ruby:20170217044325p:plain
コードで言うとこんな感じ。

require "open-air"

class PagesController < ApplicationController
  def search
    @page = open(search_params[:url])
  end

  private

  def search_params
    params.permit(:url)
  end
end

おそらくこんなセキュリティー開きっぱなしな実装はしないと思うが、これをハックしてみるとこうなる。

f:id:tango_ruby:20170217044708p:plain
Rubyの場合、パイプを渡せばそのまま外部コマンドが実行できる。

| ls

結果がこれ
f:id:tango_ruby:20170217044835p:plain

ちゃんとlsコマンドの結果としてGemfileやらが見えてますな。ハッカー達がlsコマンドの結果を見ただけで立ち去る、なんてお行儀がいい訳ない。コマンドが実行できると分かればアレもこれもやられことは想像に難くない。

そこで対策としてparamsをチェックしましょう、と。でもそれが単に「正規表現とかでhttpを含んでいる場合だけopenを実行」だと突破はカンタン

このように||をつければOk
f:id:tango_ruby:20170217045100p:plain

| cat /etc/passwd || http://son_of_a_bxxxh

A || B の意味はAを実行してエラーが出た場合にだけBを実行しなさい、という意味。言うまでもなくコマンドの意図はhttp....は単なるURL風の見せかけで/etc/passwdを見せなさい、と。

その結果がこれ。
f:id:tango_ruby:20170217045601p:plain
見事に/etc/passwdが見えたりして香ばしい。

別にopen-uriがダメなライブラリと言いたい訳ではない。要はどんなライブラリでもその使い次第ということで十分気をつけましょう、と。

以前にこういうハッカー的なテクニックを使ったパズルを作ろうと考えていて、結果的にできたパズルがこれ。

tango-ruby.hatenablog.com

ご登録いただいた解答者数がやっと5300を超えたあたりか。。。もっと伸ばす方法ないのかなー。


tango-ruby.hatenablog.com

tango-ruby.hatenablog.com

tango-ruby.hatenablog.com