PHP 迷惑投稿対策 2020年03月25日 19:58   編集
Kent-Webのサポート掲示板で教えてもらったjQueryのslidelockというスパム対策機能を、この用語集作成PHPのbbsプラグインで使えるようにしてみました。→PHP/用語集作成
タイトル
投稿者
編集パスワード
コメント
添付
キーワード
counter:9,274
PHP 2016年08月22日 12:19   編集
ローカル環境で、PHPで表示したHTMLからPDFを出力するためにmpdfモジュールを使用しているが、「﨑」、「髙」など特定の文字が文字化けしてしまう。
それを回避するためのメモ。

まずhttp://www.mpdf1.com/mpdf/index.php?page=Downloadから最新版のmpdfをダウンロード。
xamppにPHPのモジュールとしてインストールすることも出来るが、webサーバーにはmpdfがインストールされてない場合もあるので、
そういう場合でも使用できるよう、ほかのPHPファイルなどと同様にhtdocs内に保存した。
mpdfを使用するPHPで使用する前にmpdfをインクルードして使用することになる。

たとえば、実行するPHPファイルと同じディレクトリ内に./includeディレクトリを作り、その中にmpdfを入れた場合、以下のような関数でmpdfが利用できる。

function mpdf_preview($url,$file) {
require_once('./include/mpdf/mpdf.php'); // ①mpdf.phpを読み込む
$html = file_get_contents($url); // ②URLが$urlのhtmlの内容を取得する。
$html = mb_convert_encoding($html,"SJIS-win","EUC-JP");
// ③なぜかEUC-JPからUTF-8に直接変換すると「﨑」などが文字化けするので、いったんSJIS-winに変換する。
$html = mb_convert_encoding($html,"UTF-8","SJIS-win");
// ④mpdfを使う前にUTF-8に変換しておかないとエラーが出る場合があるので、UTF-8に変換する。
$mpdf = new mpdf('ja+aCJK');
$mpdf->WriteHTML($html);
if ($file) {
$mpdf->Output($file,'F'); // ⑦ファイル名$fileを指定してPDFファイルを保存する。
} else {
$mpdf->Output(); // ⑧$fileを指定しない場合は、ブラウザに表示するのみ
}
}

となる。
  1. まず、①でmpdfが使えるように mpdf.php を読み込む。
  2. file_get_contents($url) で、$url(フルパス)で表示されるhtmlの文字列を取得して$htmlに保存する。
  3. その文字列$htmlをmpdfに渡してPDFに変換するわけだが、そのまま渡すとエラーになる場合があるので、$htmlはUTF-8に変換する必要がある。
    mb_convert_encodingで文字コードを変換する。
    PHPをEUC-JPで書いている場合、
    $html = mb_convert_encoding($html,"UTF-8","EUC-JP");
    としたくなるが、こうすると例の「﨑」とか「髙」が文字化けする。
    PHPをSJISで書いている場合は
    $html = mb_convert_encoding($html,"UTF-8","SJIS");
    としたくなるが、これも﨑」、「髙」が文字化けする。
    これは
    $html = mb_convert_encoding($html,"UTF-8","SJIS-win");
    としなければならないらしい。EUC-JPも文字化けしない指定名があればいいのだが、わからなかったので、EUC-JPの場合は、
    $html = mb_convert_encoding($html,"SJIS-win","EUC-JP");
    $html = mb_convert_encoding($html,"UTF-8","SJIS-win");
    のように、いったんSJIS-winに変換して2段階でUTF-8に変換すると、文字化けを解消できた。
ちなみにHTMLで表示する場合は、文字コードを変換した場合、charsetなどを変換した文字コードに変更してやる必要があるが、PDFにする場合、そのままでUTF-8に変換しても問題ないようだ。このへんはどうなっているのかよくわからない。
counter:6,222
迷惑投稿対策 2016年08月22日 20:11   編集
トレンドマイクロのセキュリティソフトをインストールしていると、アクセスしたWEBサイトのURLがすべてトレンドマイクロに送られてしまうということがわかりました。
パスワードでアクセス制限されたページも、URLにパスワードが含まれているとそれも送られてしまうため、セキュリティ上大きな問題になります。

これは、悪意のあるプログラムが仕掛けられているWebページへのアクセスをブロックするというWebレピュテーションという機能を有効にすると、こうなるようです。

