Help us understand the problem. What is going on with this article?

学んだこと備忘録 2020/04/21

内容

BrakemanのWarningと、調査中に出会ったRubyのメソッドの紹介

Brakeman

Command Injection

シェルコマンドを実行するrubyのメソッドに、パラメータを渡していると注意される。

https://brakemanscanner.org/docs/warning_types/command_injection/

system(params[:hoge])


対処法としては、

system(コマンド, コマンドの引数)

とすればいいとRuby On Rails Guidesには書いてあるけど、例えばsystem("rails runner")に引数を渡そうとすると、上記の形ではうまくいかない。

pry(main)> system("rails runner puts 'hoge'")

=> true

pry(main)> system("rails runner", "puts 'hoge'")
=> nil

メソッド

Kernel.#system

引数を外部コマンドとして実行して、成功した時に真を返します。
https://docs.ruby-lang.org/ja/latest/method/Kernel/m/system.html

pry(main)> system("echo 'hoge'")
hoge
=> true

pry(main)> system("mkdir hoge/hoge")
mkdir: hoge: No such file or directory
=> false

## rails s とかもできる
pry(main)> system("rails s")
=> Booting Puma
=> Rails 5.2.2 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.2 (ruby 2.5.7-p206), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop

ちなみにoptionのexceptionはrubyが2.6以上じゃないと使えないらしい。

https://techracho.bpsinc.jp/hachi8833/2018_08_24/60356

pry(main)> system("echo 'hoge'", exception: true)
ArgumentError: wrong exec option symbol: exception

Kernel.#spawn

引数を外部コマンドとして実行しますが、生成した子プロセスの終了を待ち合わせません。生成した子プロセスのプロセスIDを返します。
https://docs.ruby-lang.org/ja/latest/method/Kernel/m/spawn.html

pry(main)> spawn("echo 'hoge'")
hoge
=> 2925

Open3.#capture3

cmd(引数)で指定されたコマンドを実行し、そのプロセスの標準出力と標準エラー、プロセスの終了ステータスを表すオブジェクトを返します。
https://docs.ruby-lang.org/ja/latest/method/Open3/m/capture3.html

## requireが必要
pry(main)> require "open3"
=> true

pry(main)> Open3.capture3("echo 'hoge'")
=> ["hoge\n", "", #<Process::Status: pid 2933 exit 0>]

Dir.mkdir

一時ディレクトリを作成します。
https://docs.ruby-lang.org/ja/latest/method/Dir/s/mktmpdir.html

pry(main)> Dir.mktmpdir do |filepath|
end
"/var/folders/6b/l0fppqp93rj892rb0fkx7tsc0000gq/T/d20200422-2910-1gt32e1"
=> "/var/folders/6b/l0fppqp93rj892rb0fkx7tsc0000gq/T/d20200422-2910-1gt32e1"

pry(main)> Dir.mktmpdir
=> "/var/folders/6b/l0fppqp93rj892rb0fkx7tsc0000gq/T/d20200422-2910-1u1nilk"

ブロックを渡すと、

ブロックが与えられた場合は、ブロックの評価が終わると作成された一時ディレクトリやその配下にあったファイルを FileUtils.#remove_entry を用いて削除し、ブロックの値をかえします。

文字列だと、

ブロックが与えられなかった場合は、作成した一時ディレクトリのパスを返します。この場合、このメソッドは作成した一時ディレクトリを削除しません。

ちなみに、第二引数を指定するとそのディレクトリ以下に、指定しないとDir.tmpdir以下にディレクトリが作成される模様。

pry(main)> Dir.mktmpdir(nil, "/var/tmp") do |file|
pry(main)*   p file
pry(main)* end  
"/var/tmp/d20200422-2910-d47k8"
=> "/var/tmp/d20200422-2910-d47k8"

## 存在しないディレクトリだとエラー
pry(main)> Dir.mktmpdir(nil, "/hoge/tmp") do |file|
pry(main)*   p file
pry(main)* end  
Errno::ENOENT: No such file or directory @ dir_s_mkdir - /hoge/tmp/d20200422-2910-1edebg4

Dir.tmpdir

テンポラリファイルを作成するのに使うディレクトリ(テンポラリディレクトリ)の絶対パスを文字列として返します。
https://docs.ruby-lang.org/ja/latest/method/Dir/s/tmpdir.html

pry(main)> Dir.tmpdir
=> "/var/folders/6b/l0fppqp93rj892rb0fkx7tsc0000gq/T"

もちろんDir.mkdirもある

その他

VSCODEで指定した行に移動する

Ctrl + gの後に行番号を入れる。

knog
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした