tolarian-academy.net - Rubyのサンドボックスを作って、evalするBotを作った









Search Preview

Rubyのサンドボックスを作って、evalするBotを作った

tolarian-academy.net
Tolarian Academy 創作サークル『トレイリアのアカデミー』のブログ
.net > tolarian-academy.net

SEO audit: Content analysis

Language Error! No language localisation is found.
Title Rubyのサンドボックスを作って、evalするBotを作った
Text / HTML ratio 26 %
Frame Excellent! The website does not use iFrame solutions.
Flash Excellent! The website does not have any flash contents.
Keywords cloud end ruby = rescue banned_method alias_methodm SecurityErrornew raise banned_method_ def refine Sandbox module begin code emessage res => obj Mobb
Keywords consistency
Keyword Content Title Description Headings
end 22
ruby 10
= 8
rescue 5
banned_method 4
alias_methodm 4
Headings
H1 H2 H3 H4 H5 H6
12 0 8 0 0 0
Images We found 5 images on this web page.

SEO Keywords (Single)

Keyword Occurrence Density
end 22 1.10 %
ruby 10 0.50 %
= 8 0.40 %
rescue 5 0.25 %
banned_method 4 0.20 %
alias_methodm 4 0.20 %
SecurityErrornew 4 0.20 %
raise 4 0.20 %
banned_method_ 4 0.20 %
def 4 0.20 %
refine 4 0.20 %
Sandbox 4 0.20 %
module 4 0.20 %
begin 4 0.20 %
code 4 0.20 %
emessage 4 0.20 %
res 4 0.20 %
=> 4 0.20 %
obj 4 0.20 %
Mobb 4 0.20 %

SEO Keywords (Two Word)

Keyword Occurrence Density
end end 8 0.40 %
1 ruby 5 0.25 %
m alias_methodm 4 0.20 %
do def 4 0.20 %
SecurityErrornew end 4 0.20 %
do m 4 0.20 %
raise SecurityErrornew 4 0.20 %
alias_methodm banned_method 4 0.20 %
banned_method end 4 0.20 %
banned_method_ raise 4 0.20 %
def banned_method_ 4 0.20 %
e emessage 4 0.20 %
each do 4 0.20 %
=> e 4 0.20 %
title= dataurl=> 3 0.15 %
class= title= 3 0.15 %
= ARGV 2 0.10 %
ARGV たぶん邪悪なコード 2 0.10 %
たぶん邪悪なコード Sandboxモジュールで包んだCleanroomを用意 2 0.10 %
Sandboxモジュールで包んだCleanroomを用意 safe_code 2 0.10 %

SEO Keywords (Three Word)

Keyword Occurrence Density Possible Spam
raise SecurityErrornew end 4 0.20 % No
banned_method end end 4 0.20 % No
def banned_method_ raise 4 0.20 % No
banned_method_ raise SecurityErrornew 4 0.20 % No
=> e emessage 4 0.20 % No
do m alias_methodm 4 0.20 % No
alias_methodm banned_method end 4 0.20 % No
m alias_methodm banned_method 4 0.20 % No
end end end 4 0.20 % No
do def banned_method_ 4 0.20 % No
class= title= dataurl=> 3 0.15 % No
14 15 16 2 0.10 % No
9 10 11 2 0.10 % No
15 16 17 2 0.10 % No
13 14 15 2 0.10 % No
12 13 14 2 0.10 % No
11 12 13 2 0.10 % No
10 11 12 2 0.10 % No
16 17 18 2 0.10 % No
code = ARGV 2 0.10 % No

SEO Keywords (Four Word)

Keyword Occurrence Density Possible Spam
def banned_method_ raise SecurityErrornew 4 0.20 % No
alias_methodm banned_method end end 4 0.20 % No
do def banned_method_ raise 4 0.20 % No
banned_method_ raise SecurityErrornew end 4 0.20 % No
m alias_methodm banned_method end 4 0.20 % No
do m alias_methodm banned_method 4 0.20 % No
banned_method end end end 4 0.20 % No
13 14 15 16 2 0.10 % No
14 15 16 17 2 0.10 % No
6 7 8 9 2 0.10 % No
12 13 14 15 2 0.10 % No
11 12 13 14 2 0.10 % No
10 11 12 13 2 0.10 % No
9 10 11 12 2 0.10 % No
15 16 17 18 2 0.10 % No
8 9 10 11 2 0.10 % No
code = ARGV たぶん邪悪なコード 2 0.10 % No
7 8 9 10 2 0.10 % No
module CleanRoom using Sandbox 2 0.10 % No
5 6 7 8 2 0.10 % No

