背景
随着Web应用的普及和发展,前端代码越来越多地暴露在客户端环境中运行。这种开放性虽然带来了更好的用户体验,但也为恶意用户提供了可乘之机。前端 JavaScript 代码容易被查看、修改甚至替换,这使得保护前端逻辑变得尤为重要。
示例
输入验证绕过
示例代码:
<template><div><el-form :model="ruleForm" ref="ruleForm":rules="rules" label-position="left" label-width="86px"><el-row class="row-from"><el-col class="text-left col-item"><el-form-item label="项目成员" prop="oneName"><el-tooltip class="item" size="medium" effect="dark":disabled="selectNum == 0" placement="top"
v-model="isShowTooltip"><div slot="content"class="tooltip-con"><div v-for="item in selectUserList":key="item.userId"class="size16 team-text">{{`${item.userName} -
${item.phone}`}}</div><i class="el-icon-close close" @click="closeTooltip"></i></div><el-badge :value="selectNum"class="item" type="primary"><el-input size="medium" v-model="ruleForm.oneName" clearable @focus="showDialog"
placeholder="请选择"></el-input></el-badge></el-tooltip></el-form-item></el-col></el-row><el-row class="row-from"><el-col class="text-left"><el-button class="btn select" size="medium" @click="submit" type="primary">提交</el-button></el-col></el-row></el-form><SDialog ref="SDialog" @selectUser="selectUser"></SDialog></div></template><script>import SDialog from'@/views/popupAndSelect/SDialog.vue';exportdefault{
name:'show',data(){constcheckOneName=(rule, value, callback)=>{
console.log('checkTeam::: ', value);if(!value){callback(newError('请选择和作社项目组名称'))}else{callback()}};return{
isShowTooltip:false,
selectNum:0,
rules:{
oneName:[{ required:true, message:'请选择名字', trigger:'blur,change'},{ validator: checkOneName, trigger:'change'}],},
ruleForm:{
nameList:[],
userIds:[],
oneName:"",},
selectUserList:[],}},
components:{ SDialog },
methods:{showDialog(){this.$refs.SDialog.show()},selectUser(data){
console.log('data::: ', data);// 拿到所有用户的 userNamelet nameList = data.map(item=> item.userName);this.ruleForm.oneName =`${data[0].userName} - ${data[0].phone}`;this.selectNum = nameList.length;this.ruleForm.nameList = nameList;// 拿到所有用户的 userIdthis.ruleForm.userIds = data.map(item=> item.userId);this.selectUserList = data;},// 关闭 TooltipcloseTooltip(){this.isShowTooltip =false;},// 提交表单submit(){this.$refs.ruleForm.validate(valid=>{if(valid){this.$message({
message:'提交成功',
type:'success'});}else{
console.log('error submit!!');returnfalse;}});},}}</script>
绕过方法: 攻击者可以通过修改浏览器控制台中的代码,进行绕过验证
防范措施:
- 后端验证:始终在后端进行输入验证,确保数据的安全性。
- 禁用开发者工具:虽然不推荐,但在某些情况下可以考虑禁用开发者工具。
- 打包时对代码进行加密混淆处理,使原始代码变得难以阅读和理解。
参考文档: 使用 webpack-obfuscator 进行代码混淆
css样式控制绕过
在 Vue 中使用
v-show
判断的按钮
示例代码:
<template><div><h1>js绕过</h1><div><button v-show="showBtn" @click="submit">btn1</button><button v-if="showBtn" @click="submit1">btn2</button></div></div></template><script>exportdefault{
name:"JsbBypass",data(){return{
showBtn:false,};},
methods:{submit(){
console.log('submit触发了::: ');},submit1(){
console.log('submit1触发了::: ');}}};</script>
绕过方法: 攻击者可以通过修改浏览器控制台中的css属性,使按钮在页面显示出来,从而可以点击触发相应的事件
防范措施:
- 禁用开发者工具:虽然不推荐,但在某些情况下可以考虑禁用开发者工具。
- 改为
v-if
:使用v-if
后,页面上不对存在元素。<buttonv-if="showBtn"@click="submit">btn1</button>
- 在绑定的事件函数内部做判断
submit(){if(!this.showBtn)return; console.log('submit触发了::: ');},
使用
readonly
或者
disabled
禁用表单元素
示例代码:
<template><div><h1>css绕过</h1><div><input style="width: 200px;margin-right:15px":disabled="isDisabled"></input><input style="width: 200px;margin-right:15px":readonly="isReadonly"></input><button :disabled="isDisabled" @click="submit">btn</button></div></div></template><script>exportdefault{
name:"disabledBypass",data(){return{
isDisabled:"disabled",
isReadonly:"readonly"};},
methods:{submit(){
console.log('submit触发了::: ');},}};</script>
绕过方法: 攻击者可以通过删除浏览器控制台标签的 css 属性,从而使得已被禁用的表单元素生效。
防范措施:
- 禁用开发者工具:虽然不推荐,但在某些情况下可以考虑禁用开发者工具。
- 服务器端验证:确保对提交的数据进行严格的验证。
- 按钮可以通过绑定的事件函数内部进行判断
submit(){if(this.isDisabled ==='disabled'||this.isReadonly ==='readonly')return; console.log('submit触发了::: ');},
总结
在 Web 应用开发中,前端代码的开放性为恶意用户提供了绕过验证和控制的机会。为了保障应用的安全性,应采取多方面的防护措施。首先,始终在服务器端进行严格的输入验证,确保数据的安全性和完整性。其次,合理使用 Vue 的响应式特性,如 v-if 和 v-show,并在事件处理函数中进行状态检查,防止用户通过修改浏览器控制台中的代码或 CSS 属性来绕过前端控制。此外,可以考虑对前端代码进行混淆处理,增加攻击者的破解难度。综合这些措施,可以有效提升 Web 应用的安全性。
版权归原作者 你不讲 wood 所有, 如有侵权,请联系我们删除。