Lyndbaum v4.38アップデート

adiary置き換え計画始動から連なる、Lyndbaum v4.37アップデートの続き。

今回は機能追加と機能改善。

PukiWikiの差分に相当する機能を追加

PukiWikiには前回更新時のスナップショットを持っておき、前回の状態と比較できる機能がある。これを追加した。

これにより更新したけど、やっぱ戻したいとか、前何書いたっけ?を確認したい需要に対応できる。

リンクカードの更新を抑制

v4.36で導入したリンクカード記法には記事更新やブログ再構築時に毎回再取得が走る問題があり、相手サーバーの負荷になるうえ、単純に更新が重い問題があった。

これを解消するために再構築ではリンクカードの更新をオプションにし、記事更新時にはリンクカードを作らないようにした。どうしても作り直す場合は作り直したいカードを消して更新し、もう一度書き直すことで実現できる。

この方式はMastodonの作りを参考にしている。Mastodonでは一度投稿を消し適当なハッシュリンク付きで投稿し、削除し、ハッシュリンクなしのURLで再投稿することでリンクカードを無理やり更新できる裏技がある。この恐らくMastodonの開発者が想定しているとは思えない振る舞いを参考にし仕様を作った。システムでどうこうすると大変なので運用でカバー。

画面表示に利用していたリポジトリURLが古かったのを修正

フッターに出ていたリポジトリURLがLyndbaum4のままだったので無印に改定した。参考までに過去のLyndbaumはLyndbaum0になっている。

あとがき

今回の対応によりIssueはだいぶ片付き、残りといえば直しても直さなくてもどうでもいいレベルの内容や、他の人が使えるようにする対応のようなものが中心になっている。

特に何もなければ昨今起きているLyndbaumアップデート記事の連打は今後減っていく、と思いたい。

そういえばリリースの版数でブランチバージョンを除いたバージョンを数えていたら64件になっていた。キリがいい。

現時点でのリリース一覧(v0.22.dev-1はブランチに見えるが、v0.22.0相当なので含んでいる)

リンク先はリリースページでなくPRかコミットハッシュにしている。

v4.38 / v4.37 / v4.36 / v4.35 / v4.34 / v4.33 / v4.32 / v4.31 / v4.30 / v4.29 / v4.28 / v4.27 / v4.26 / v4.25 / v4.24 / v4.23 / v4.22 / v4.21 / v4.20 / v4.19 / v4.18 / v4.17 / v4.16 / v4.15 / v4.14 / v4.13 / v4.12 / v4.11 / v4.10 / v4.09 / v4.08 / v4.7 / v4.6 / v4.5.1 / v4.5 / v4.4 / v0.43 / v0.42.0 / v0.41.0 / v0.40.0 / v0.30.0 / v0.29.0 / v0.28.0 / v0.27.0 / v0.26.0 / v0.25.0 / v0.24.0 / v0.23.0 / v0.22.dev-1 / v0.21.0 / v0.16.0 / v0.15.0 / v0.13.0 / v0.9.2 / v0.9.0 / v0.8.0 / v0.7.0 / v0.6.2 / v0.6.0 / v0.5.0 / v0.4.1 / v0.3.0 / v0.2.0 / v0.1.0

Lyndbaum v4.37アップデート

adiary置き換え計画始動から連なる、Lyndbaum v4.36アップデートの続き。一日に二度更新しているが、単に土曜の更新が日曜にずれ込んだ関係でこうなっているだけだと思う。たぶん。

今回は機能追加対応がメインだ。

ブログの画像の想定が正方形だったのをバナー想定にし、ブログの画像をRSSの画像に設定するようにした

表示の優先順もブログの画像があればブログの画像、ブログの画像がなければサイトアイコン、それもなければデフォルトアイコンを出すようにロジックを変えている。

この対応によりブログの画像はバナー、サイトアイコンはアイコンという使い分けができるようになった。そして何も設定していなければLyndbaumのロゴになる。

