Kaynağa Gözat

fix: prevent login form query leaks

Codex 1 ay önce
ebeveyn
işleme
92eb4ed513
3 değiştirilmiş dosya ile 15 ekleme ve 3 silme
  1. 2 2
      public/login.html
  2. 4 0
      public/login.js
  3. 9 1
      src/server.js

+ 2 - 2
public/login.html

@@ -41,7 +41,7 @@
           <button data-mode="register" type="button">注册</button>
         </div>
 
-        <form id="loginForm" class="login-form">
+        <form id="loginForm" class="login-form" method="post" action="/api/login">
           <label>
             用户名或邮箱
             <input name="username" autocomplete="username" required autofocus>
@@ -53,7 +53,7 @@
           <button type="submit">登录</button>
         </form>
 
-        <form id="registerForm" class="login-form hidden">
+        <form id="registerForm" class="login-form hidden" method="post" action="/api/register">
           <label>
             用户名
             <input name="username" autocomplete="username" minlength="3" required>

+ 4 - 0
public/login.js

@@ -5,6 +5,10 @@ const modeTitle = document.querySelector('#modeTitle');
 const modeEyebrow = document.querySelector('#modeEyebrow');
 const tabs = document.querySelectorAll('[data-mode]');
 
+if (window.location.search) {
+  window.history.replaceState(null, '', window.location.pathname);
+}
+
 for (const tab of tabs) {
   tab.addEventListener('click', () => setMode(tab.dataset.mode));
 }

+ 9 - 1
src/server.js

@@ -116,6 +116,9 @@ const server = http.createServer(async (req, res) => {
 
     const user = getRequestUser(req, url.pathname);
     if (isLoginAsset(url.pathname)) {
+      if ((url.pathname === '/login' || url.pathname === '/register') && url.search) {
+        return redirect(res, url.pathname);
+      }
       if ((url.pathname === '/login' || url.pathname === '/register') && user) return redirect(res, '/');
       return await serveStatic(req, res, url);
     }
@@ -592,7 +595,12 @@ async function readJson(req) {
   const chunks = [];
   for await (const chunk of req) chunks.push(chunk);
   if (!chunks.length) return {};
-  return JSON.parse(Buffer.concat(chunks).toString('utf8'));
+  const raw = Buffer.concat(chunks).toString('utf8');
+  const contentType = String(req.headers['content-type'] || '').toLowerCase();
+  if (contentType.includes('application/x-www-form-urlencoded')) {
+    return Object.fromEntries(new URLSearchParams(raw).entries());
+  }
+  return JSON.parse(raw);
 }
 
 function sendJson(res, status, payload) {