提交登录/注册表单时密码暴露在URL中的安全问题求助
登录注册表单密码邮箱URL明文泄露问题
我开发了一套登录与注册表单,表单数据提交至后端完成验证,验证通过返回200状态码。后端使用bcryptjs对数据库中的密码进行哈希存储,但目前存在严重安全问题:提交表单时,邮箱和密码会显示在URL中。
前端代码
const Form = ({ sendprop }) => { const [formValue, setFormValue] = useState({ name: "", email: "", password: "", confirmPassword: "", }); function onFormChange(e) { console.log("target : "+e.target.value); setFormValue({ ...formValue, [e.target.name]: e.target.value }); console.log(formValue); } const handleSubmit=async(e,prop)=>{ e.preventDefault(); if(prop==="signup"){ console.log("in handleSubmit") if(formValue.password===formValue.confirmPassword){ console.log("in if") const res=await axios.post('http://localhost:8000/signup',{ ...formValue }) console.log(res); } } else{ const {email,password}=formValue const body={ email:email, password:password } const res= await axios.post('http://localhost:8000/login',body); console.log(res); } }; return ( <> <form onSubmit={(e)=>{handleSubmit(e,sendprop)}}> <div id="input-div"> {sendprop === "signup" ? <NameInput passState={{formValue,setFormValue}}/> : " "} <input type="email" placeholder="E m a i l A d d r e s s" id="email-input" className="form-input" name="email" onChange={onFormChange} value={formValue.email} /> <div id="border" className="border-div" /> <input type="password" placeholder="P a s s w o r d" id="password-input" className="form-input" name="password" onChange={onFormChange} value={formValue.password} /> <div id="border" className="border-div" /> {sendprop === "signup" ? <ConfirmPassword passState={{formValue,setFormValue}}/> : " "} </div> <div id="submit-btn-div"> <button type="submit" id="submit-btn"> S U B M I T </button> </div> {sendprop === "signup" ? <LoginAccount /> : " "} {sendprop !== "signup" ? <CreateAccount /> : " "} </form> </> ); }; export default Form;
后端登录API代码
router.post('/login',async(req,res)=>{ const {name,email,password}=req.body; const data = await UserSchemaModel.findOne({email}); console.log(data); try{ if(data===null){ res.status(403).send({message:"email doesnt exist"}); } else{ isMatch=await bcryptjs.compare(password,data.password); if(!isMatch){ res.status(401).send({message:"password doesnt match"}); } else{ res.status(200).send({ msg: 'success', statusCode: res.statusCode }); } } } catch(error){ console.log(error); res.status(400).send({error}); } })
问题原因与修复方案
核心原因
虽然代码中使用axios.post发送请求且调用了e.preventDefault(),但表单标签未指定method="POST",在某些异常场景下(比如handleSubmit逻辑未正常执行),浏览器会触发表单默认的GET提交行为,导致敏感数据暴露在URL中。
修复步骤
给form标签添加method属性
修改form标签,明确指定提交方法为POST,从根源上避免默认GET行为:<form method="POST" onSubmit={(e)=>{handleSubmit(e,sendprop)}}>确认e.preventDefault()的执行时机
当前代码中handleSubmit第一行就调用了e.preventDefault(),这是正确的,确保它不会被任何条件判断包裹,保证无论分支逻辑如何,都能阻止表单默认提交。额外安全强化
- 生产环境必须使用HTTPS协议,防止数据在传输过程中被窃听;
- 可给表单添加
autocomplete="off"属性,避免浏览器自动填充带来的潜在风险; - 后端可添加CSRF防护,进一步提升安全性。
内容的提问来源于stack exchange,提问作者Lord
相关产品推荐
相关产品推荐