SSPのRSSを選んだ時にユーザーさんの興味をグングン引くような画像が出るようにしているところ

今回の対応の目的はSSP上でRSSにユーザーさんの好奇心を引き立てるような画像を設定可能にするのが主目的で、副次的にバナーをOGPとして出せることがある。サイトアイコンは正方形、バナーはそれ以外としてOGPを出し分けたい需要が私の中にあったのでそうしている。

v4.26でRSSを載せるようにした対応も伺か向けだったし、伺か向け対応を続けるCMS、いったい何者なのか…。

なおSSP以外のリーダーが<image>をどう解釈するかについては一切何ら考慮していない。何故ならそんなRSSリーダーを私が知らないからである。

FediverseのURLを入れた時にいい感じのカードを出せるようにした

[&URL]構文で出せるやつ。

変更前 変更後
変更前はテキストだけで味気ない 変更後はSNSのステータスカード風に出ている

Fediverseユーザーが開発しているCMSならFediverseのカードが出せないといかんでしょ!ということで対応したもの。Lycodonと末代、Misskey.ioでのみ動作確認している。MastodonとMisskey以外で使えるのかは不明だが一般的なActivityPubであれば対応可能なものだと見込んでいる。

下書き選択のタイトルにbyと入ってるのを消した

修正前は下書き選択のタイトルにbyと入っていた

修正前は下書き選択のタイトルにbyと入っていたが、これをなくした。v4.34で行った複数ユーザー機能の削除の残骸掃除。

Lyndbaumテーマで目次とただのリストの見分けがつけづらいのを分かりやすくした

変更前 変更後
変更前は単なるリストと見分けがつかない見た目 変更後はリストマーカーを消し、明示的に目次であることを示す見出しを付けた

更前は単なるリストと見分けがつかない見た目で、唯一の差は枠と背景色の有無であった。私は自分のブログを見ていてたまに混乱していた。

そこでリストマーカーを消し、明示的に目次であることを示す見出しを付けることで、錯誤しないように直してみた。目次の見出しについてOpusはCSS装飾を進めてきたが、文字が表示されてるのに選択できないのはキモいし、アクセシビリティ的にもよくないので本体のToC生成実装を直してHTML上に文字列を表示する要素を組み込んでもらった。

追従する目次のほうは特に直していない。ここは本文と明らかに別の位置にあるし、領域が狭く改行が起きるのでマーカーがないと目次のリストが読みづらい気がしたからだ。

IndexNow対応

待望のIndexNow対応!IndexNow対応は二年前に想起したものの面倒で対応をやめていた。

元々は優先度がかなり低いタスクだったが、Claude.aiのサイトでは検索エンジンにインデックスされてないサイトを読んでくれないため、送球にインデックスさせる必要性を感じ導入することにした。

体感ではBingは24時間以内にインデックスしてくれる感じがあったので、これまでは重要性を全く感じていなかったが、それはもう過去の話であってLLM大全盛期の今となっては24時間では遅く、より早いインデックスが求められると考えている。また副次効果としてYandexからのインデックスも期待できるようになる。

年齢確認済の解消文言が長すぎるのを短くした

LLMに書かせたメッセージは概して長いので仕方ないね。

あとがき

しかしまぁ最近見事なまでにLyndbaumのことしか書いていないし、更新も落ち着いてきた部分があるので、もっとブログらしいことを書いていきたい。下書きも地味に溜まってるし…。

とはいえ、直近のアップデートで微妙になった部分もあるので、そこも直す必要があるのだが、急ぐことでもないので、今後はもうちょいのんびりやっていきたいところだ…。というのは何度か過去にも言った気がするのだが、まぁ…w

Lyndbaum v4.36アップデート

adiary置き換え計画始動から連なる、Lyndbaum v4.35アップデートの続き。

今回は改善系の対応を行った。

画面表示時のスケルトン探索処理の効率化

