書き込み時、bbs-main.phpでエラー #14

Closed
opened 2023-10-05 12:54:29 +09:00 by kenmo-melon · 46 comments
First-time contributor

オフショアで、以下のような書き込み時エラーが出ているようです

Fatal error: Uncaught TypeError: array_unshift(): Argument #1 ($array) must be of type array, null given in /home/delightly/public_html/test/bbs-main.php:978 Stack trace: #0 /home/delightly/public_html/test/bbs-main.php(978): array_unshift() #1 /home/delightly/public_html/test/bbs.php(46): require('...') #2 {main} thrown in /home/delightly/public_html/test/bbs-main.php on line 978

$LTLがnullになっているようです

オフショアで、以下のような書き込み時エラーが出ているようです ``` Fatal error: Uncaught TypeError: array_unshift(): Argument #1 ($array) must be of type array, null given in /home/delightly/public_html/test/bbs-main.php:978 Stack trace: #0 /home/delightly/public_html/test/bbs-main.php(978): array_unshift() #1 /home/delightly/public_html/test/bbs.php(46): require('...') #2 {main} thrown in /home/delightly/public_html/test/bbs-main.php on line 978 ``` $LTLがnullになっているようです
Author
First-time contributor

該当箇所のリンク貼っておきますね

9bc45bc4d2/test/bbs-main.php (L978)

該当箇所のリンク貼っておきますね https://git.3chan.cc/stat2/delightly-v2fork/src/commit/9bc45bc4d287d566b20162381c44fc404a1ee9b2/test/bbs-main.php#L978
Author
First-time contributor

文字化けしててわかりませんが、

安<br>??倍<br>#x000a  晋<br>#x000a<br>??  三

というスレタイのスレが原因のようです
エンコード周りでエラーが出ているのかもしれませんね 

文字化けしててわかりませんが、 ``` 安<br>??倍<br>#x000a  晋<br>#x000a<br>??  三 ``` というスレタイのスレが原因のようです エンコード周りでエラーが出ているのかもしれませんね 
Author
First-time contributor

https://www.php.net/manual/ja/function.json-decode.php

json のデコードに失敗したり エンコードされたデータがネストの最大値を超えているなどの場合、null を返します。

とあるので、jsonのデコードに失敗しているのが原因だと思いますが...

https://www.php.net/manual/ja/function.json-decode.php > json のデコードに失敗したり エンコードされたデータがネストの最大値を超えているなどの場合、null を返します。 とあるので、jsonのデコードに失敗しているのが原因だと思いますが...
Author
First-time contributor

はるひさんから「たぶん改行コードが悪さをしている」とあったのですが、おそらくJSON_UNESCAPED_UNICODEでjsonをエンコードしているので、改行コードがそのまま突っ込まれているのが原因かなと思います。
何かエスケープしたくない理由があるのでなければ、エンコードするときのフラグを変えるのがいいかと思います。
エスケープが必要なら、スレタイ追加の時に手動で改行コードなどを全部除去するしかないかもしれませんね。

はるひさんから「たぶん改行コードが悪さをしている」とあったのですが、おそらくJSON_UNESCAPED_UNICODEでjsonをエンコードしているので、改行コードがそのまま突っ込まれているのが原因かなと思います。 何かエスケープしたくない理由があるのでなければ、エンコードするときのフラグを変えるのがいいかと思います。 エスケープが必要なら、スレタイ追加の時に手動で改行コードなどを全部除去するしかないかもしれませんね。
Owner

ありがとうございます。
エスケープ処理と思われる場所です。jsonファイルについては一回削除しないとダメなようでした。