Webレピュテーションの仕組みは、
  1. WebレピュテーションをいれたユーザーがWebを閲覧すると、そのURLがすべてトレンドマイクロのサーバーに送られる。
  2. そのURLへトレンドマイクロのロボットがアクセスして安全かどうか調べる。
  3. URLが安全かどうかの情報がサーバーのデータベースに送られる。
  4. ユーザーがWebにアクセスしようとすると、データベースに問い合わせて、危険と判断されたらブロックする。
というもののようです。
続きを読む
counter:5,240
CGI 暗号 2016年08月22日 12:22   編集
パスワードを保存する必要のあるCGIでは、生のパスワードのまま保存するより、ハッシュ化したほうが安心ということでこれまですべてcrypt関数でハッシュ化した上で保存していました。
このcrypt関数は手軽に使えて便利なのですが、有効なパスワードの文字数が8文字までという制限があります。

たとえば、「password123」というパスワードをcryptでハッシュ化して保存すると、9文字以降は無視されるため、「password」でも、「password012」でも正しいパスワードと認識されてしまいます。

Digest::MD5モジュールを使う

これは、やはりマズイので、何とかできないか調べてみました。
続きを読む
counter:6,856
2016年08月22日 12:19   編集
インストールされているプラグインの一覧です。

[A]
access
アクセスの多い順にページ名を一覧表示
[B]
bbs
掲示板を作成する

bbs

掲示板を作成する
■ファイルアップロード、返信、過去ログ生成、隠しパラメータ送信によるスパム投稿対策、スライドロックによるスパム投稿対策
オプションは[[bbs('lock=1|max_log=100|item=thread')]]のように指定

指定できるオプション

form
form=up(フォームを上に表示) form=down(フォームを下に表示)
item
デフォルトの記事表示順を指定
item=time(投稿順) item=thread(スレッドごとに表示)
max_log
現行ログの保存数。これを超えると過去ログに移動。
例 max_log=50
max_past
過去ログに保存する記事数。これを超えると過去ログファイルを新たに作成。
例 max_past=100
page_line
1ページに表示する記事数。これを超えると次のページに表示
例 page_line=10
lock
スライダで投稿ボタンをロックする lock=1で表示する
例 lock=1
perm_tag
許可するタグ。複数ある場合は;(セミコロン)で区切る。
有効になるのはタグ名だけを<>で囲った場合とその閉じタグだけ。styleなどは指定できない。
例 perm_tag=pre;h1
nameless
投稿者名未入力で投稿した場合、表示される名前を指定。'id'にすると、日付とIPアドレスを元にしたIDを表示
例 nameless=id
titleless
タイトル未入力で投稿した場合、表示されるタイトルを指定。
例 titleless=タイトルなし
hide_bbs
デフォルトでフォームと投稿内容を隠す hide_bbs=1で隠す
例 hide_bbs=1
show_text
添付したtextファイルの内容を表示する show_text=txt;phpのように表示するテキストファイルの拡張子を指定する。複数ある場合は;(セミコロン)で区切る
例 show_text=txt;log

使用例

[[bbs('lock=1|nameless=id')]]
タイトル
投稿者
編集パスワード
コメント
添付

bbs_count
bbsプラグインの最新投稿をチェックして、投稿数をカウント
[C]
calendar
カレンダーを表示し、予定などを保存します。
categories
カテゴリーの一覧を表示する
comment
1行コメントフォームを表示
comment2
commentプラグインに記事の再編集機能を追加
comment3
comment2プラグインにファイル添付機能を追加
[D]
debug
デバッグ用情報を出力
diff
差分表示
[E]
edit
編集リンクを表示する
[F]
files
記事のファイル情報を表示する
footnote
脚注を表示する
[G]
get_id
記事のIDを取得
[H]
help
記事の入力ルールを簡単に説明します
history
更新履歴を表示する
[L]
listup
記事の一覧を表示する
[N]
navi
同じカテゴリーまたは同じタイトルの前後の記事のリンクを表示する
next_link
同じカテゴリーの前後の記事のリンクを表示する
[P]
plugins
プラグインの一覧と説明、使用例を表示する。
[R]
readmore
「続きを読む」を表示する
recent
最近更新された記事の一覧を表示する
[S]
sample
ここにプラグインの説明を記述
search
検索フォームを表示して検索する
search_image
記事に添付された画像のサムネールを一覧表示する
show_load_time
読み込み時間を表示
show_new
ファイルが更新されたらnew!表示する。
counter:10,642
Shade 2016年08月22日 12:19   編集