本家と比較したときにパフォーマンスが劣化しているの対応で原因調査をしていたら、スケルトン探索処理の方式が原因だったため、そこを直した。

具体的にはテンプレートエンジンが呼び出しているパーツの探索を効率化した。adiaryのテンプレートエンジンはスケルトンと呼ばれるファイルで管理されており、動的表示のためにサイドバーにあるモジュールや記事、ページのフレームなどの単位でスケルトンが分割されている。

そしてこのシステムは標準スケルトンとテーマスケルトンに分かれており、テーマスケルトンで標準スケルトンを上書きするという振る舞いをしている。Lyndbaumではレスポンシブデザインに適用させるためスケルトンの分割方式を変えていてスケルトンファイルが従来より増えている。

adiary本来の処理では、標準側とテーマ側でファイルがあるかを1つずつ確認していたため、スケルトンファイルの増加によりシステムコールの回数が増えてパフォーマンスの劣化に繋がっていた。今回はこの方式をやめ、何のスケルトンがあるかのキャッシュをあらかじめ作っておき、無駄な探索をしないようにした。

その他細かい無駄な処理を見直し微妙に早くなるようにしている。

FCGIモードでの比較

改修の前後でFCGIモードで極力条件をそろえた状態でベンチマークをとった結果が以下だ。

前提としてadiaryはsatsuki2/satsuki2テーマ、Lyndbaumはlyndbaum/lyndbaumテーマを使っており、記事数もadiaryよりLyndbaumのほうが若干多いため、ベンチマーク的にはadiaryのほうが有利な状況になっている。

またベンチマーク方式はadiary公式の方式に可能な範囲で合わせている。但し計測したマシンについては以下の通りスペックがだいぶ異なる。

構成 製品 備考
OS Ubuntu 26.04.1 LTS
Perl v5.40.1
CPU AMD Ryzen 5 8500G 6C12T 3.5GHz TDP65W
MEM Crucial CP2K16G60C36U5W DDR5-6000 16GB * 2
Storage Crucial P1 CT500P1SSD8JP NVMe SSD 500GB

FCGIモードでのベンチスコア

今回の測定結果としてはab -n 2000 -c 100 -l条件で本家より早くなった。ab -n 100 -c 1 -lでは僅差で負けているが、計測回数が少ないので誤差の可能性もある。計測はサービスを再起動して即座に測定したが、全て手動操作なので起動経過時間で見ると数秒の誤差があるため、完全に平等ではない。

ローカルで実行しているため通信のオーバーヘッドは極めて少なく、確実に実運用よりいい値が出ている。これは本家のベンチスコアも同様だろう。

CMS Ver abコマンド req/s 平均応答(ms)
adiary v3.52b ab -n 2000 -c 100 -l 1184.12 84.451
adiary v3.52b ab -n 100 -c 1 -l 294.8 3.392
lyndbaum v4.35 ab -n 2000 -c 100 -l 1091.55 91.613
lyndbaum v4.35 ab -n 100 -c 1 -l 225.67 4.431
lyndbaum v4.36 ab -n 2000 -c 100 -l 1375.58 72.697
lyndbaum v4.36 ab -n 100 -c 1 -l 291.23 3.434

CGIモードでの比較

CGIを実行する環境がないので、さくらのレンタルサーバー上で動かしているのをローカルのabから叩いた結果になる。さくらのレンタルサーバーにはabが入っていないのでローカルから叩くしかなかった。

テーマや記事データなどはFCGI版と同じ条件でやっている。

また実装の修正と検証に時間がかかった関係で、同一時刻での計測ができておらず、結果は余りあてにならない。一応同じ時間帯にadiaryとlyndbaumの比較はしているが、手間の関係でlyndbaumのバージョンアップ前後での確認は飛ばしている。

Perlのバージョンはv5.32.1だった。

CGIモードでのベンチスコア

