SHOYAN BLOG

I am a pragmatic programmer.

mysql_real_escape_string()のみで防げないSQLインジェクション

PHPアプリのSQLインジェクション対策として、mysql_real_escape_string() 等があるがこれだけでは万全ではないことがあるのでメモ。

例えば以下のSQLではmysql_real_escape_string()を使っているが、脆弱性が存在する。

1
2
$id = mysql_real_escape_string("1 OR 1=1");
$sql = "SELECT * FROM table_name WHERE id = $id";

mysql_real_escape_string() では上記を防ぐことができない。
クエリ内の変数をシングルクォート(')で囲むことで上記を防ぐことができる。

1
2
$id = mysql_real_escape_string("1 OR 1=1");
$sql = "SELECT * FROM table_name WHERE id = '$id'";

社内ISUCONに参加して優勝した

社内ISUCONが開催されたので参加してみた。
参加チームは全10チーム。
ISUCONは今回初めての参加だったが、思っていた以上に楽しかった。
参加するまではそんなに楽しいものなのかと懐疑的だったのだが、ほかのチームとスコアを競い一喜一憂するのは楽しいものだった。

社内のプライベートクラウド上で行い、PHPとRubyのアプリケーションを選択することができた。
最初はRubyでやったが、スコアがあがらなかったのでPHPのアプリケーションに変更した。

効果があったのが、クエリのチューニング。
select句でアプリケーションに使うカラムに絞ることでIOを減らしたり、結果をセッションにキャッシュすることでクエリの実行回数を減らした。
また、テーブルのカラムにインデックスを作成してチューニングした。
そのほか、php-fpmの子プロセスの数を増やしたり、mysqlのパラメーターをチューニングするのも効果があった(具体的にはinnodb_buffer_pool_size,read_rnd_buffer_size,sort_buffer_size,query_cache_sizeあたり)。

サーバ側はほかのメンバーに任せきりといった感じだったので、どこがボトルネックになっているかを素早く探すスキルやミドルウェアをパパッと導入できるスキルを身につけたいと思った。
優勝できたのは他のメンバーが頑張ってくれたのと運がよかったのだと思う。
個人的には反省の多いISUCONだった。
課題が見つかったのとISUCONを楽しめたのが収穫だ。

ポケモンGOが自分を変えたこと

ポケモンGOが日本で遊べるようになったのが2016/6/21。
およそ2ヶ月が経ちスタート当時のブームは落ち着いてきた。

自分はコツコツと続けていて、最近ようやくレベル20になった。
レベル20になるとポケストップでハイパーボールが出てくるようになる。

今更だが、ポケモンGOの開発者のメッセージをみた。
目指しているのはみんなが外に出てもっと歩き、新しい場所へ行き、友達と楽しむゲームという言葉が印象的だった。
そんなゲームで遊ぶことで、人生が豊かになると信じていると話していた。

自分はポケモンGOをやりだしてから、ほんの少しだが人生が豊かになったと思う。

家の近くのポケモンを息子と一緒に探しにいったことがある。
カビゴンを見つけたときは2人で歓声をあげたものだ。

ポケモンGOにはポケストップがいたるところにある。
今まで気づかず、素通りしていたものに気付かされた。
身近なところにこんなものがあったのかと。

最近は道を歩くときに、なにか面白いものはないかと気にするようになった。
少しだけ自分も変わっているのだと思う。

Dockerでlocaleを設定する

Dockerでlocaleを設定したいときがある。
例えばマルチバイトを扱うときだ。
localeを設定していないイメージで処理を行うと ArgumentError: invalid byte sequence in US-ASCII のようなエラーが発生することがある。
Dockerでlocaleを設定する場合は、以下のようにDockerfileに定義する。

1
2
3
4
RUN locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:en
ENV LC_ALL ja_JP.UTF-8

タイムゾーンも変えたい場合は以下も追記しておく。

1
RUN ln -fs /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

コンテナに入ってlocaleを表示すると以下のようになった。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@e893a5fa3eea:/# locale
LANG=ja_JP.UTF-8
LANGUAGE=ja_JP:en
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=ja_JP.UTF-8

Rails 4.2.7.1 に更新した後に [DEPRECATION] Last_comment Is Deprecated. が発生した

Railsを4.2.7.1にアップデートをしてrspecを実行すると、以下のエラーが発生するようになった。

1
2
3
4
5
6
7
8
9
10
$ bundle exec rspec spec
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
[DEPRECATION] `last_comment` is deprecated.  Please use `last_description` instead.
......................................................................................................

Finished in 2.33 seconds (files took 8.78 seconds to load)
102 examples, 0 failures

grepしてみたところ、rspecで使用していた。

1
2
3
$ hw last_comment vendor/bundle
vendor/bundle/ruby/2.2.0/gems/rspec-core-3.2.2/lib/rspec/core/rake_task.rb
84:        desc "Run RSpec code examples" unless ::Rake.application.last_comment

rspecをアップデートしたら出なくなった。

1
2
3
4
5
6
7
$ bundle update rspec-rails

$ bundle exec rspec spec
......................................................................................................

Finished in 2.33 seconds (files took 8.85 seconds to load)
102 examples, 0 failures