// 特殊な文字等変換
$_POST['title'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['title']);
$_POST['name'] = str_replace('"', "&quot;", $_POST['name']);
$_POST['name'] = str_replace("<", "&lt;", $_POST['name']);
$_POST['name'] = str_replace(">", "&gt;", $_POST['name']);
$_POST['name'] = str_replace("'", "&#039;", $_POST['name']);
$_POST['name'] = str_replace("&amp", "", $_POST['name']);
$_POST['name'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['name']);
$_POST['name'] = trim($_POST['name']);
$_POST['mail'] = htmlspecialchars($_POST['mail'], ENT_QUOTES, 'UTF-8');
$_POST['mail'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['mail']);
$_POST['mail'] = trim($_POST['mail']);
$_POST['board'] = str_replace(array(".","/","|"), "", $_POST['board']);
$_POST['thread'] = str_replace(array(".","/","|"), "", $_POST['thread']);
$_POST['comment'] = str_replace('"', "&quot;", $_POST['comment']);
$_POST['comment'] = str_replace("<", "&lt;", $_POST['comment']);
$_POST['comment'] = str_replace(">", "&gt;", $_POST['comment']);
$_POST['comment'] = str_replace("'", "&#039;", $_POST['comment']);
$_POST['comment'] = str_replace("&amp", "", $_POST['comment']);
$_POST['comment'] = trim($_POST['comment']);
$_POST['comment'] = str_replace(array('[', ']'), array('[', ']'), $_POST['comment']); //レス情報欄偽造防止
$_POST['comment'] = str_replace(array("\r\n","\r","\n"), "<br>", $_POST['comment']);
$_POST['comment'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['comment']);
$_POST['comment'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['comment']);
$_POST['title'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['title']);
$_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['title']);
$_POST['name'] = preg_replace("/&#0*10([^0-9]|$)/", "", $_POST['name']);
$_POST['name'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "", $_POST['name']);
$msgbr = explode("<br>", $_POST['comment']);
ありがとうございます。 エスケープ処理と思われる場所です。jsonファイルについては一回削除しないとダメなようでした。 ``` // 特殊な文字等変換 $_POST['title'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['title']); $_POST['name'] = str_replace('"', "&quot;", $_POST['name']); $_POST['name'] = str_replace("<", "&lt;", $_POST['name']); $_POST['name'] = str_replace(">", "&gt;", $_POST['name']); $_POST['name'] = str_replace("'", "&#039;", $_POST['name']); $_POST['name'] = str_replace("&amp", "", $_POST['name']); $_POST['name'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['name']); $_POST['name'] = trim($_POST['name']); $_POST['mail'] = htmlspecialchars($_POST['mail'], ENT_QUOTES, 'UTF-8'); $_POST['mail'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['mail']); $_POST['mail'] = trim($_POST['mail']); $_POST['board'] = str_replace(array(".","/","|"), "", $_POST['board']); $_POST['thread'] = str_replace(array(".","/","|"), "", $_POST['thread']); $_POST['comment'] = str_replace('"', "&quot;", $_POST['comment']); $_POST['comment'] = str_replace("<", "&lt;", $_POST['comment']); $_POST['comment'] = str_replace(">", "&gt;", $_POST['comment']); $_POST['comment'] = str_replace("'", "&#039;", $_POST['comment']); $_POST['comment'] = str_replace("&amp", "", $_POST['comment']); $_POST['comment'] = trim($_POST['comment']); $_POST['comment'] = str_replace(array('[', ']'), array('[', ']'), $_POST['comment']); //レス情報欄偽造防止 $_POST['comment'] = str_replace(array("\r\n","\r","\n"), "<br>", $_POST['comment']); $_POST['comment'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['comment']); $_POST['comment'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['comment']); $_POST['title'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['title']); $_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['title']); $_POST['name'] = preg_replace("/&#0*10([^0-9]|$)/", "", $_POST['name']); $_POST['name'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "", $_POST['name']); $msgbr = explode("<br>", $_POST['comment']); ```
Author
First-time contributor

直接このバグと関係しているかはわかりませんが、\n \r 以外のエスケープが必要な文字(\b \tなど)がreplaceされていないのが気になります。
https://www.ipentec.com/document/json-character-escape
可能ならJSON_UNESCAPED_UNICODE を使わないのが手っ取り早い修正ではあると思うのですが...

直接このバグと関係しているかはわかりませんが、\n \r 以外のエスケープが必要な文字(\b \tなど)がreplaceされていないのが気になります。 https://www.ipentec.com/document/json-character-escape 可能ならJSON_UNESCAPED_UNICODE を使わないのが手っ取り早い修正ではあると思うのですが...
Owner

変更箇所としては今の所こうなってます…

$_POST['title'] = str_replace(array("\r\n","\r","\n", "&#10;", "&#13;", "&#010;", "&#xa;", "&#0xa;","&#x0a;", "000a", "&#x0000a;"), " ", $_>
$_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "&lt;br&gt;", $_POST['title']);
変更箇所としては今の所こうなってます… ``` $_POST['title'] = str_replace(array("\r\n","\r","\n", "&#10;", "&#13;", "&#010;", "&#xa;", "&#0xa;","&#x0a;", "000a", "&#x0000a;"), " ", $_> ``` ``` $_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "&lt;br&gt;", $_POST['title']); ```
Author
First-time contributor

改行コードに関しては、やはりこの処理で消えているように思えるので、わかりません......

改行コードに関しては、やはりこの処理で消えているように思えるので、わかりません......
Author
First-time contributor

image
repl.itで試した感じだと、\b \f " が残っているようです。

追記: 一応imgurでも貼っておきます https://imgur.com/KuagpUJ

![image](https://git.3chan.cc/attachments/d183de16-c5e8-403a-98ec-9363f2735d75) repl.itで試した感じだと、\b \f \" が残っているようです。 追記: 一応imgurでも貼っておきます https://imgur.com/KuagpUJ
Author
First-time contributor

正規表現のところ(preg_replace)は、ちょっと何をしているのかわかりません...

正規表現のところ(`preg_replace`)は、ちょっと何をしているのかわかりません...
Author
First-time contributor

当該のスレタイが残っているならjson_decode(..., $flags=JSON_THROW_ON_ERROR)としてとりあえず例外を出させるのがいいかもしれません。ちょっとコードを読むだけだとこれ以上はわからなそうです。お役に立てずすみません。

当該のスレタイが残っているなら`json_decode(..., $flags=JSON_THROW_ON_ERROR)`としてとりあえず例外を出させるのがいいかもしれません。ちょっとコードを読むだけだとこれ以上はわからなそうです。お役に立てずすみません。
Author
First-time contributor

https://qiita.com/kanaxx/items/b46356532b01737dedd4
色々調べていたのですが、正規表現の部分はこれをやっているのかもしれません。
ただ、タイトルに\xD7をいれたらjson_decodeが失敗したのでこれがうまくいっていないのかもしれません。もう少し調べてみます。

追記: これはまた別の問題でした

https://qiita.com/kanaxx/items/b46356532b01737dedd4 ~~色々調べていたのですが、正規表現の部分はこれをやっているのかもしれません。 ただ、タイトルに`\xD7`をいれたらjson_decodeが失敗したのでこれがうまくいっていないのかもしれません。もう少し調べてみます。~~ 追記: これはまた別の問題でした
Contributor

あまり関係ない部分ですが

46 名前:radix ★@転載禁止[No.1696491529] 投稿日:2023/10/05(木) 16:38:49 ID:CAP_USER
>>41
タイトル部分の改行文字を、本来は削除するところが、まちがってbrタグに置換してることが原因だと思います。

http://dev.delightly.xyz/test/read.cgi/nore/1695561044/47
からすると、

$_POST['title'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['title']);
$_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['title']);