リモートサーバーに繋ぎに行っているため-kでKeepAliveを有効にしている。

見た感じは改善してそうだが、通信のオーバーヘッドが入っているほか、試験に使ったのは共用サーバーで時間帯によって負荷が変わるほか、CGIは起動が重いこともあり、数値の信憑性は怪しい可能性がある。しかしそれでも明らかに遅いように見えたのが僅かに早くなったので満足した。

CMS Ver abコマンド req/s 平均応答(ms)
adiary v3.52b ab -n 2000 -c 100 -l -k 306.69 326.06
adiary v3.52b ab -n 100 -c 1 -l -k 11.16 89.635
lyndbaum v4.35 ab -n 2000 -c 100 -l -k 311.13 321.406
lyndbaum v4.35 ab -n 100 -c 1 -l -k 11.43 87.489
adiary v3.52b ab -n 2000 -c 100 -l -k 263.89 378.945
adiary v3.52b ab -n 100 -c 1 -l -k 5.23 191.33
lyndbaum v4.36 ab -n 2000 -c 100 -l -k 268.2 372.851
lyndbaum v4.36 ab -n 100 -c 1 -l -k 5.43 184.152

ベンチマーク測定元ソース

記事に書いてるのは測定結果の一部を切り出したものなので、以下に測定データ全体を残す。

記事に出したベンチマークスコアの元ネタ
CMS 走行時間 Ver モード 記事数 コメント数 タグ数 並列数 件数 keep-alive 失敗 req/s 平均応答(ms) Connect平均 TTFB平均 50% 95% 99% 最大 ab
adiary 12時くらい v3.52b CGI 766 71 208 100 2000 あり 0 306.69 326.06 4 301 54 2434 4944 5289 ab -n 2000 -c 100 -l -k
adiary 12時くらい v3.52b CGI 766 71 208 1 100 あり 0 11.16 89.635 12 60 87 110 293 293 ab -n 100 -c 1 -l -k
lyndbaum 12時くらい v4.35 CGI 779 70 208 100 2000 あり 0 311.13 321.406 4 294 68 2246 4707 5020 ab -n 2000 -c 100 -l -k
lyndbaum 12時くらい v4.35 CGI 779 70 208 1 100 あり 0 11.43 87.489 12 62 87 106 227 227 ab -n 100 -c 1 -l -k
adiary 12時くらい v3.52b FCGI 766 71 208 100 2000 なし 0 1184.12 84.451 31 13 81 95 127 139 ab -n 2000 -c 100 -l
adiary 12時くらい v3.52b FCGI 766 71 208 1 100 なし 0 294.8 3.392 1 2 3 4 4 4 ab -n 100 -c 1 -l
lyndbaum 12時くらい v4.35 FCGI 779 70 208 100 2000 なし 0 1091.55 91.613 18 9 93 105 143 165 ab -n 2000 -c 100 -l
lyndbaum 12時くらい v4.35 FCGI 779 70 208 1 100 なし 0 225.67 4.431 1 3 4 5 5 5 ab -n 100 -c 1 -l
adiary 22時くらい v3.52b CGI 766 71 208 100 2000 あり 0 263.89 378.945 8 340 80 2866 5532 5800 ab -n 2000 -c 100 -l -k
adiary 22時くらい v3.52b CGI 766 71 208 1 100 あり 0 5.23 191.33 30 96 134 487 1275 1275 ab -n 100 -c 1 -l -k
lyndbaum 22時くらい v4.36 CGI 779 70 208 100 2000 あり 0 268.2 372.851 9 323 59 2070 5642 5814 ab -n 2000 -c 100 -l -k
lyndbaum 22時くらい v4.36 CGI 779 70 208 1 100 あり 0 5.43 184.152 28 91 113 501 734 734 ab -n 100 -c 1 -l -k
lyndbaum 22時くらい v4.36 FCGI 780 70 208 100 2000 なし 0 1375.58 72.697 31 13 69 83 117 130 ab -n 2000 -c 100 -l
lyndbaum 22時くらい v4.36 FCGI 780 70 208 1 100 なし 0 291.23 3.434 1 2 3 4 4 4 ab -n 100 -c 1 -l

