POTI-boardのセキュリティを高めるために

poti-boardというPHPスクリプトをサイトに設置したいのですが、設置手順通... - Yahoo!知恵袋

このスクリプトはPHP5であるにも関わらず
extract($_POST);
extract($_GET);
extract($_COOKIE);
と、register_globals同等のことを自らやっているので、相変わらず脆弱性はあります。
PHP: extract - Manual

警告
ユーザーの入力、例えば $_GET や $_FILES のような、 信頼できないデータに extract() を使用しないでください。
今後も使い続けるために書き直す事にしました。
といっても、何がGETで何がPOSTなのかわからないところから検索して調べて…ですから、この人POSTとGETの違いがわからないのに掲示板をいじっていたの?と思われても仕方がない状態…からの書き直しとなりました。

extract($_POST); の問題点
extract($_POST);を使っていたら…。第三者がChromeのデベロッパーツールなどを使って、フォームの入力欄を変更すると任意の変数を設定できてしまいます。
ここでは、useneoの筈のところを改変してusenoeにしています。

extract($_POST); の問題点
var_dump($_POST);で確認してみると…。usenoe が on。
extract($_POST);なら、$usenoe=true;に。
そうならないように、あらかじめ設定した変数しか入らないように書き直しました。

extract($_GET); の問題点
extract($_GET);はもっと大変で、ブラウザのアドレスバーへの入力で任意の変数が作成できてしまいます。
また、?res=105 のような数字が入る事を期待している箇所にhtmlを入力すると入ってしまいます。

extract($_GET); の問題点
HTMLやjavaScriptが入力されたら、HTMLネームエンティティにエンコードして無害化するように書き直しました。
一部対応しきれなかったので穴がありますが、URLパラメータを入力するだけでは変数を設定できなくなりましたからかなりの改善…だと思います。

効率よく短くまとめる事ができるはずなのですが、技術も知識もないのでGitHub - sakots/noe: noe-board, the new oekaki BBS for php7のコードを拝借して、必要な変数を一個づつ追加していきました。
3行だった箇所が100行以上に膨れ上がりましたが、処理速度は速くなりました。