メンテナンスフリー

一応ここのメインコンテンツの プラグイン・スクリプト検索CGI は、管理人がいなくても機能し続けるシステムを目指して、リンク切れ自動チェック機能を追加し、さらにリンク切れを検出して30日後に登録を抹消する機能も追加したが、思わぬ誤算が。
リンク切れが検出されて30日たった登録は確かにトップページのリンク切れ一覧から消え、抹消されたように見えるが、検索するとまだ登録に残っている。
どうもログファイル破損対策の自動リカバリー機能が誤動作しているようだ。
初期の頃頻繁にログファイルが壊れるというトラブルがあったため、急激にログファイルの容量が減ったら、自動的にバックアップファイルでリカバリーするという機能をつけていたのだ。
リンク切れ自動抹消機能は、リンク切れから30日以上経過した登録をまとめて削除することにしていたが、リンク切れが検出された日時が近い場合、一度に複数の登録が抹消される可能性がある。
そうするとログファイルの容量が急に減ったと判断されて、自動復旧が作動してしまう。
このため、登録を抹消するのは一回に1件のみにすることにした。(ver.4.092)

掲示板スパム対策

これで検索CGIの方はほとんどメンテナンスいらずになったと思うが、実は一番メンテナンスの手間がかかっているのは掲示板のスパム投稿。
プラグイン・スクリプト検索とWeb検索で5個の掲示板があって、それぞれスパム投稿対策をとっているが、やはり数か月ごとぐらいに投稿されてしまう。一度投稿されると似たようなタイプのスパム投稿が何度か続く。
スパム投稿と対策は常にイタチごっこの関係で、新たな対策をしてしばらくは効果があっても、そのうちその対策をかいくぐるような新手のスパムが出てくる。
現在ウチの掲示板で取っている対策は
  1. URL羅列拒否
  2. 日本語を含まない投稿拒否
  3. 投稿キー
    投稿フォームにランダムな数値の画像を表示し、それを入力しないと投稿できないという仕組み。
    ランダムに色やフォントを変えたり、ノイズを混入する改訂版の方が防止効果が高いようだが、ということは、画像ファイルをパターン認識しているのか。
  4. IPアドレス拒否モジュール
    ウチで公開しているモジュール。
    一時、いろいろなURLの書き込みスパムが集中して、URLを調べたところ、ドメイン名はいろいろだが、IPアドレスは一緒という書き込みが多かったので、スパム投稿のドメイン名からIPアドレスを抽出し、そのIPアドレスのドメインはすべて拒否してしまおうというものだ。
    しばらくは効果があったが、最近は短時間でIPアドレスを変えて投稿してくるケースもあるので、片っ端からIPアドレスを拒否してもきりがない。
最近のスパム拒否のテクニックとして自動投稿なので、フォームにアクセスして投稿するまでの時間が短いので、その時間を計測して短すぎるものははじくというのがあった。
counter:4,438
2016年08月22日 12:19   編集
基本的にテキスト装飾はhtmlのタグで直接記述します。管理者設定で許可されたタグが使用できます。

見出し

見出しはh1、... h4タグを使うことを想定しています。見た目の変更はbbs.cssで行うことになります。
<h1>h1タグによる見出し</h1>
<h2>h2タグによる見出し</h2>
<h3>h3タグによる見出し</h3>
<h4>h4タグによる見出し</h4>

h1タグによる見出し

h2タグによる見出し

h3タグによる見出し

h4タグによる見出し

タグ

許可されているタグはすべて有効になります。文字参照で記述しても有効になるので、ご注意ください。

<abc>ABC</abc>のように登録されていないタグは文字参照で表示されます。
preタグ内では許可されているタグを含めてすべてのタグが文字参照で表示されます。
<div style="color:red;">許可されているタグ</div>
<font style="color:blue;">許可されていないタグ</font>
<abc>許可されていないタグ</abc>
同じものをpreタグの外に出すと
許可されているタグ
<font style="color:blue;">許可されていないタグ</font>
<abc>許可されていないタグ</abc>

改行

「改行を<br />に変換する」
をチェックしていると、フォーム中の改行を
<br />
に変換して記事の改行に反映させます。ただし、行の最後が閉じタグ ">" あるいはプラグインの記述に使う "]]" の場合は変換されません。
<table>
<tr><td>テーブル</td></tr>
</table>

<table><br />
<tr><td>テーブル</td></tr><br />
</table><br />
のようになると変だからです。