の所は

$_POST['title'] = preg_replace("/&#0*10([^0-9]|$)/", "", $_POST['title']);
$_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "", $_POST['title']);

が本来の処理だと多分思います

あまり関係ない部分ですが > 46 名前:radix ★@転載禁止[No.1696491529] 投稿日:2023/10/05(木) 16:38:49 ID:CAP_USER > \>\>41 > タイトル部分の改行文字を、本来は削除するところが、まちがってbrタグに置換してることが原因だと思います。 http://dev.delightly.xyz/test/read.cgi/nore/1695561044/47 からすると、 ``` $_POST['title'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['title']); $_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['title']); ``` の所は ``` $_POST['title'] = preg_replace("/&#0*10([^0-9]|$)/", "", $_POST['title']); $_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "", $_POST['title']); ``` が本来の処理だと多分思います
Owner

後半の正規表現が2行分タイトルの部分あるのに今気がついて修正したのですが問題は変わりませんでした。
以前の修正の時点で出力はエスケープされているようなので、スレタイのインデックス作成やjsonパースするあたりが怪しいのかもしれません。

後半の正規表現が2行分タイトルの部分あるのに今気がついて修正したのですが問題は変わりませんでした。 以前の修正の時点で出力はエスケープされているようなので、スレタイのインデックス作成やjsonパースするあたりが怪しいのかもしれません。
Author
First-time contributor

これが原因だと断定はできないのですが、自分の手元ではjson_decodeが落ちるケースは\xD[1-9]しか作れてないので、こいつらは全削除したほうがいいと思います。

これが原因だと断定はできないのですが、自分の手元ではjson_decodeが落ちるケースは\xD[1-9]しか作れてないので、こいつらは全削除したほうがいいと思います。
First-time contributor

preg_replace("/&#[xX]0*aA/", "<br>", $_POST['title']);
について

269 :ぷにぷに名無しさん 🥚 (d):2023/10/05(木) 16:48:36.65 ID:YznvnAe2
≫262
preg_replaceは&#x0a又は&#x000aみたいな文字にマッチしたのを第二引数の値に置換しとるだけ
って教えたってや

270 :ぷにぷに名無しさん 🥚 (d):2023/10/05(木) 16:52:10.88 ID:YznvnAe2
≫269
つまりは、CRとLFの文字コードx0aとx000aという文字を検索してlt br gtに置き換えてるわけやな

それがどういう効果をもたらすのかは他の箇所のコード読んで無いからしらん

https://bbs.punipuni.eu/test/read.cgi/vaporeon/1696479286/

代理で送らせていただきました。

preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "&lt;br&gt;", $_POST['title']); について 269 :ぷにぷに名無しさん 🥚 (d):2023/10/05(木) 16:48:36.65 ID:YznvnAe2 ≫262 preg_replaceは&#x0a又は&#x000aみたいな文字にマッチしたのを第二引数の値に置換しとるだけ って教えたってや 270 :ぷにぷに名無しさん 🥚 (d):2023/10/05(木) 16:52:10.88 ID:YznvnAe2 ≫269 つまりは、CRとLFの文字コードx0aとx000aという文字を検索してlt br gtに置き換えてるわけやな それがどういう効果をもたらすのかは他の箇所のコード読んで無いからしらん https://bbs.punipuni.eu/test/read.cgi/vaporeon/1696479286/ 代理で送らせていただきました。
Author
First-time contributor

引き続き試して見たのですが、

\x + [a-z|A-Z] + [1-9]

は必ずjson_decodeがSyntax errorをはきます。
繰り返し、これが今回のエラーの原因かはわかりませんが、おそらくスレを落とすことが可能と思われるので、正規表現で除去したほうがいいと思います。

引き続き試して見たのですが、 ``` \x + [a-z|A-Z] + [1-9] ``` は必ずjson_decodeがSyntax errorをはきます。 繰り返し、これが今回のエラーの原因かはわかりませんが、おそらくスレを落とすことが可能と思われるので、正規表現で除去したほうがいいと思います。
First-time contributor

(何らかの理由でエスケープシーケンスを使いたいのであれば別ですが) そもそもの\を空文字 or &#92 といった 別の文字列に置換すれば全部エスケープシーケンスを無効にできませんか?

(何らかの理由でエスケープシーケンスを使いたいのであれば別ですが) そもそもの\を空文字 or &#92 といった 別の文字列に置換すれば全部エスケープシーケンスを無効にできませんか?
Author
First-time contributor

@otoufu おそらく\x系(javascriptのエスケープ)だけで大丈夫で他は特になんの害もないと思うのですが、もう少し調べてみないとわかりません

@otoufu おそらく\x系(javascriptのエスケープ)だけで大丈夫で他は特になんの害もないと思うのですが、もう少し調べてみないとわかりません
Author
First-time contributor

もう一つ考えられるのがfile_get_contents($LTLFILE) がnullという場合ですが....、ちょっと考えづらいですね

