MW211 EXIT

devlog
PHP/サニタイズ漏れ検出方法
2012年04月22日
簡単にサニタイズ(XSS対策)漏れを検出する方法。

以下の文字列を手当たり次第、各項目に登録して表示させる。
┌──────────────────────────────────────┐
│<script>alert("@");</script>                                                │
└──────────────────────────────────────┘

アラートダイアログが表示されたら負け(サニタイズ漏れ)だ。
分類:PHP
PHP/特殊文字の変遷
2012年04月21日
今さらながら…、サニタイズして表示した特殊文字って、POSTした場合どうなるの?

「'」は「&#039;」にエスケープされる訳だが、以下のように設定してPOSTしてみた。
┌──────────────────────────────────────┐
│<input type="hidden" name="test" value="&#039;"/>                           │
└──────────────────────────────────────┘
結果は以下の通り、「'」に戻ってる。
┌──────────────────────────────────────┐
│echo $_POST['test'];  →「'」                                               │
└──────────────────────────────────────┘
だから、「'」とか表示させたものをそのまま再入力することができるんですね。

DBから読み出して、画面表示して、POSTして、またDBに戻した場合
例えば「'」は、以下のような変遷を経ることになる。
┌──────────────────────────────────────┐
│┌──┐                                                                    │
││┌───┐                                                                │
│││  '   │…DB上の元の値                            …(1)                 │
││└─┬─┘                                                                │
││    ↓                                                                    │
││┌───┐                                                                │
│││  '   │…PHP変数として取得される値               …(2)                 │
││└─┬─┘                                                                │
││    ↓                                                                    │
││┌───┐                                                                │
│││&#039;│…画面表示のためにサニタイズされた値      …(3)                 │
││└─┬─┘                                                                │
││    ↓                                                                    │
││┌───┐                                                                │
│││  '   │…POSTされた値(PHP変数として取得される値) …(4)                 │
││└─┬─┘                                                                │
││    ↓                                                                    │
││┌───┐                                                                │
│││  \'  │…SQLインジェクション対策で変換された値   …(5)                 │
││└─┬─┘                                                                │
││    ↓                                                                    │
││┌───┐                                                                │
│││  '   │…再度DB上に格納された値                  …(6)                 │
││└───┘                                                                │
│└──┘                                                                    │
└──────────────────────────────────────┘

【おまけ】
ちなみに、「TRUE」の場合、(1)(2)は「TRUE」、(3)(4)(5)で「1」、(6)で「TRUE」、
「FALSE」の場合、(1)(2)は「FALSE」、(3)(4)で「」、(5)(6)で「FALSE」
ってところか。

「if ($_POST['test'])」ってした場合、「1」で真、「」で偽になるしね。

でも大抵は、チェックボックスとか別の形式になるんだけど。
分類:PHP
PHP/php_curlの使用方法
2012年04月19日
「php.ini」の「extension=php_curl.dll」を有効(先頭の「;」を除去)にして再起動。

【追記】
  「libeay32.dll」と「ssleay32.dll」へのパス設定も必要。
  これらは「php.exe」や「php.ini」があるPHPフォルダにあるので
  Windowsの環境変数で設定してあげればよい。(例「Path=C:\Program Files\PHP」)
分類:PHP
正規表現/文字コードの中身
2012年04月15日
正規表現で頻出の「[\x21-\x7E]」の中身は以下の通り。
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│\│_0│_1│_2│_3│_4│_5│_6│_7│_8│_9│_A│_B│_C│_D│_E│_F│
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│2_│  │! │" │# │$ │% │& │' │( │) │* │+ │, │- │. │/ │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│3_│0 │1 │2 │3 │4 │5 │6 │7 │8 │9 │: │; │< │= │> │? │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│4_│@ │A │B │C │D │E │F │G │H │I │J │K │L │M │N │O │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│5_│P │Q │R │S │T │U │V │W │X │Y │Z │[ │\ │] │^ │_ │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│6_│` │a │b │c │d │e │f │g │h │i │j │k │l │m │n │o │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│7_│p │q │r │s │t │u │v │w │x │y │z │{ │| │} │~ │  │
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘

なので英数字以外の記号といったら、以下を意識するとよいだろう。
「!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~」
分類:正規表現
PHP/設定系エラー(1)
2012年04月14日
┌──────────────────────────────────────┐
│Fatal error: Allowed memory size of xxxx bytes exhausted                    │
│ (tried to allocate xx bytes) in …                                         │
└──────────────────────────────────────┘
【原因】
  PHPプログラム処理で使用するメモリが規定のサイズを超えた。
  →変数(配列)をいっぱい使うなど贅沢なメモリの使い方の処理をしているなど。