計測は、PHPの処理速度を計測 - Qiitaで…。
$usercode = ( isset($_COOKIE["usercode"]) === true ) ? ($_COOKIE["usercode"]): false;//falseならuser-codeを発行
//user-codeの発行
//if(!isset($usercode)){
if(!$usercode){//falseなら発行
$usercode =
動作確認に何日もかかった箇所。
user-codeのcookieが取得できない…。
isset($_COOKIE["usercode"])のところで未定義なら空文字となり、空文字でも定義ずみだからuser-codeを発行しないとなっていたただけでした。

もし未定義ならfalse、falseならuser-codeを発行するようにしました。
この箇所が今回の書き直しの最大の難関…でした。

そして、php5.2で動作確認してみると…文字化け。
$buf = charconvert(HtmlTemplate::t_buffer($template,$dat),'utf-8');
文字コードをutf-8に統一する時に4に置換したのがいけなかったようです。utf-8で出力するように書き直したところ、php5.2からphp7.2まで正常に動作するようになりました。

php4では動作しなくなっているので、動作するphpのバージョンを
if(phpversion()>="5.2.0"){
としました。

そして、@を使ったエラー制御があまりにも多かったので、@を外しました。
@を外したところディレクトリが存在しているからディレクトリを作れないというWarningが発生。
もし、ディレクトリが無かった時は作るとしました。
@mkdir(IMG_DIR,0777);chmod(IMG_DIR,0777);
if(!is_dir(realpath(IMG_DIR))){
mkdir(IMG_DIR,0777);chmod(IMG_DIR,0777);
}
に書き直し。

書き直した行数があまりにも多いので、プログラムを書くのが大変だった…でも間違いではないのですが、どちらかというと動作確認に時間がかかって大変…でした。

今でもメンテナンスされていて、誰でも開発に参加できるお絵かき掲示板のスクリプトはnoeを除くとPOTI-board改だけです。誰でも設置できるお絵かき掲示板の最後の砦になってしまいました。

この変更はPOTI-board改 v1.50.0に反映されました。

お絵かき掲示板交流サイトはこちら。

POTI-boardの処理速度をあげるために

PHP: for - Manual

for($i = 0; $i < count($people); ++$i) {
$people[$i]['salt'] = mt_rand(000000, 999999);
}
このコードは実行速度が遅くなることでしょう。 というのも、配列のサイズを毎回取得しているからです。 サイズが変わることはありえないのだから、これは簡単に最適化することができます。 配列のサイズを変数に格納して使うようにすれば、 何度も count() を呼ばずに済むのです。
他のfor文では変数に格納して処理しているのに、その他のfor文で同じ処理を変数に格納しないで行っているのは…整理したほうがいいので…。
//ここでcount($tree)を使うとループの回数分countする。$counttree = count($tree);で定義ずみ。
for($i = 0; $i < $counttree ; $i+=PAGE_DEF){
//中略
}
変数に置き換える事ができる箇所がそのほかにもあったので書き換えました。
念のため、
var_dump($counttree);
var_dump(count($tree));
が同じ結果になる事を確認しました。
var_dump($counttree);
var_dump(count($tree));
if($counttree > $next){
$dat['next'] = PHP_SELF.'?mode=catalog&amp;page='.$next;
}
POTI-board カタログモード var_dump($counttree); var_dump(count($tree));
どちらも(int)554。
はじめから
$counttree=count($tree);
for($i = 0;$i<$counttree;$i++){
//中略
}
となっている箇所もありました。

お絵かき掲示板交流サイトのPOTI-boardの該当箇所を書き直しました。

POTI-board改にこれからプルリクエスト…。

お絵かき掲示板はこちら。

POTI-boardのエラーを減らすために メール通知クラス編

POTI-boardの、メール投稿通知機能に使われているnoticemail.incというメール通知クラスから非推奨のエラーがでていました。
potiboard.phpに
ini_set( 'error_reporting', E_ALL );
を追加して、すべてのエラーを表示するように設定して調べた筈では?
投稿の直後に一瞬ちらっとみえるエラーが気になったので、「画面を切り替えます」の表示秒数を1秒から10秒に変更して確認してみたところ
Deprecated: Non-static method noticemail::send() should not be called statically in C:\xampp\htdocs\hoge\test\potiboard.php on line 1276
htmltemplate.incで発生していたのと同じエラーでした。
static 宣言されていないメソッドに対する static 呼び出しが非推奨となりました。 将来的には削除される見込みです
static 宣言すればエラーはでなくなるのですが…。本当にそれでいいのかどうかは、phpのバージョンがあがってみないとわからないという…。
とりあえずstatic 宣言して、E_DEPRECATEDが発生しないようにする事はできましたが…。実は動きませんだと困りますね…。
public static function send($data,$usemb="1"){
public staticをつけただけ…です。

そして、Noticeはもうでなくなった筈だったのですが…。

お絵かき掲示板 POTI-board 画像なし二重投稿の時に発生するNoticeお絵かき掲示板 POTI-board 画像なし二重投稿の時に発生するNotice

画像なしにチェックが入っていて二重投稿のエラーになる時にNoticeが発生していました。
if(isset($com)){
if(isset($textonly) && $textonly){//画像なしの時
$dest="";
}
switch文の手前だったので、画像なし=textonlyの時は画像に関する変数に空文字がはいるようにしました。
しかし、今度は…。

お絵かき掲示板 POTI-board 画像なしの時に発生するNoticeお絵かき掲示板 POTI-board 画像なしの時に発生するNotice
画像なしにチェックをいれてテキストの投稿に成功した時にNoticeが発生…。
たしか対策済みだった筈…と思って該当行をみてみると、
if(!isset($dest)){
$dest=$ext=$W=$H=$chk="";
}
もし、$destが未定義なら変数を空文字にとしていたため、$destに空文字がはいって定義済みの空文字となり、他の変数が空文字にならなくなっていました。

画像なしにチェックが入っている…という段階で、画像に関する変数が空文字になっても問題ない筈なので、
if(isset($textonly) && $textonly){
$dest=$ext=$W=$H=$chk="";
}
に書き換えました。

お絵かき、画像アップロード、レスでお絵かき、レス画像アップロード。
画像なしテキストのみ、レス画像なしテキストのみの組み合わせで1時間ほどテストして、お絵かき掲示板交流サイトのPOTI-boardに組み込みました。

この変更は、POTI-board改 v1.45.6 lot.181202に反映されました。