もう一つ考えられるのが`file_get_contents($LTLFILE)` がnullという場合ですが....、ちょっと考えづらいですね
stat2 added the
bug
label 2023-10-06 02:10:05 +09:00
First-time contributor

またバグってますね
このスレが原因っぽいです

テ????rg [HhIDkiQs★]
http://bbs.3chan.cc/test/read.cgi/offshore/1696551063/

またバグってますね このスレが原因っぽいです テ????rg [HhIDkiQs★] http://bbs.3chan.cc/test/read.cgi/offshore/1696551063/
Contributor

$_POST['title']のエスケープ処理の修正案を考えてみました。
こうするとjson_decodeした時に$_POST['title']部分が原因で壊れることはないと思うのですがどうでしょうか。

// /をエスケープ
$_POST['title'] = preg_replace('/\//', '\/', $_POST['title']);
// "をエスケープ
$_POST['title'] = preg_replace('/"/', '\"', $_POST['title']);
// &#10;(LF) &#13;(CR) をエスケープ
$_POST['title'] = preg_replace("/&#0*1[03];/", "&lt;br&gt;", $_POST['title']);
// &#x0a;(LF) &#x0d;(CR) をエスケープ
$_POST['title'] = preg_replace("/&#[xX]0*[aAdD];/", "&lt;br&gt;", $_POST['title']);
$_POST['title']のエスケープ処理の修正案を考えてみました。 こうするとjson_decodeした時に$_POST['title']部分が原因で壊れることはないと思うのですがどうでしょうか。 ``` // /をエスケープ $_POST['title'] = preg_replace('/\//', '\/', $_POST['title']); // "をエスケープ $_POST['title'] = preg_replace('/"/', '\"', $_POST['title']); // &#10;(LF) &#13;(CR) をエスケープ $_POST['title'] = preg_replace("/&#0*1[03];/", "&lt;br&gt;", $_POST['title']); // &#x0a;(LF) &#x0d;(CR) をエスケープ $_POST['title'] = preg_replace("/&#[xX]0*[aAdD];/", "&lt;br&gt;", $_POST['title']); ```
First-time contributor

ちょっと試してみますー
最初のコードからの修正でOKでしょうかー?

ちょっと試してみますー 最初のコードからの修正でOKでしょうかー?
Contributor

元々のコードの以下の3行の代わりに上記の4行を入れてもらえればいいかと思います。

// 特殊な文字等変換
$_POST['title'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['title']);
// ~中略~
$_POST['title'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['title']);
$_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['title']);
元々のコードの以下の3行の代わりに上記の4行を入れてもらえればいいかと思います。 ``` // 特殊な文字等変換 $_POST['title'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['title']); // ~中略~ $_POST['title'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['title']); $_POST['title'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['title']); ```
First-time contributor

改変したところTLが消えて書き込み不可になっちゃいますねー
残さなきゃいけないコードがあるもしくは行の位置が悪かったかなー?
また確認してみますー

改変したところTLが消えて書き込み不可になっちゃいますねー 残さなきゃいけないコードがあるもしくは行の位置が悪かったかなー? また確認してみますー
Contributor

了解です。
こちらでも再確認してみます。

了解です。 こちらでも再確認してみます。
Author
First-time contributor

私もはるひさんにお願いがあるのですが、スレタイに"\xA9"や"\xD4"があるときエラーがあるか確認していただいても大丈夫でしょうか?
よろしくお願いします。

私もはるひさんにお願いがあるのですが、スレタイに"\xA9"や"\xD4"があるときエラーがあるか確認していただいても大丈夫でしょうか? よろしくお願いします。
Author
First-time contributor

改変したところTLが消えて書き込み不可になっちゃいますねー

テストに使用したスレタイを共有していただいてもよろしいでしょうか?
公開したくないようでしたらmisskeyのDMでお願いします。

> 改変したところTLが消えて書き込み不可になっちゃいますねー テストに使用したスレタイを共有していただいてもよろしいでしょうか? 公開したくないようでしたらmisskeyのDMでお願いします。
First-time contributor

そもそもTLが消えて通常の書き込み不可になっちゃいましたー
post-v2の遷移画面で止まりますー
もしかしたらはるひのソースコード改変間違いの可能性もあるので
修正したbbsmain.phpのファイルがあるとすぐ反映できるのでありがたいですー

そもそもTLが消えて通常の書き込み不可になっちゃいましたー post-v2の遷移画面で止まりますー もしかしたらはるひのソースコード改変間違いの可能性もあるので 修正したbbsmain.phpのファイルがあるとすぐ反映できるのでありがたいですー
Author
First-time contributor

了解です、検証ありがとうございます
ちょっと今日はもう厳しいので明日以降また検証のお願いするかもです

了解です、検証ありがとうございます ちょっと今日はもう厳しいので明日以降また検証のお願いするかもです
Collaborator

ちょっと整理しました。
私の環境ではTLも動いたんですが、どうでしょう?

// スレタイの特殊文字等変換
function escapeTitle($title) {
        // /をエスケープ
        $title = preg_replace('/\//', '\/', $title);
        // "をエスケープ
        $title = preg_replace('/"/', '&quot;', $title);
        // &#10;(LF) &#13;(CR) をエスケープ
        $title = preg_replace("/&#0*1[03];/", "&lt;br&gt;", $title);
        // &#x0a;(LF) &#x0d;(CR) をエスケープ
        $title = preg_replace("/&#[xX]0*[aAdD];/", "&lt;br&gt;", $title);
        
        return $title;
    }
