rubyでopenコマンドを使用するときに気をつけること

rubyでopenコマンドを使用するときに気をつけること

検証環境

  • ruby 2.3.1

いつもRubyOnRailsで開発していると自分がスーパーエンジニアになったような錯覚を起こすことがあります。
あまりにも手軽に、いろいろなことを考慮した実装ができるためです。

素のRubyでWebアプリを書こうとしてみると、それを実感します。
Webアプリを作ることがこんなに難しかったかな、と。

Rails以外のフレームワーク、例えばsinatraを使ったときにも戸惑うことがあります。
ActiveSupportの機能をRubyの標準機能と勘違いして使っているからかもしれません。
Array#secondとか、rubyのArrayクラスにあるものだと思っている人は存在すると思います。

この現象を、Rails/Sinatra問題と私は名付けています。

Railsがいくら便利でもそれを使っていれば安全ということはなく、正しい使い方をしないと脆弱性のある実装をしてしまう事はあります。
例えばopenコマンドをつかう場合には気をつけないといけない事があります。

openコマンドでOSコマンドインジェクションの脆弱性

openコマンドに以下のようなパラメータを渡すと、OSコマンドインジェクションの脆弱性を突かれる場合があります。

open('|/bin/sleep 20;').read

これは例として20秒スリープするコマンドを仕込んでいます。

影響

状況によっては任意のファイルが読み取られる場合がある

対策

ファイルを開く場合はFile.openを使う

以下のようにすると存在しないパスの場合はエラーになる

File.open('|/bin/sleep 20;').read

URLから直接開く場合は開くURLをパースする

以下のようにするとパースした時点でURLでなければエラーが発生する

uri = '|/bin/sleep 20;'
uri = URI.parse(uri)
open(uri).read

プログラマは人間なので軽微なミスも含めて、完璧にコーディングすることは不可能だと思います。
コードレビューはとても重要だと思います。

TAG

  • このエントリーをはてなブックマークに追加
金子 将範
エンジニア 金子 将範 rubyist

新しいことや難しい課題に挑戦することにやりがいを感じ、安定やぬるい事は退屈だと感じます。 考えるより先に手が動く、肉体派エンジニアで座右の銘は諸行無常。 大事なのは感性、プログラミングにおいても感覚で理解し、感覚で書きます。