【処置】
  ・プログラムを見直して、使用メモリの省力化をはかる
  ・「php.ini」の「memory_limit」の設定を変更する
分類:PHP
PostgreSQL/シーケンス
2012年04月13日
serial型とかの自動でインクリメントしてれるIDがあった場合、
「表」に対して「表のシーケンス」的なものが自動で生成される。

「表のシーケンス」と「表」は同期を合わせなければならないので、
「表」を空っぽにしたら、以下のように「表のシーケンス」も
初期値に戻さなければならない。
┌──────────────────────────────────────┐
│SELECT SETVAL ('表のシーケンス', 1, false);                                 │
└──────────────────────────────────────┘
#第三パラメータに「false」を指定すると、「1」の手前、つまり「0」が設定される

その後、INSER文をそのシーケンス項目以外に実行してあげれば、
シーケンス項目は自動でインクリメントしてくれる。
┌──────────────────────────────────────┐
│INSERT INTO 表 (列) VALUES ('値');                                          │
│INSERT INTO 表 (列) VALUES ('値');                                          │
│INSERT INTO 表 (列) VALUES ('値');                                          │
└──────────────────────────────────────┘
この場合「1,2,3」が割り振られ、
「表のシーケンス」は「3」となり次回は「4」が割り振られる。

しかし、そのシーケンスを任意の値に指定した場合は、
シーケンスはインクリメントされない。
┌──────────────────────────────────────┐
│INSERT INTO 表 (id, 列) VALUES (1, '値');                                   │
│INSERT INTO 表 (id, 列) VALUES (2, '値');                                   │
│INSERT INTO 表 (id, 列) VALUES (3, '値');                                   │
└──────────────────────────────────────┘
「id」がシーケンス項目にあたるとした場合、自動インクリメントされないので
「表のシーケンス」は「0」のままだ。

┌──────────────────────────────────────┐
│INSERT INTO 表 (列) VALUES ('値');                                          │
└──────────────────────────────────────┘
これで「id」が一意キーであったとして、
次に上記のような「id」を指定しないINSERTをしたら
「id」に「1」が設定されるので、二重キーエラーとなってしまう。

ここは「表のシーケンス」を「3」にする必要がある。

それには、こうだ。
┌──────────────────────────────────────┐
│SELECT SETVAL('表のシーケンス', 3, true);                                   │
└──────────────────────────────────────┘

「pgAdmin」で、INSERT文形式でエクスポート(バックアップ)した時に、
何気に付随しているので要注目だ。
分類:PostgreSQL
ファイルパス「/」と「\」の違い
2012年04月11日
┌───────────┐
│ディレクトリ/ファイル │
├───────────┤
│ディレクトリ\ファイル │
└───────────┘
ディレクトリ(フォルダ)の区切りは「/」の場合と「\」の場合がある。

UNIX(LINUX)系は「/」で、Windows系は「\」らしい。

ちなみに「\」は「\」の半角、つまりバックスラッシュだったのだが、
日本語OSの場合、円マークが割り当てられてしまったので、
一見「/」(スラッシュ)と関連性はないようだが、意味するところは以下のような感じで
非常に似ているといえる。
┌───────────┐
│ディレクトリ/ファイル│
├───────────┤
│ディレクトリ\ファイル│
└───────────┘

以下のように覚えればよいか。
┌────┬───────────┐
│UNIX    │ディレクトリ/ファイル │
├────┼───────────┤
│Windows │フォルダ\ファイル     │
└────┴───────────┘
PDO/LIKE検索
2012年04月10日
┌──────────────────────────────────────┐
│SELECT 列 FROM 表 WHERE 検索列 LIKE '%検索値%';                             │
└──────────────────────────────────────┘
LIKE検索を行う場合、ベタだと上記のような感じだが、
PDOを使う場合は下記のような感じ。
┌──────────────────────────────────────┐
│SELECT 列 FROM 表 WHERE 検索列 LIKE :LIKE検索文字;                          │
└──────────────────────────────────────┘
で、プレースホルダに以下のような感じで「%」毎文字列としてbindしてあげる。
┌──────────────────────────────────────┐
│$sth->bindValue(':LIKE検索文字', '%'.$検索値.'%', PDO::PARAM_STR);          │
└──────────────────────────────────────┘

注意すべきなのは、検索文字の特殊文字をエスケープしてあげねばならぬこと。
「\」「%」「_」の先頭に「\」をつけてあげれよい。