$_POST['title'] = escapeTitle($_POST['title']);
$_POST['name'] = str_replace('"', "&quot;", $_POST['name']);
$_POST['name'] = str_replace("<", "&lt;", $_POST['name']);
$_POST['name'] = str_replace(">", "&gt;", $_POST['name']);
$_POST['name'] = str_replace("'", "&#039;", $_POST['name']);
$_POST['name'] = str_replace("&amp", "", $_POST['name']);
$_POST['name'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['name']);
$_POST['name'] = trim($_POST['name']);
$_POST['mail'] = htmlspecialchars($_POST['mail'], ENT_QUOTES, 'UTF-8');
$_POST['mail'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['mail']);
$_POST['mail'] = trim($_POST['mail']);
$_POST['board'] = str_replace(array(".","/","|"), "", $_POST['board']);
$_POST['thread'] = str_replace(array(".","/","|"), "", $_POST['thread']);
$_POST['comment'] = str_replace('"', "&quot;", $_POST['comment']);
$_POST['comment'] = str_replace("<", "&lt;", $_POST['comment']);
$_POST['comment'] = str_replace(">", "&gt;", $_POST['comment']);
$_POST['comment'] = str_replace("'", "&#039;", $_POST['comment']);
$_POST['comment'] = str_replace("&amp", "", $_POST['comment']);
$_POST['comment'] = trim($_POST['comment']);
$_POST['comment'] = str_replace(array('[', ']'), array('[', ']'), $_POST['comment']); //レス情報欄偽造防止
$_POST['comment'] = str_replace(array("\r\n","\r","\n"), "<br>", $_POST['comment']);
$_POST['comment'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['comment']);
$_POST['comment'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['comment']);
$_POST['name'] = preg_replace("/&#0*10([^0-9]|$)/", "", $_POST['name']);
$_POST['name'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "", $_POST['name']);
$msgbr = explode("<br>", $_POST['comment']);

ちょっと整理しました。 私の環境ではTLも動いたんですが、どうでしょう? ``` // スレタイの特殊文字等変換 function escapeTitle($title) { // /をエスケープ $title = preg_replace('/\//', '\/', $title); // "をエスケープ $title = preg_replace('/"/', '&quot;', $title); // &#10;(LF) &#13;(CR) をエスケープ $title = preg_replace("/&#0*1[03];/", "&lt;br&gt;", $title); // &#x0a;(LF) &#x0d;(CR) をエスケープ $title = preg_replace("/&#[xX]0*[aAdD];/", "&lt;br&gt;", $title); return $title; } $_POST['title'] = escapeTitle($_POST['title']); $_POST['name'] = str_replace('"', "&quot;", $_POST['name']); $_POST['name'] = str_replace("<", "&lt;", $_POST['name']); $_POST['name'] = str_replace(">", "&gt;", $_POST['name']); $_POST['name'] = str_replace("'", "&#039;", $_POST['name']); $_POST['name'] = str_replace("&amp", "", $_POST['name']); $_POST['name'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['name']); $_POST['name'] = trim($_POST['name']); $_POST['mail'] = htmlspecialchars($_POST['mail'], ENT_QUOTES, 'UTF-8'); $_POST['mail'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['mail']); $_POST['mail'] = trim($_POST['mail']); $_POST['board'] = str_replace(array(".","/","|"), "", $_POST['board']); $_POST['thread'] = str_replace(array(".","/","|"), "", $_POST['thread']); $_POST['comment'] = str_replace('"', "&quot;", $_POST['comment']); $_POST['comment'] = str_replace("<", "&lt;", $_POST['comment']); $_POST['comment'] = str_replace(">", "&gt;", $_POST['comment']); $_POST['comment'] = str_replace("'", "&#039;", $_POST['comment']); $_POST['comment'] = str_replace("&amp", "", $_POST['comment']); $_POST['comment'] = trim($_POST['comment']); $_POST['comment'] = str_replace(array('[', ']'), array('[', ']'), $_POST['comment']); //レス情報欄偽造防止 $_POST['comment'] = str_replace(array("\r\n","\r","\n"), "<br>", $_POST['comment']); $_POST['comment'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['comment']); $_POST['comment'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['comment']); $_POST['name'] = preg_replace("/&#0*10([^0-9]|$)/", "", $_POST['name']); $_POST['name'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "", $_POST['name']); $msgbr = explode("<br>", $_POST['comment']); ```
First-time contributor

ソースコード修正後動作正常確認しましたー
テスト掲示板を解放するのでテストしてもらいたいと思いますー
ここに直接貼っても大丈夫かなー?

ソースコード修正後動作正常確認しましたー テスト掲示板を解放するのでテストしてもらいたいと思いますー ここに直接貼っても大丈夫かなー?
First-time contributor

とりあえず避難所の方に貼ってテストしてもらいますー

とりあえず避難所の方に貼ってテストしてもらいますー
First-time contributor

TLが壊れましたが現状その後の書き込みは正常に行われてますー

TLが壊れましたが現状その後の書き込みは正常に行われてますー
Contributor

一応私の環境の結果も書いておきます。

