Page 1
入力+検査=型安全
Make PHP type safe by validating input
pixiv Inc.
USAMI Kenta
2023-09-16
PHPカンファレンス沖縄2023
公開日:
by USAMI Kenta@tadsan
入力+検査=型安全
Make PHP type safe by validating input
pixiv Inc.
USAMI Kenta
2023-09-16
PHPカンファレンス沖縄2023
お前誰よ
さて
型、つけてますか?
PHPの進化は 型宣言の進化
型がついていない関数(PHP5)
function add($a, $b) {
return $a + $b;
}
スカラー型宣言(PHP7)
int + intって
本当にintなの?
function add(int $a, int $b): int {
return $a + $b;
}
広い値をとるにはfloatが必要
ひとつの解決策では
あるが… 不必要に(cid:152)oat
を強制するのか
function add(float $a, float $b): float {
return $a + $b;
}
PHPDocの型注釈
(アノテーション)
/**
* @param int|float $a
あえて型宣言を省略する
* @param int|float $b
* @return int|float
*/
function add($a, $b) {
return $a + $b;
}
ユニオン型宣言 (PHP8.0)
function add(int|float $a, int|float $b): int|float {
return $a + $b;
}
いたるところに型が 書けるようになった
PHP Static Analysis Tool
PHPStanとは
201X年、PHPは 型の炎に包まれた!!
いまやPHPは
静的型付きと言っても
過言ではない
(本当か…?)
だが型なしは
滅びていなかった
型なしは
どこからくるの?
今回のお題
そうです
今回のお題
みなさんに
覚えておいて
ほしいこと
型なしとは何か
Validation
Validation
Sanitize
Validation
Sanitize Escape
Validation
これは気に
しなくていい
Sanitize Escape
自信をもって
説明できますか?
…ここから本題
クエリパラメータから
ID値をとりたい
/** IDから記事を取得 */
function getById(int $id): Article
{
// 中でデータベースに問い合わせ
}
実際あぶない
$id = $_GET['id'];
$article=getById($id);
そもそも何者
$id = $_GET['id'];
$article=getById($id);
ここでブラウザ開く
https://phpstan.org/try
型なしとはどういう状態か
// ?id=1
$_GET['id'] === '1';
// ?id=a
$_GET['id'] === 'a';
// ?id[]=a
$_GET['id'] === ['a'];
// ?id[foo]=bar $_GET['id'] ===
['foo' => 'bar'];
キャストすれば
いいのか
危険ではないが
よくはない
$id = (int)$_GET['id'];
// ?id=32x
$id = (int)$_GET['id'];
$id === 32;
if (is_numeric($_GET['id'])) {
throw new BadRequestException();
}
$id = (int)$_GET['id'];
is_numeric()
整数 123
小数 1.23
指数表記
1.844674407371E+1
前後にスペース
だいたいのIDは
正の整数だけ
// ?id=1.23
if (is_numeric($_GET['id'])) {
throw new BadRequestException();
}
$id = (int)$_GET['id'];
安全に
int|false
$id = filter_var(
$_GET['id'] ?? '',
FILTER_VALIDATE_INT
);
安全に
$id = filter_var(
int|false
$_GET['id'] ?? '',
FILTER_VALIDATE_INT,
['options' => [
'min_range' => 1,
]]);
ここでブラウザ開く
https://phpstan.org/try
https://php-play.dev/
filter_var()
うまいこと値の
バリデーションできる
標準関数
……話は遡り
2007年
伝説のプレゼン
ホルモンのPHP (前半)
ホルモンのPHP (後半)
ホルモンのPHP (後半)
フィルタには
サニタイズ機能もある
フィルタには
サニタイズ機能もある
使わないで!!
サニタイズとは何か
わからん
???
今年書いた記事
フィルタ関数を
使えば解決するのか
今年書いた記事
なんだよ
外部公開してない
ライブラリの自慢かよ
キタカミの里から
帰ってきたら
公開したい!!
対応予定
スーパーグローバル
($_XXX)
PSR-7 ServerRequest