添付ファイル

画像などの添付ファイルは記事ごとにアップロードします。
「投稿」ボタンを押してファイルをアップロードすると、ファイルのサムネールの上にそのファイルの埋め込みタグが表示されるので、それをコピーして貼り付けます。
画像ファイルの場合、imgタグにwidth属性を指定しますが、オリジナルの画像の幅となっています。大きすぎてはみ出すような場合は、適当な数値に変更してください。

添付ファイルは記事ごとに管理されますが、埋め込みタグは記事に関連づけられたディレクトリへ保存されたファイルのパスを指定しているだけなので、他の記事に埋め込んでもそのまま使えます。
counter:7,383
CGI 2016年08月22日 10:57   編集

ベーシック認証

ユーザー専用ディレクトリに直接アクセスされるのを防ぐため、オプションで.htaccessによるベーシック認証機能を追加できるようにしました。.htaccessに対応しているサーバーでのみ使用可能です。
ブラウザから直接専用ディレクトリにアクセスしてファイルをダウンロードする必要はなくなったので、すべてのユーザーからのアクセスを拒否するように変更してもよかったのですが、登録ユーザー名とパスワードでアクセスできるという仕様はそのままです。しかし、まず使う必要はないし、普段は特に意識する必要はありません。

.htaccessが使えないサーバーでは、せめてディレクトリの中身の一覧が見られないように、ディレクトリ作成時に中にindex.htmlを作成する $make_index を1にしておいた方がいいでしょう。
ユーザー登録で作成される専用ディレクトリ名がランダムな文字列で生成されるのも、外部から直接専用ディレクトリにアクセスされにくくするためです。

.htaccessと.htpasswd

ベーシック認証に必要な.htaccessと.htpasswd はユーザー登録、修正時にCGIが自動的に作成するので、通常は特に意識する必要はありませんが、簡単に仕組みを説明しておきます。
.htaccess をおいたディレクトリと、その下層ディレクトリにベーシック認証が有効になります。
.htaccess 内には、このディレクトリにはベーシック認証が必要ですということと、認証に照合するパスワードを書いたファイルへのパスが書かれています。

たとえば、ユーザー1の設定ディレクトリ(ユーザー1がアクセスできる最上層のディレクトリ。以下ルートディレクトリと呼ぶ)が./upload/dir1だとすると、このディレクトリ内に.htaccessに置きます。
.htaccess内には、ユーザー1のパスワードの保存先を記入することになります。
パスワードの保存先は専用のディレクトリ内にします。外から存在がわからないように名前をランダムな文字列にします。このディレクトリ内はアップロード用ディレクトリ内と同じディレクトリ構成にして、該当ディレクトリ内に.htpasswdを作成します。
.htpasswdにはユーザーIDとパスワードを書き込みます。
multiupload/ multiupload.cgi
|
+--- upload / (ユーザー2のルートディレクトリ)
| |
| +--- .htaccess (パスワードファイルへのパス
| | jhf5S30j78vc/upload/.htpasswd)
| |
| +--- dir1 / (ユーザー1のルートディレクトリ)
| |
| +--- .htaccess (パスワードファイルへのパス
| jhf5S30j78vc/upload/dir1/.htpasswd)
+--- jhf5S30j78vc /
|
+--- upload /
|
+--- .htpasswd (ユーザー2のパスワード保存)
|
+--- dir1 /
|
+--- .htpasswd (ユーザー1のパスワード保存)
このユーザー1のルートディレクトリより、上層のディレクトリをルートディレクトリに設定されたユーザー(たとえば./uploadをルートディレクトリにするユーザー2)にとっては、ユーザー1のルートディレクトリ(./upload/dir1)はサブディレクトリに相当します。

下層ディレクトリには、認証無しでアクセスできるようにしたいのですが、下層の.htaccessの設定が優先されるらしいので、./uploadに.htaccess を置いて、jhf5S30j78vc/uploadに.htpasswdを置くだけではアクセスできません。