// 特殊な文字等変換
// /をエスケープ
$_POST['title'] = preg_replace('/\//', '\/', $_POST['title']);
// "をエスケープ
$_POST['title'] = preg_replace('/"/', '\"', $_POST['title']);
// &#10;(LF) &#13;(CR) をエスケープ
$_POST['title'] = preg_replace("/&#0*1[03];/", "&lt;br&gt;", $_POST['title']);
// &#x0a;(LF) &#x0d;(CR) をエスケープ
$_POST['title'] = preg_replace("/&#[xX]0*[aAdD];/", "&lt;br&gt;", $_POST['title']);
$_POST['name'] = str_replace('"', "&quot;", $_POST['name']);
$_POST['name'] = str_replace("<", "&lt;", $_POST['name']);
$_POST['name'] = str_replace(">", "&gt;", $_POST['name']);
$_POST['name'] = str_replace("'", "&#039;", $_POST['name']);
$_POST['name'] = str_replace("&amp", "", $_POST['name']);
$_POST['name'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['name']);
$_POST['name'] = trim($_POST['name']);
$_POST['mail'] = htmlspecialchars($_POST['mail'], ENT_QUOTES, 'UTF-8');
$_POST['mail'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['mail']);
$_POST['mail'] = trim($_POST['mail']);
$_POST['board'] = str_replace(array(".","/","|"), "", $_POST['board']);
$_POST['thread'] = str_replace(array(".","/","|"), "", $_POST['thread']);
$_POST['comment'] = str_replace('"', "&quot;", $_POST['comment']);
$_POST['comment'] = str_replace("<", "&lt;", $_POST['comment']);
$_POST['comment'] = str_replace(">", "&gt;", $_POST['comment']);
$_POST['comment'] = str_replace("'", "&#039;", $_POST['comment']);
$_POST['comment'] = str_replace("&amp", "", $_POST['comment']);
$_POST['comment'] = trim($_POST['comment']);
$_POST['comment'] = str_replace(array('[', ']'), array('[', ']'), $_POST['comment']); //レス情報欄偽造防止
$_POST['comment'] = str_replace(array("\r\n","\r","\n"), "<br>", $_POST['comment']);
$_POST['comment'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['comment']);
$_POST['comment'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['comment']);
$_POST['name'] = preg_replace("/&#0*10([^0-9]|$)/", "", $_POST['name']);
$_POST['name'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "", $_POST['name']);
$msgbr = explode("<br>", $_POST['comment']);

スレタイtest\n"\xA9""\xD4"&#10;&#13;&#x0a;&#x0d;\rで作成。TLに問題は見られず。
エスケープ処理後のスレタイはtest\n\"\xA9\"\"\xD4\"<br><br><br><br>\rとなっています。

一応私の環境の結果も書いておきます。 ``` // 特殊な文字等変換 // /をエスケープ $_POST['title'] = preg_replace('/\//', '\/', $_POST['title']); // "をエスケープ $_POST['title'] = preg_replace('/"/', '\"', $_POST['title']); // &#10;(LF) &#13;(CR) をエスケープ $_POST['title'] = preg_replace("/&#0*1[03];/", "&lt;br&gt;", $_POST['title']); // &#x0a;(LF) &#x0d;(CR) をエスケープ $_POST['title'] = preg_replace("/&#[xX]0*[aAdD];/", "&lt;br&gt;", $_POST['title']); $_POST['name'] = str_replace('"', "&quot;", $_POST['name']); $_POST['name'] = str_replace("<", "&lt;", $_POST['name']); $_POST['name'] = str_replace(">", "&gt;", $_POST['name']); $_POST['name'] = str_replace("'", "&#039;", $_POST['name']); $_POST['name'] = str_replace("&amp", "", $_POST['name']); $_POST['name'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['name']); $_POST['name'] = trim($_POST['name']); $_POST['mail'] = htmlspecialchars($_POST['mail'], ENT_QUOTES, 'UTF-8'); $_POST['mail'] = str_replace(array("\r\n","\r","\n"), " ", $_POST['mail']); $_POST['mail'] = trim($_POST['mail']); $_POST['board'] = str_replace(array(".","/","|"), "", $_POST['board']); $_POST['thread'] = str_replace(array(".","/","|"), "", $_POST['thread']); $_POST['comment'] = str_replace('"', "&quot;", $_POST['comment']); $_POST['comment'] = str_replace("<", "&lt;", $_POST['comment']); $_POST['comment'] = str_replace(">", "&gt;", $_POST['comment']); $_POST['comment'] = str_replace("'", "&#039;", $_POST['comment']); $_POST['comment'] = str_replace("&amp", "", $_POST['comment']); $_POST['comment'] = trim($_POST['comment']); $_POST['comment'] = str_replace(array('[', ']'), array('[', ']'), $_POST['comment']); //レス情報欄偽造防止 $_POST['comment'] = str_replace(array("\r\n","\r","\n"), "<br>", $_POST['comment']); $_POST['comment'] = preg_replace("/&#0*10([^0-9]|$)/", "<br>", $_POST['comment']); $_POST['comment'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "<br>", $_POST['comment']); $_POST['name'] = preg_replace("/&#0*10([^0-9]|$)/", "", $_POST['name']); $_POST['name'] = preg_replace("/&#[xX]0*[aA]([^a-zA-Z0-9]|$)/", "", $_POST['name']); $msgbr = explode("<br>", $_POST['comment']); ``` スレタイ`test\n"\xA9""\xD4"&#10;&#13;&#x0a;&#x0d;\r`で作成。TLに問題は見られず。 エスケープ処理後のスレタイは`test\n\"\xA9\"\"\xD4\"<br><br><br><br>\r`となっています。
Author
First-time contributor

皆さん検証ありがとうございます!

TLが壊れましたが

これの再現さえできれば残りのケースは一応は解決ですかね?