Lyndbaumテーマで記事タイトルの頭に線を引くようにした

なんとなく記事の境目が分かりづらいなという気がしていたのでマークをつけてみた。本当は横線を上に引こうと思っていたのだが、なんかいまいちだったので頭に縦線を引くことにした。

変更前 変更後

HTTPクライアントをIPv6対応にした

なんとadiaryのHTTPクライアントはIPv4にしか対応していなかった。このため自宅サーバーで自分のドメインに対してHTTPクライアントを実行すると確定で繋がらない問題があった。

IPv6に対応させることでこれを解決した。また拒否IPリストもIPv6に対応させたため、v4.34で行った制限でv6が漏れていた問題にも対応した。

ポートは80か443以外の疎通を許可していないので、妙なポートが疎通することはないが、認証をかけていなければ開けてしまうのでGrafanaやPHPMyAdminとかはちゃんと保護してないと疎通してしまう。そもそも管理コンソールが外から開ける時点でおかしいので、最低でもBasic認証くらいは掛けていてほしいが…w

[&https://]記法でOGカードを出せるようにし、正しく出ないものについても解消した

[&https://]記法で正しく動かないケースがあるのを解消。元々この対応をする過程で一つ前のIPv6に関する課題が浮上したのだが、こっちも不具合とそれとは別の不満があり、直すことにした。

まずこの記法はリンクを書く手間を減らすためのもので、リンク先によってはリッチに出せるものだったが、基本的には[サイトタイトル](https://example.com)のショートハンドでしかなかった。

そしてGitHubを指定するとリッチに出るはずだったのだが、どうにもバグっており[&https://github.com/Lycolia]と書くと<script src="https://gist-it.appspot.com/github/Lycolia"></script>が出力される状態だった。悪意のあるスクリプトが出てきたら即死するところだった。

元の仕様がイケてないのと超ド級のヤバ不具合があったため、リンクカードを出せるようにし、scriptタグが入らないようにした。LLMに書かせたscriptタグの検査は見た感じ甘そうだが、構造上滅多に入らないと思うので一旦放置している。

あとがき

ベンチマークをとる環境の整備とベンチマークの記録と実際の動作確認やら記事向けに余計な情報を取捨選択するやらなにやらで今回の対応はだいぶ疲れた。正直途中で止めて日曜コミットしようかと思ったが、気合で土曜中にやり切った。

お陰でv4.34アップデートのあとがきに書いたとおり、五年半ぶりにGitHubの草を縦に繋げることができた。このためだけにv4.36に乗せるものを減らしたくらいだ。23時にFixさせると絶対に間に合わないので可能な限り19時、遅くとも21時Fixを目指したが、結局余計な機能をねじ込んでしまいFixは22時になった。それでも何とか土曜中にPRを収めマージしきったので何とかなった。手前で映画鑑賞録なんて書くから…

Go製CGIで触っていて明らかに早かったSerene Bach v4でのベンチマークもとって比較しようと思ったが、データコンバートが面倒なのと、へとへとなのでそこは取りやめにした。そもそもバイナリにスクリプトが勝負しても仕方ない。

CGIはコードが読めて中身に変なものがあっても直せるのが売りなので、それを許さないことで高速化を達成しているものと比較しても仕方がない。

Lyndbaum v4.35アップデート

adiary置き換え計画始動から連なる、Lyndbaum v4.34アップデートの続き。

今回はバージョンが0.1しか増えず、控えめなアップデートとなった。内容としては15ファイルの変更と131行の追加、178行の削除があった。追加行107行はGitHub ActionsのWorkflowファイルなので実質削除が本丸である。

今回の変更

変更内容はページキャッシュ機能の削除のみ。この機能はページが表示されたときのHTMLキャッシュをCMSのメモリに持ち、次回アクセス時にキャッシュヒットさせて返す仕組みだった。

しかし動的要素が返せないなどの問題があり、潜在不具合がありそうなので私は使っていなかった。そもそも使わなくても早いというのもある。

CGIモードでは使えない機能ということもあり、機能削減の一環として削除した。機能が少なければ少ないほど保守が容易だし、必要になれば復活させることもできるため削除した。

今後の機能開発予定

今回の対応は少なかったが、やりたいことはまだまだ多くあり、たぶんこれ以外にも日々湧いてくるのでやることは全く尽きていない。

あとがき

Claudeが出したベンチマークスクリプトでは劣化はないことになっていたが、本家の計測指標で使われていたApache Benchを使うと明確な劣化が認められたので、次はここを潰していきたいところだ。

参考までに計測結果を以下に残す。

計測結果

名前 計測コマンド 並列数 件数 失敗 req/s 平均応答(ms) Connect平均 TTFB平均 50% 95% 99% 最大
adiary v3.52b ab -n 2000 -c 100 -l 100 2000 0 1184.12 84.451 31 13 81 95 127 139
adiary v3.52b ab -n 100 -c 1 -l 1 100 0 294.8 3.392 1 2 3 4 4 4
Lyndbaum v4.35 ab -n 2000 -c 100 -l 100 2000 0 1091.55 91.613 18 9 93 105 143 165
Lyndbaum v4.35 ab -n 100 -c 1 -l 1 100 0 225.67 4.431 1 3 4 5 5 5

計測したマシン

構成 製品 備考
OS Ubuntu 26.04.1 LTS
CPU AMD Ryzen 5 8500G 6C12T 3.5GHz TDP65W
MEM Crucial CP2K16G60C36U5W DDR5-6000 16GB * 2
Storage Crucial P1 CT500P1SSD8JP NVMe SSD 500GB

また、内容はまだ確認できていないがPageSpeed Insightsの結果も作ったので後で見れるよう残しておく。

Lyndbaum v4.34アップデート

adiary置き換え計画始動から連なる、Lyndbaum v4.26アップデートの続き。

わずか二日でバージョンが0.8も増えた。直近で散々書いてきた、やることがなくなってきたとは一体何だったのか…。

今回は機能削除とセキュリティ対応、デグレード対応を主に行い、182ファイルの変更と4,659行の追加、4,585行の削除があった。

セキュリティ対応

ディレクトリトラバーサルができた問題を修正

特定の条件で..が指定されたときにCGIのルートフォルダなど本来アクセス出来てはならない場所を操作できる問題を修正した。

ソケットが777で保存される問題を修正

660にし、ユーザーとグループしか見れないようにした。

HTTPSでアクセスされたとき、CookieにSecure属性を付与するように修正

何も属性がついてなかったため。

セッションIDが予測可能だった問題を修正

rand()からPOSIXの乱数器に変更。

有害なタグを使えないように修正

管理者自身が自ら脆弱性を埋め込む可能性があるのを回避した。

これによってよく知らないスクリプトをコピペで記事などに埋め込んだ時に管理者が自滅するのを防止する。

lyndbaum.httpd.plを削除

nginxやApacheにさえ無限の脆弱性があるのにadiaryのhttpdに脆弱性がないはずがないと思って検査したところ無数の脆弱性が出てきたので削除した。

デバッグ用に残すことも検討したが、デバッグ時に脆弱性や不具合にぶつかったときに、その由来がhttpdか本体か区別できないため残さないことにした。

プライベートモードの削除

プライベートモードを突破できる脆弱性がいくつかあったため機能削除した。

プライベートにする場合、サーバー側で認証をかければ済む。

複数ユーザー機能の削除

管理者アカウントのみに限定し、ユーザー管理機能を丸ごと葬った。

これにより編集権限を持つユーザーが管理者やほかの編集ユーザーに攻撃可能になる脆弱性を作りこめてしまう問題など、アカウント機能があることで起こりえる問題が恒久的に消えた。

HTTPクライアントのHTTPS通信で証明書を検証するようにした

別にやらなくてもいいのだがやるようにした。

半年くらい前にQiitaが証明書違反になっているのを見かけたが、こういう場合は正規の通信先でもこけるようになるためOGP取得処理とかがこける。

ファイル名の変更で既存のファイルを上書きしないようにした

リネーム前に存在チェックをかけているため、これが起きることは現実的にはないのだが、原理上起きないようにした。

HTTPS通信でタイムアウトするようにした

今まではタイムアウトしなかったため相手から切られるか、OOMするまで放置されていた。

アップロードしたファイルをリネームすることで本来上げられないファイル拡張子を上げることができた

アップロード可能な拡張子を制限しているのにアップロード後にリネームすることでこの制約を抜けることができた。

これは次のケースで問題が起きることがある。ただし現実的にこれらが起きることはまずない。何故なら管理者の自爆操作だからだ。

  • 悪意のあるスクリプトが仕込まれたHTMLを.txtとしてアップロードし、その後.htmlに書き換えて開くことで同一オリジン攻撃が可能になり、管理権限を乗っ取れる
  • 悪意のあるスクリプトが仕込まれたPHPを.txtとしてアップロードし、その後.phpに書き換えて開くことで任意コードが実行可能になる

書いていて思ったこととして、アップロードできる拡張子の制限という機能そのものをなくしたほうがいい気がしてきた。こんなことをしても無駄な処理とテストが増えるだけなので。

HTTPクライアントに制限をつけた

内部向けのアクセスができないようにし、巨大なファイルをダウンロードしようとしたら止めるようにした。

間違えて内部にいるPrometheusのような管理ツールのOGPを記事に展開しようとしてもできなくなった。

IPv4向けの対応であり、v6向けには特に何もしていない。

v6にして行うと自宅サーバーで自分がホストする別のサービスに繋げなくなるため、v6に対して行う予定は今のところない。

SomeOrigin攻撃対策をした

レンタルサーバーでは*.sakura.ne.jpや*.x0.toなど、サブドメインが異なる他人が多くいるため、HTTPヘッダーを検証し、同一オリジン以外からのCSRF攻撃が起きないようにした、

検索操作時に任意コード実行の脆弱性があったのを修正

このブログには付けていないが、特定の検索機能で任意コードが実行可能だったので対応した。

check_user_dataの型チェックが常に偽になるのを修正

動作的には特に問題がなかったがバグではあるため直した。

ログインの失敗を同じIPからの回数でも数えるようにした

IDに対して行っていると管理者のIDに対してログイン失敗を繰り返すことで管理者を締め出せるため、IPでも見るようにした。

その他

  • HTTP(S)通信で無限リダイレクトしないようにした
  • メールの送信でタイムアウトするようにした
  • wwwのプロセスのumaskを0から002にする
  • indexを一時ファイルに書いてからrenameで置き換え、ロックの後に置き換わっていないか確かめる
  • 空のindexを作り直し、ファイルの書き込みのエラーを返す
  • pkeyを指定したinsertのシリアル値を、indexと一緒に保存する
  • ソケットのパーミッションを変更
  • その他セキュリティ修正をいくつか追加

不具合対応

ファイル名によってアップロード後の操作ができない問題を修正

ファイル操作によってファイル名の検査処理が異なりエラーになっていたのを直した。

その他

  • JSONパーサーが正しくJSONをパース出来ていなかった問題の修正
  • 途中で切れたテンプレートのキャッシュでページがエラーのままになっていたのを修正
  • テキストDBの検索の値を埋め込んだ関数を際限なく保持していたので、1000個を超えたら捨てるようにした
    • OOMが起きる可能性があった
  • ページキャッシュ機能で同じ秒に同じ大きさで書き直されたファイルの古い内容を出し続けることがあったのを修正
    • 現実問題ほぼほぼ起きないと思うが一応対応した

改善

メインカラムが<div />だったのを<main />に変更

Webアクセシビリティ対応。

自動テストの高速化

11ファイル、1,475件、108秒を分割し、テストを並行で走行するようにした。結果、14ファイル、1,476件、26秒に短縮した。1件増えてるのは分割したせい。

機能削除の繰り返しにより最新版では22ファイル、1,290件、20秒にまで減っている。

env.cgiとconf.cgiを統一し、設定を全体的に見直した

分けている意味が分からないため統一した。

また設定の持ち方がカオスだったのを見直し、大半の設定を画面からできるようにし、致命的なケース以外では設定ファイルをいじくらなくていいようにした。

アイキャッチの自動設定機能を廃止

アイキャッチを編集画面で選んだ画像だけにし、自動設定機能を外した。

これはフロントエンドの表示とサーバーサイド側の処理で判定が異なり、画面上の表示と実際の処理が異なっていたほか、コードフェンスの中に画像のパスがあると、それを取り込んでしまうなど問題が色々あって対応が面倒だったのでやめた。

ユーザーが選べば解決するなら凝った実装を排除したほうがいい。ユーザーの手間が3秒増える程度。どうせ選びたいときは選ぶわけだし。

ページトップのOGPを無条件で出すようにした

v0.5.0でOGPの出力条件を削除し、UserAgentに依存させないようにしたの対応漏れ。

ついでにTwitter向けのOGPのサイズをデフォルト画像とそれ以外で可変にする対応を入れているが、私はTwitterをしていないため動作確認してない。

v4.29/v4.33より古いデータからのアップデートサポートを切り捨て

後方互換性維持のために残していた負債実装をすべて削除した。

adiary v3.52devからアップデートする場合、一度v4.29のタグをチェックアウトし、バージョンアップしたのち、次にv4.33のタグをチェックアウトしアップデートし、その後v4.34のタグをチェックアウトしてアップデートすることでアップデート可能。

v4.34時点のタグをチェックアウトするとアップデート処理が消滅しているので、段階的に作業する必要がある。

マルチサイト削除対応で残った残骸を除去

この対応によりv4.29/v4.33以前との互換性が完全に消滅した。

あとがき

今回のコードの変更量はバージョンのわりに少ないがClaudeを使って何回も多角的に調査させたため、木曜の今時点でMax x5プランで28%も使ってしまった。

Fable 5.1も使ってみたが的外れな指摘が多く役に立たず、役に立った指摘はOpus 5.5からのものだった。また、現時点でChatGPTの契約がまだ生きているのでGPT-6.1 Solにも見させているが、GPT-6.1 Solの指摘はClaudeとは全く違う視点から来ているのにクロスチェックに便利だと感じた。但し指摘が的外れであることも少なくなく、有用性としては補助程度に留まった。

ChatGPTの功績を残したのでGitHubの貢献者にCodexを生やすことができた。Codexはv4.27のHTTP通信のタイムアウトをスレッドごとに制御するを担当した。なお私はCodexをほとんど信頼してないのでこれしかやらせていない。

しかしまぁここ一ヶ月のコミットは本当にすごいことになっているのでコーディングエージェントの凄さを痛感する。

前も書いた気がするが去年まではLLMはハルシネーションの塊だと思っていたし、半年前でもまだ私のほうが上だと思っていたのに、もはや太刀打ちできない。私がやっているのはPRを手書きし、この記事を書くことでコードレビューを多少なりとも行い、気になった部分を見たり、わからなければLLMに確認する程度だ。

GitHubの草も珍しく列が繋がりそうになった。

縦に繋がったことは過去に一度しかなく、2021年初頭の話なので、もし繋がったら五年半ぶりの快挙になる。