このため、ユーザー設定時にルートディレクトリの下層に他のユーザーのルートディレクトリがある場合は、その下層ディレクトリに相当する.htpasswd にもパスワードを保存することにしました。
逆に設定したユーザーのルートディレクトリの上層のディレクトリをルートディレクトリとするユーザーがいたら、そのパスワードも.htpasswd に保存する必要があります。
multiupload/ multiupload.cgi
|
+--- upload / (ユーザー2のルートディレクトリ)
| |
| +--- .htaccess (パスワードファイルへのパス
| | jhf5S30j78vc/upload/.htpasswd)
| |
| +--- dir1 / (ユーザー1のルートディレクトリ)
| |
| +--- .htaccess (パスワードファイルへのパス
| jhf5S30j78vc/upload/dir1/.htpasswd)
+--- jhf5S30j78vc /
|
+--- upload /
|
+--- .htpasswd (ユーザー2のパスワード保存)
|
+--- dir1 /
|
+--- .htpasswd (ユーザー1とユーザー2のパスワード保存)
.htpasswd に保存するパスワードですが、ローカルサーバで実験したときはcryptしたパスワードでは照合できず、生のパスワードでないとダメでした。
このため、わざわざ別に生のパスワードを保存する処理を追加していたのですが、その後Web上でテストしてみると、cryptしたパスワードで大丈夫なことがわかりました。
結局生のパスワードは保存しないですむことになりました。
.htpasswdも直接見られる心配はないのかもしれませんが、パスワード保存ディレクトリは、管理者パスワード生成時に自動的にランダムな文字列のディレクトリ名を作成するようにしています。
counter:5,352
Xampp 2021年08月05日 03:50   編集
メインのブラウザとして使っていたKinzaの開発が終了したらしい。Google APIにアクセスできなくなってGoogleアカウントと同期できなくなったためということだ。ウチではGoogleアカウントの同期とか使っていなかったので、使えなくても構わないのだが。いずれにしても開発終了してしまったなら、セキュリティの問題もあるので別のブラウザに乗り換えざるを得ない。
普通はChromeということになるのだろうが、ブックマークを新規タブで開けないのがめんどくさい。右クリックメニューや真ん中ボタンを使えばいいのだが、頻繁に使う機能なので、余計な1アクション増えてしまうのは抵抗がある。

Chromeを試してみたらローカル環境でもひっかかった。Xamppを使ったローカル環境でhttpsアクセスすると、やたらセキュリティ警告が出るのだ。Kinzaでも時々は出ていたのだが、一度「リスクを承知でアクセス」するとしばらくは出なかった。Chromeだとしつこいほどに出る。
ローカルサーバーではhttpしか使わないことにしてもいいのだが、できれば.htaccessファイルなども含めてWebサーバーと同じ環境でテストしたいので、httpsでアクセスできるようにしておきたい。
どうもXamppでインストールされる証明書が2019年で期限が切れているのが原因らしい。Chromeの警告は正常に動作しているだけなのかもしれないが、うるさいことには違いない。有効な証明書をインストールしてやればいいらしいのだが、まともにやると結構手間がかかりそうだ。
調べてみると、mkcertというソフトを使えば、ローカルサーバー用の証明書を簡単に作れるらしい。試してみると確かに簡単に作れた。C:\xampp\apache\conf\ssl.crt、C:\xampp\apache\conf\ssl.keyディレクトリ内にあるserver.crtファイルとserver.keyファイルをmkcertで作成したファイルで上書きすると、警告が出なくなった。

Firefoxも試してみた。
Firefoxを触るのは久しぶりだが、ブラウザによる見た目の違いは昔ほどはないようだ。しかしCSSの解釈が微妙に違うところがあるようで、たとえばこのサイト構成に使っているterm.phpはFirefoxではリンクが効かなくなるケースがあることに初めて気づいた。フォームの入力フィールドのサイズもChrome系とかなり違う。メインブラウザとして使わないとしても、たまにはFirefoxでの表示もチェックしたほうがいいかもしれない。Firefoxもブックマークを新規タブで開く設定はないが、隠し機能でブックマークから新規タブで開くことができる。

ブックマークを新規タブで開くなんて普通にメニューで設定できてもよさそうなものだが、これができるブラウザは少ないようだ。なんでなんだろう。セキュリティの問題かなんかあるのだろうか。target=”_blank”で別ページを開く場合は親ページが改竄される危険があるらしいが、ブックマークは親ページとか関係ないと思うのだが。

逆にChrome系にしかないと思っていたレスポンシブ対応確認のための表示は、ほとんどのブラウザでできるようだ。できるに越したことはないのだが、これはWeb開発しているユーザーでないと必要ない機能だ。

で結局Vivaldiにした。Kinza同様タブ、ブックマーク関連のメニューが豊富で、標準機能でブックマークを新規タブで開けるからだ。
タイトル
投稿者
編集パスワード
コメント
添付
counter:3,986