皆さん検証ありがとうございます! > TLが壊れましたが これの再現さえできれば残りのケースは一応は解決ですかね?
Collaborator

そうですね、なぜローカルだと再現しないんだろう?

そうですね、なぜローカルだと再現しないんだろう?
Contributor

web版でHTMLタグをスレタイに埋め込めてしまうので更に修正案。
9bc45bc4d2/test/bbs-main.php (L314) あたりでエスケープしてるように思うんですが違うんですかね…

// 特殊な文字等変換
// HTMLタグをエスケープ
$_POST['title'] = htmlspecialchars($_POST['title'], ENT_QUOTES, 'UTF-8');
// /をエスケープ
$_POST['title'] = preg_replace('/\//', '\/', $_POST['title']);
// &#10;(LF) &#13;(CR) をエスケープ
$_POST['title'] = preg_replace("/&#0*1[03];/", "&lt;br&gt;", $_POST['title']);
// &#x0a;(LF) &#x0d;(CR) をエスケープ
$_POST['title'] = preg_replace("/&#[xX]0*[aAdD];/", "&lt;br&gt;", $_POST['title']);
// 後略
web版でHTMLタグをスレタイに埋め込めてしまうので更に修正案。 https://git.3chan.cc/stat2/delightly-v2fork/src/commit/9bc45bc4d287d566b20162381c44fc404a1ee9b2/test/bbs-main.php#L314 あたりでエスケープしてるように思うんですが違うんですかね… ``` // 特殊な文字等変換 // HTMLタグをエスケープ $_POST['title'] = htmlspecialchars($_POST['title'], ENT_QUOTES, 'UTF-8'); // /をエスケープ $_POST['title'] = preg_replace('/\//', '\/', $_POST['title']); // &#10;(LF) &#13;(CR) をエスケープ $_POST['title'] = preg_replace("/&#0*1[03];/", "&lt;br&gt;", $_POST['title']); // &#x0a;(LF) &#x0d;(CR) をエスケープ $_POST['title'] = preg_replace("/&#[xX]0*[aAdD];/", "&lt;br&gt;", $_POST['title']); // 後略 ```
First-time contributor

梅沢富美男で試しましたがHTML無効になってますねー👏

梅沢富美男で試しましたがHTML無効になってますねー👏
Contributor
// /をエスケープ
$_POST['title'] = preg_replace('/\//', '\/', $_POST['title']);

これは不要かもしれません。私の環境では抜いてもTLは正常のままです。
subject.jsonやindex.jsonを見ると、この行が無くても/がエスケープ処理されているのが分かります。
つまり2重で処理が行われているため、url等が次のようになってしまいます。https://www.google.co.jp/ => https:\/\/www.google.co.jp\/

また、そもそも抜けていたのですが\のエスケープ処理についても同様に無いままで構わないかと思います。

``` // /をエスケープ $_POST['title'] = preg_replace('/\//', '\/', $_POST['title']); ``` これは不要かもしれません。私の環境では抜いてもTLは正常のままです。 subject.jsonやindex.jsonを見ると、この行が無くても/がエスケープ処理されているのが分かります。 つまり2重で処理が行われているため、url等が次のようになってしまいます。https://www.google.co.jp/ => https:\\/\\/www.google.co.jp\\/ また、そもそも抜けていたのですが\のエスケープ処理についても同様に無いままで構わないかと思います。
Author
First-time contributor

\がエスケープされるのはjson_encodeの仕様みたいですね