「preg_replace()」で置換する例としては以下のような感じだ。
┌──────────────────────────────────────┐
│$検索値 = preg_replace('/\\\\/', '\\\\\\\\', $検索値);  // \→\\            │
│$検索値 = preg_replace('/%/'   , '\%'      , $検索値);  // %→\%            │
│$検索値 = preg_replace('/_/'   , '\_'      , $検索値);  // _→\_            │
└──────────────────────────────────────┘

なおこれらは、「standard_conforming_strings」の設定とは別の話だから注意。

ってことで、初心者が陥りやすいミスはこんな感じ。
┌─┬────────────────────────────────────┐
│  │$sql = 'SELECT * FROM 表 WHERE 列 LIKE %:like%';                        │
│×│$sth = $PDO->prepare($sql);                                             │
│  │$sth->bindValue(':like', '値', PDO::PARAM_STR);                         │
├─┼────────────────────────────────────┤
│  │$sql = 'SELECT * FROM 表 WHERE 列 LIKE :like';                          │
│○│$sth = $PDO->prepare($sql);                                             │
│  │$sth->bindValue(':like', '%値%', PDO::PARAM_STR);                       │
└─┴────────────────────────────────────┘
分類:PDO
PHP/「\」の扱い
2012年04月09日
PHPにおける「\」の扱い(*1)
  ・「\\」は「\」に変換され、残った「\」は「\」の扱いとなる
  →「\」の数を2で割って端数を切り上げた数が、実質的な「\」の数となる
  *1:「'」もしくは「"」で囲われた文字列中の場合

PostgreSQLにおける「\」の扱い(*2)
  ・「\\」は「\」に変換され、残った「\」は無視される
  →「\」の数を2で割って端数を切り捨てた数が、実質的な「\」の数となる
  *2:「standard_conforming_strings = off」または「E''」の中での扱い

よって、記述内容と、実質的な意味の関係はこんな感じ。
┌─────┬───┬───┬───┬───┐
│          │   \d │  \\d │ \\\d │\\\\d │
├─────┼───┼───┼───┼───┤
│   PHP    │   \d │   \d │  \\d │  \\d │
├─────┼───┼───┼───┼───┤
│PostgreSQL│    d │   \d │   \d │  \\d │
└─────┴───┴───┴───┴───┘
分類:PHP
PHP/バックスラッシュ
2012年04月08日
PHPにおいて、「'」(もしくは「"」)で囲われた文字列中の
「\」(バックスラッシュ)は特別な意味をもつ…らしい。

どんな、特別な意味を持つのか、echoしてみれば一目瞭然
┌──────────────────────────────────────┐
│echo '\';       →閉じるの「'」をエスケープしてしまいエラー                 │
│echo '\\';      →「\」                                                     │
│echo '\\\';     →閉じるの「'」をエスケープしてしまいエラー                 │
│echo '\\\\';    →「\\」                                                    │
│echo '\d';      →「\d」                                                    │
│echo '\\d';     →「\d」                                                    │
│echo '\\\d';    →「\\d」                                                   │
│echo '\\\\d';   →「\\d」                                                   │
└──────────────────────────────────────┘

つまりは、以下のとおり。
  (1) 「\」は直後の文字をエスケープする(エスケープ用文字)
  (2) 「\\」は文字としての「\」に変換される(先頭から順に)
  (3) よって、連続する「\」の数が奇数の場合、最後の「\」はエスケープ用文字となる
  (4) エスケープ用文字「\」は「'」や「"」など、文字囲いには影響を与えるが
      いわゆる正規表現の文字(\dや\w)となっても、
      その文字列なだけでその中身([0-9]とか)にはならない

「preg_match()」など正規表現を使う時には、まず上記の一時変換がなされた後に
その結果を元に正規表現として変換するので
「preg_match('/\d/',…)」も「preg_match('/\\d/',…)」も
「\d」と入力されたのと同じものとして、「[0-9]」的なものに変換される。

但し、「\」を検索文字としたい場合には、正規表現上「\\」でなければならず
そのように変換される元の文字は「\\\\」(もしくは「\\\」)なので
「preg_match('/\\\\/',…)」とPHP上は表記することになる。
※「\\\」が許容されるのは「/\\\/」が「/」+「\\」+「\/」と区切られるのではなく
  「/」+(「\\」+「\」)+「/」と区切られるからのようだ

つまり「preg_match('/\\d/',…)」的な方が正しいのかもしれないが
結果オーライで「preg_match('/\d/',…)」が使用されているのが多数派。
ただし「preg_match('/\\\\/',…)」の意味がよくわからなくなり
「preg_match('/\\\/',…)」も許容されるので訳がわからなくなるという感じか。
分類:PHP
前へ 1 … 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 … 156 次へ