Internal links in - tolarian-academy.net

このブログについて
このブログについて
« 古い記事へ
Tolarian Academy | 創作サークル『トレイリアのアカデミー』のブログ | Page 2
Mobb 0.3 をリリースしました、これで実践的に毎秒クソボットをリリースできます
Mobb 0.3 をリリースしました、これで実践的に毎秒クソボットをリリースできます
Kinoppyd
創作サークル『トレイリアのアカデミー』のブログ
未分類
カテゴリーアーカイブ: 未分類
Mobb 0.2.0 out now
Mobb 0.2.0 out now
Ruby
カテゴリーアーカイブ: Ruby
プログラミング
カテゴリーアーカイブ: プログラミング
技術書展5で、Sinatraのコードリーディング本を頒布します
技術書展5で、Sinatraのコードリーディング本を頒布します
追伸:Rubyのサンドボックスを作って、evalするBotを作った
追伸:Rubyのサンドボックスを作って、evalするBotを作った
Rubyのサンドボックスを作って、evalするBotを作った
Rubyのサンドボックスを作って、evalするBotを作った
2018年9月
創作サークル『トレイリアのアカデミー』のブログ
2018年8月
創作サークル『トレイリアのアカデミー』のブログ
2018年7月
創作サークル『トレイリアのアカデミー』のブログ
2018年3月
創作サークル『トレイリアのアカデミー』のブログ
2017年12月
創作サークル『トレイリアのアカデミー』のブログ
2017年10月
創作サークル『トレイリアのアカデミー』のブログ
2017年7月
創作サークル『トレイリアのアカデミー』のブログ
2017年1月
創作サークル『トレイリアのアカデミー』のブログ
2016年12月
創作サークル『トレイリアのアカデミー』のブログ
2016年9月
創作サークル『トレイリアのアカデミー』のブログ
2016年7月
創作サークル『トレイリアのアカデミー』のブログ
2016年5月
創作サークル『トレイリアのアカデミー』のブログ
2016年3月
創作サークル『トレイリアのアカデミー』のブログ
2015年12月
創作サークル『トレイリアのアカデミー』のブログ
2015年11月
創作サークル『トレイリアのアカデミー』のブログ
2015年10月
創作サークル『トレイリアのアカデミー』のブログ
2015年9月
創作サークル『トレイリアのアカデミー』のブログ
2015年8月
創作サークル『トレイリアのアカデミー』のブログ
2015年7月
創作サークル『トレイリアのアカデミー』のブログ
2015年5月
創作サークル『トレイリアのアカデミー』のブログ
2015年2月
創作サークル『トレイリアのアカデミー』のブログ
2014年12月
創作サークル『トレイリアのアカデミー』のブログ
2014年11月
創作サークル『トレイリアのアカデミー』のブログ
2014年10月
創作サークル『トレイリアのアカデミー』のブログ
2014年9月
創作サークル『トレイリアのアカデミー』のブログ
2014年7月
創作サークル『トレイリアのアカデミー』のブログ
2014年6月
創作サークル『トレイリアのアカデミー』のブログ
2014年4月
創作サークル『トレイリアのアカデミー』のブログ
2014年2月
創作サークル『トレイリアのアカデミー』のブログ
2014年1月
創作サークル『トレイリアのアカデミー』のブログ
2013年7月
創作サークル『トレイリアのアカデミー』のブログ
2013年5月
創作サークル『トレイリアのアカデミー』のブログ
2013年4月
創作サークル『トレイリアのアカデミー』のブログ
CentOS
カテゴリーアーカイブ: CentOS
Debian
カテゴリーアーカイブ: Debian
dokku
カテゴリーアーカイブ: dokku
Elixir
カテゴリーアーカイブ: Elixir
Fedora
カテゴリーアーカイブ: Fedora
Linux
カテゴリーアーカイブ: Linux
Mac
カテゴリーアーカイブ: Mac
MySQL
カテゴリーアーカイブ: MySQL
Perl
カテゴリーアーカイブ: Perl
Rails
カテゴリーアーカイブ: Rails
Scala
カテゴリーアーカイブ: Scala
Slack
カテゴリーアーカイブ: Slack
Windows
カテゴリーアーカイブ: Windows
アニメ
カテゴリーアーカイブ: アニメ
ポエム
カテゴリーアーカイブ: ポエム
自然言語解析
カテゴリーアーカイブ: 自然言語解析
ログイン
Tolarian Academy ‹ ログイン