`\`がエスケープされるのは`json_encode`の仕様みたいですね
First-time contributor

こちらでも先ほどのコードで異常ない事確認できましたー
別サーバーではTLの不具合もありましたので様子は見てみますー

こちらでも先ほどのコードで異常ない事確認できましたー 別サーバーではTLの不具合もありましたので様子は見てみますー
Contributor

スレタイ絵文字の文字化け等があったので修正案。
314行あたりの処理を上に持ってきて一本化してみました。

314行目あたりは全て削除。復旧が必要な場合のために一応コメントアウトにしてます。

// // スレッドタイトルの変換形式
// if ($SETTING['BBS_UNICODE'] != "checked") {
// $_POST['title'] = htmlspecialchars($_POST['title'], ENT_QUOTES, 'UTF-8');
// }else {
// $_POST['title'] = str_replace('"', "&quot;", $_POST['title']);
// $_POST['title'] = str_replace("<", "&lt;", $_POST['title']);
// $_POST['title'] = str_replace(">", "&gt;", $_POST['title']);
// $_POST['title'] = str_replace("'", "&#039;", $_POST['title']);
// $_POST['title'] = str_replace("&amp", "?", $_POST['title']);
// $_POST['title'] .= " ";
// $_POST['title'] = trim($_POST['title']);
// }

特殊な文字等変換のところに追加・修正。

// 特殊な文字等変換
if ($SETTING['BBS_UNICODE'] != "checked") {
  // 絵文字禁止モードなのでhtmlspecialcharsでok
  $_POST['title'] = htmlspecialchars($_POST['title'], ENT_QUOTES, 'UTF-8');
}else {
  // 絵文字をhtmlspecialcharsしてしまうと数値実体参照の文字列になってしまうので個別にエスケープ処理
  $_POST['title'] = preg_replace('/&(?!#[a-zA-Z0-9]+;)/', '&#38;', $_POST['title']);
  $_POST['title'] = str_replace('"', '&#34;', $_POST['title']);
  $_POST['title'] = str_replace('<', '&#60;', $_POST['title']);
  $_POST['title'] = str_replace('>', '&#62;', $_POST['title']);
  $_POST['title'] = str_replace("'", '&#39;', $_POST['title']);
}
// &#10;(LF) &#13;(CR) をエスケープ
$_POST['title'] = preg_replace("/&#0*1[03];/", "&#32;", $_POST['title']);
// &#x0a;(LF) &#x0d;(CR) をエスケープ
$_POST['title'] = preg_replace("/&#[xX]0*[aAdD];/", "&#32;", $_POST['title']);
// スレ立て時の判定
if($_POST['title']!==''){
  // 先頭と末尾の空白文字を削除
  $_POST['title'] = trim($_POST['title']);
  // trim後のスレタイが空文字ならerror
  if($_POST['title'] === ''){
    Error2("invalid:1");
  }
}
// 後略 $_POST['name'] が続く

ついでに改行コードを<br>に置換する意味は無いと感じたので半角空白に変更してみました。
何かおかしなところがあれば修正していただきたいです。
※レスがスレ立てになる不具合が発生したので再修正しました。

スレタイ絵文字の文字化け等があったので修正案。 314行あたりの処理を上に持ってきて一本化してみました。 314行目あたりは全て削除。復旧が必要な場合のために一応コメントアウトにしてます。 ``` // // スレッドタイトルの変換形式 // if ($SETTING['BBS_UNICODE'] != "checked") { // $_POST['title'] = htmlspecialchars($_POST['title'], ENT_QUOTES, 'UTF-8'); // }else { // $_POST['title'] = str_replace('"', "&quot;", $_POST['title']); // $_POST['title'] = str_replace("<", "&lt;", $_POST['title']); // $_POST['title'] = str_replace(">", "&gt;", $_POST['title']); // $_POST['title'] = str_replace("'", "&#039;", $_POST['title']); // $_POST['title'] = str_replace("&amp", "?", $_POST['title']); // $_POST['title'] .= " "; // $_POST['title'] = trim($_POST['title']); // } ``` 特殊な文字等変換のところに追加・修正。 ``` // 特殊な文字等変換 if ($SETTING['BBS_UNICODE'] != "checked") { // 絵文字禁止モードなのでhtmlspecialcharsでok $_POST['title'] = htmlspecialchars($_POST['title'], ENT_QUOTES, 'UTF-8'); }else { // 絵文字をhtmlspecialcharsしてしまうと数値実体参照の文字列になってしまうので個別にエスケープ処理 $_POST['title'] = preg_replace('/&(?!#[a-zA-Z0-9]+;)/', '&#38;', $_POST['title']); $_POST['title'] = str_replace('"', '&#34;', $_POST['title']); $_POST['title'] = str_replace('<', '&#60;', $_POST['title']); $_POST['title'] = str_replace('>', '&#62;', $_POST['title']); $_POST['title'] = str_replace("'", '&#39;', $_POST['title']); } // &#10;(LF) &#13;(CR) をエスケープ $_POST['title'] = preg_replace("/&#0*1[03];/", "&#32;", $_POST['title']); // &#x0a;(LF) &#x0d;(CR) をエスケープ $_POST['title'] = preg_replace("/&#[xX]0*[aAdD];/", "&#32;", $_POST['title']); // スレ立て時の判定 if($_POST['title']!==''){ // 先頭と末尾の空白文字を削除 $_POST['title'] = trim($_POST['title']); // trim後のスレタイが空文字ならerror if($_POST['title'] === ''){ Error2("invalid:1"); } } // 後略 $_POST['name'] が続く ``` ついでに改行コードを&#60;br&#62;に置換する意味は無いと感じたので半角空白に変更してみました。 何かおかしなところがあれば修正していただきたいです。 ※レスがスレ立てになる不具合が発生したので再修正しました。
Owner

みなさん本当にありがとうございます…!。
こちらの修正を適用し、サーバー側でもいくつか追加のセキュリティ対策を実施した上で再度delighlyへの移行を検討したいと思います。

みなさん本当にありがとうございます…!。 こちらの修正を適用し、サーバー側でもいくつか追加のセキュリティ対策を実施した上で再度delighlyへの移行を検討したいと思います。
Contributor

#23 を受けてエスケープ処理の再確認及び一本化を行いました。
これで少し可読性が上がって処理漏れの恐れも無くなったかと思います。
該当箇所のコードは以下の通りです。
1ab9ad67fb/test/bbs-main.php (L72-L113)

※再修正しました。
※追記 こちらのプルリクエストが令和最新版です。
#24
#27

https://git.3chan.cc/stat2/delightly-v2fork/issues/23 を受けてエスケープ処理の再確認及び一本化を行いました。 これで少し可読性が上がって処理漏れの恐れも無くなったかと思います。 該当箇所のコードは以下の通りです。 ~~https://git.3chan.cc/konkon-fox/delightly-v2fork/src/commit/1ab9ad67fb10c301626922e64c5816ffeec8c02f/test/bbs-main.php#L72-L113~~ ※再修正しました。 ※追記 こちらのプルリクエストが令和最新版です。 ~~https://git.3chan.cc/stat2/delightly-v2fork/pulls/24~~ https://git.3chan.cc/stat2/delightly-v2fork/pulls/27
Owner

#27で修正済み。

[#27](stat2/delightly-v2fork#27)で修正済み。
stat2 closed this issue 2023-10-28 18:24:29 +09:00
Sign in to join this conversation.
No description provided.