セキュリティ:RSS漏出の修正

守矢諏訪子 <suwako@076.moe>、2026-11-10 17:14
コミット 62fe9d8d093f8d0781ca3eeebc66072b3c9bee68 ・親 ce7caf8 ・ファイルを見る

2個のファイル、+16 -2

@@ -44,6 +44,20 @@
4444 private string $domain = 'technicalsuwako.moe';
4545
4646 /**
47+ * フィードは誰でも読めるので、会員・支援者・スタッフ限定の記事を除外する
48+ * (getPosts()はプレビューを隠すだけで、記事そのものは返す)
49+ *
50+ * @param array $posts 投稿の配列
51+ * @return array 公開記事だけの配列
52+ */
53+ private function publicOnly(array $posts): array {
54+ $restricted = ['memberonly', 'subscriberonly', 'staffonly', 'nintendodevonly'];
55+ return array_values(array_filter($posts, function($post) use ($restricted): bool {
56+ return empty(array_intersect($restricted, $post['category'] ?? []));
57+ }));
58+ }
59+
60+ /**
4761 * 最新の5記事のAtomフィードを生成する
4862 *
4963 * @param array $params パラメータ配列
@@ -54,7 +68,7 @@
5468 // 最新の投稿を取得
5569 $posts = $this->getPosts('/blog/', null);
5670 // 最新の5件に制限
57- $posts = array_slice($posts, 0, 5);
71+ $posts = array_slice($this->publicOnly($posts), 0, 5);
5872
5973 // サイトのドメインを取得
6074 $domain = $_SERVER['HTTP_HOST'];
@@ -157,7 +157,7 @@
157157 $nyuE = '';
158158
159159 if ($doRegister) {
160- if (!\verify_csrf_token($_POST['csrf_token'])) {
160+ if (!is_string($_POST['csrf_token'] ?? null) || !\verify_csrf_token($_POST['csrf_token'])) {
161161 header('Location: /');
162162 exit();
163163 }