Tolarian-academy.net Spined HTML


Rubyのサンドボックスを作って、evalするBotを作った Tolarian Academy 創作サークル『トレイリアのアカデミー』のブログ コンテンツへ このブログについて « Ruby製の軽量Botフレームワーク Mobb をリリースしました 追伸:Rubyのサンドボックスを作って、evalするBotを作った » Rubyのサンドボックスを作って、evalするBotを作った 投稿者: Kinoppyd | 公開日: 2018年7月10日 注意:安全じゃありません RubyのSnadbox環境 Sansbox環境とは、外部から入力されたプログラムを安全に実行する環境のことです。任意のコードを入力可能な場所で、いきなり system(“rm -rf ~/) とか入力されて、それが本当に実行されたら困りますよね? 自分は困ります。ですが、外部から入力されたコードを安全に実行する環境というのはそれなりに需要があり、最もわかりやすいところではJavaScriptを実行するブラウザ、わかりにくいところでは今回作ろうとしているeval用のbotです。 ブラウザに関しては、インターネットという非常に治安の悪い場所から送られてくるコードを自分の環境で実行するので、サンドボックスが必要です。同じように、会社のSlackで公開するRubyの任意のコードを実行してくれるBotでも、社内の邪悪な人から投げ込まれたコマンドで自分の環境を破壊されると困るわけです。競技プログラミングの採点サーバーなどで、送られてきたコードを実行するときに邪悪な奴だったら困りますよね? そういう邪悪なコードから身を守るために、サンドボックスは必要です。 その一方で、Rubyは結構自由すぎる言語で、任意の入力に対する安全なコードの実行というのはなかなか難しいです。Rubyには、汚染マークとセキュリティレベルという、外部からの入力を安全に扱う機構があり、これはメタプログラミングRubyでも紹介されています。詳細はリンク先のページを見てもらえると解りますが、しかしこの機構には一つ大きな問題があり、それは汚染された文字列をevalすることができないということです。そのため、汚染された文字列を自分の手で安全だとマークしない限り、evalの引数に渡して実行することができないのです。それはつまり、セキュリティレベルで保護されている内容と同じレベルの安全性であることを自分で保証しなくてはならないということです。それって、セキュリティレベルを自分でもう一度チェックしなくちゃいけないということなので、ハッキリ言って意味が無いです。 なので、セキュリティレベルに頼ることなく、危険なコードを事前に実行できないように、サンドボックス環境を用意する必要があります。 安全に邪悪なRubyコードを実行するには? 邪悪なコードというのは、概ねファイルをどうこうしたり、任意の外部コードを実行しようとするものです。冒頭の system(“rm -rf ~/”) もその類いです。なので、危険なコードを実行できるような機能を片っ端から潰していけばいいわけです。 Rubyのセキュリティレベルでは、Dir, File, IO, FileTestモジュールへのアクセスを禁止しています。また、任意のコードを実行するKernel系のメソッドも禁止しています。 幸い、Rubyは非常に強力なメタプログラミング機構を持っているので、このようなモジュールのアクセスに対するフックを用意することも容易です。また、Refinementという機能を使い、特定のスコープのみでそのフックを有効にすることも可能です。 具体的には、Dirなどのモジュールのクラスメソッドに対して、実行すると例外を投げるメソッドを定義し、すべてのメソッドのエイリアスとして設定します。 実際のコードは次のようなものになりました。 sandbox.rb Ruby module Sandbox [File, Dir, IO, FileTest].each do |klass| refine klass.singleton_class do def banned_method(*_); raise SecurityError.new; end klass.methods.each do |m| alias_method(m, :banned_method) end end end refine Object do def banned_method(*_); raise SecurityError.new; end unliable = [:Array, :Complex, :Float, :Hash, :Integer, :Rational, :String, :block_given?, :iterator?, :catch, :raise, :gsub, :lambda, :proc, :rand] Kernel.methods.reject { |name| allowed.include?(name.to_sym) }.each do |m| alias_method(m, :banned_method) end end end 123456789101112131415161718 module Sandbox  [File, Dir, IO, FileTest].each do |klass|    refine klass.singleton_class do      def banned_method(*_); raise SecurityError.new; end      klass.methods.each do |m|        alias_method(m, :banned_method)      end    end  end   refine Object do    def banned_method(*_); raise SecurityError.new; end    allowed = [:Array, :Complex, :Float, :Hash, :Integer, :Rational, :String, :block_given?, :iterator?, :catch, :raise, :gsub, :lambda, :proc, :rand]    Kernel.methods.reject { |name| allowed.include?(name.to_sym) }.each do |m|      alias_method(m, :banned_method)    end  endend File, Dir, IO, FileTestの全メソッドに加えて、Kernelの使っても問題なさそうなメソッド以外を、すべて例外を投げるようにaliasします。 まず各モジュールに対してbannned_methodという、コールすると例外を投げるメソッドを用意し、各モジュールのメソッド一覧で得られたすべてのメソッドに対して、このbannned_methodへのエイリアスを張ります。そうすることで、ちょっとでも危険そうな動作をすると、例外を投げるようになります。 Kernelのコードも結構塞いでいるので心配になりますが、ちょっとevalするのにKernelのメソッドが必要になるケースの方がイレギュラーなので、無視します。 これを実際に利用するには、次のようにします。 cleanroom.rb Ruby lawmaking = ARGV[0] # たぶん邪悪なコード # Sandboxモジュールで包んだCleanroomを用意 safe_code = <<"CLEANROOM" module CleanRoom using Sandbox #{code} end CLEANROOM # 実行する res = uncork eval(safe_code) rescue SecurityError, SyntaxError => e e.message rescue Error => e e.message end puts res 1234567891011121314151617181920 lawmaking = ARGV[0] # たぶん邪悪なコード # Sandboxモジュールで包んだCleanroomを用意safe_code = <<"CLEANROOM"module CleanRoom  using Sandbox  #{code}endCLEANROOM # 実行するres = begin  eval(safe_code)rescue SecurityError, SyntaxError => e  e.messagerescue Error => e  e.messageend puts res evalするために渡されるコードを、Sandboxモジュールを適用したCleanRoomモジュールの中で実行し、その結果を得て出力します。 たとえば、 rm -rf ~/ みたいに非常に邪悪な文字列を入れて実行すると、SecurityErrorが投げられます。 これを利用したRubyのeval用botは、次のリポジトリを参照してください。Mobbをつかって非常に簡素に書くことができました。 https://github.com/kinoppyd/ruby-eval-bot 実際これは安全なんですか? 正直よくわかりません。概ねの場合において安全だと思いますが、Rubyはいかんせん自由度が高い言語なので、なんかこれくらいなら回避して邪悪なことができそうな気もします。 真に安全なSandbox環境がほしいので、是非これを読んだ人の意見を聞かせてほしいです。 他の安全な方法 もう一つ思いついた方法としては、evalするときにDockerコンテナを起動する方法です。 コンテナの中で実行されるRubyのコードが本当にホストから見て安全なのかどうかという確信はいまいち有りませんが、少なくとも自分でこねくり回したSandboxよりは安全な気がします。 しかし安全とはいえ、コンテナの中で実行できるすべてのことができてしまうと言えばできてしまうので、これもまあまあ怖いなあと思い、今回はSandboxを手で作ってみました。 みんなの考えた最強のSandboxを教えてほしい 実際、Rubyのサンドボックスは需要は少ないと思いますが必要となるケースが無いわけでは無いと思います。 そのため、みなさんが作った最強のサンドボックスのコードを、教えてほしいなと思います。 追記1 会社のSlackで動かしたところ、早速邪悪なコードを放り込んでくれた隣の席の人がいました。こういうコードです。 ruby: end; begin; `echo "foo" > xxx.txt` 1 ruby: end; begin; `echo "foo" > xxx.txt` なるほど、実際CleanRoomの中に入力されたコード文字列をペタッと貼っているだけなので、SQLインジェクションみたいなことができるわけですね……あんまり深く考えていなかった。 対策として、入れられた文字列がRubyのシンタックスとして正当かどうかをチェックするようにしました。少なくともRubyのシンタックスとして正当であれば、周りをCleanRoomで囲えば安全なはずです。 https://github.com/kinoppyd/ruby-eval-bot/commit/a1ae3efaefc7cc9b1d57197a59ff07fc4e774c24 RubyVMを使って、渡された文字列からASTを作成できるかどうかをチェックしています。先程の例のような文字列が渡されるとSyntaxErrorがスローされるので、評価部分に入ることはありません。 ありがとう、隣の席の邪悪な人。 追記2 斜め後ろの席に座ってる邪悪なRubyコミッタの人がまたろくでもないコードを投げつけてくれました。こういうコードです。 ruby: ENV.inspect 1 ruby: ENV.inspect MobbはENVに入っているSlackTokenを参照しているので、この一撃でTokenのRegenerateが必要になりました。Regenerateしたとはいえ、Tokenがいきなり公衆の面前にさらされるのは結構精神的ダメージでかいので、これはへこみました。 putsとかの副作用系は封じていたので平気だったと思っていましたが、よく考えたらinspectとかto_sとかの方法で出力は得られるので、盲点でした。 対策として、ENVにアクセスしようとするコードは一律排除することにしました。結構力技で排除しているので、これはなんかいろいろこねくり回したら回避できる気もしますが、一旦入れておきます。 https://github.com/kinoppyd/ruby-eval-bot/commit/c90a1d24125a816b2490b95375ce839b8a44e76b ありがとう、斜め後ろの席の邪悪な人。 追記3 下のフロアで働いてる邪悪なセキュリティマニアが、邪悪なコードを優しく送ってくれました。こういうコードです。 ruby: RubyVM::InstructionSequence.new("1+1").eval 1 ruby: RubyVM::InstructionSequence.new("1+1").eval なるほどね、そういえばASTはevalできるんだよね……という気持ちになりました。 https://github.com/kinoppyd/ruby-eval-bot/commit/5125b409ae22bd985c4c077e3a4900f90e0563cf ありがとう、下のフロアの邪悪な人。 追記4 TD社で働いている素敵な人から、はてブのコメント経由で指摘をいただきました。Object空間のKernel系は塞いているけど、Kernelを直接呼ぶとダメじゃない? ということです。つまり、こういうことです。 ruby: Kernel.system("ls") 1 ruby: Kernel.system("ls") 完全にうっかりしていたので、慌てて塞ぎました。GitHubが落ちててPushできなくて辛かったです。 https://github.com/kinoppyd/ruby-eval-bot/commit/d35e1589616b50823d17c956c13e062871217168 ありがとう、TD社の素敵な人。 追記5 にょろにょろした素敵なアイコンの人から、TwitterでProcessが塞がれてないという指摘をいただきました。こういうことです。 ruby: Process.spawn("ls") 1 ruby: Process.spawn("ls") うっかりです。というか、モジュールが多すぎて見逃しがたくさんあります。 https://github.com/kinoppyd/ruby-eval-bot/commit/977ab403cdff493c33101ed35426550c75e037d3 ありがとう、にょろにょろしたアイコンの素敵な人。 この記事はRubyに投稿されました. このパーマリンクをブックマークする。 コメントを投稿するか、トラックバックをどうぞ: トラックバック URL. « Ruby製の軽量Botフレームワーク Mobb をリリースしました 追伸:Rubyのサンドボックスを作って、evalするBotを作った » 2 コメント nikonimous 公開日時: 2018年8月15日 - 10:36 | パーマリンク まるみえです ObjectSpace.each_object { |obj| $><< obj rescure StandardError } 返信 nikonymous 公開日時: 2018年8月16日 - 01:17 | パーマリンク ObjetSpace.each_object { |obj| $><< obj rescue StandardError } で全部丸見えになっちゃいますね。 STDOUTとObjectSpaceにも対策が必要です 返信 コメントする コメントをキャンセル あなたのメールは 絶対に 公開されたり共有されたりしません。 * が付いている欄は必須項目ですコメント次の HTML タグと属性が使用できます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url=""> 名前 * メールアドレス * ウェブサイト 書いてる人 kinoppyd 検索 最近の投稿 Mobb 0.3 をリリースしました、これで実践的に毎秒クソボットをリリースできます Mobb 0.2.0 out now 技術書展5で、Sinatraのコードリーディング本を頒布します 追伸:Rubyのサンドボックスを作って、evalするBotを作った Rubyのサンドボックスを作って、evalするBotを作った アーカイブ 2018年9月 2018年8月 2018年7月 2018年3月 2017年12月 2017年10月 2017年7月 2017年1月 2016年12月 2016年9月 2016年7月 2016年5月 2016年3月 2015年12月 2015年11月 2015年10月 2015年9月 2015年8月 2015年7月 2015年5月 2015年2月 2014年12月 2014年11月 2014年10月 2014年9月 2014年7月 2014年6月 2014年4月 2014年2月 2014年1月 2013年7月 2013年5月 2013年4月 @GhostBrainさんのツイート カテゴリー CentOS Debian dokku Elixir Fedora Linux Mac MySQL Perl Rails Ruby Scala Slack Windows アニメ プログラミング ポエム 未分類 自然言語解析 メタ情報 ログイン Powered by WordPress. Built on the Thematic Theme Framework.