From a60dda952866c381e69cb43d93880c506a9192f1 Mon Sep 17 00:00:00 2001 From: posimai Date: Tue, 17 Mar 2026 17:26:59 +0900 Subject: [PATCH] fix: add URL protocol validation and reaction type validation --- server.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server.js b/server.js index 6a904d2d..97299cf3 100644 --- a/server.js +++ b/server.js @@ -1424,6 +1424,10 @@ ${excerpt} r.post('/together/share', async (req, res) => { const { group_id, shared_by, url = null, title = null, message = '', tags = [] } = req.body || {}; if (!group_id || !shared_by) return res.status(400).json({ error: 'group_id と shared_by は必須です' }); + if (url) { + try { const p = new URL(url); if (!['http:', 'https:'].includes(p.protocol)) throw new Error(); } + catch { return res.status(400).json({ error: 'url は http/https のみ有効です' }); } + } try { const grpCheck = await pool.query('SELECT id FROM together_groups WHERE id=$1', [group_id]); if (grpCheck.rows.length === 0) return res.status(404).json({ error: 'グループが見つかりません' }); @@ -1488,6 +1492,7 @@ ${excerpt} r.post('/together/react', async (req, res) => { const { share_id, username, type = 'like' } = req.body || {}; if (!share_id || !username) return res.status(400).json({ error: 'share_id と username は必須です' }); + if (!['like', 'star', 'fire'].includes(type)) return res.status(400).json({ error: 'type は like/star/fire のみ有効です' }); try { const existing = await pool.query( 'SELECT 1 FROM together_reactions WHERE share_id=$1 AND username=$2 AND type=$3',