Skip to content

Commit 6bf737f

Browse files
authored
Merge pull request #282 from HXSecurity/header
feature:Add Response header vulnerability merge
2 parents 03a13ac + 6cc0606 commit 6bf737f

File tree

5 files changed

+297
-16
lines changed

5 files changed

+297
-16
lines changed

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ VUE_APP_ATOM_API = '/atom-webapi'
88

99
# target host
1010

11-
# VUE_TARGET_HOST = 'http://192.168.0.64:8000'
12-
VUE_TARGET_HOST = 'https://iast-test.huoxian.cn'
11+
VUE_TARGET_HOST = 'http://192.168.0.64:8000'
12+
# VUE_TARGET_HOST = 'https://iast-test.huoxian.cn'
1313
# VUE_TARGET_HOST = 'http://52.81.92.214:30485'
1414
# VUE_TARGET_HOST = 'http://iast.huoxian.cn'
1515

src/services/vuln.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,12 @@ export default () =>
148148
getConfig(type: any): Promise<iResponse> {
149149
return request.get(`/integration/config/` + type)
150150
}
151+
152+
getHeaderVul(params: any): Promise<iResponse> {
153+
return request.get(`/header_vul`, { params })
154+
}
155+
156+
deleteHeaderVul(id: any): Promise<iResponse> {
157+
return request.delete(`/header_vul/${id}`)
158+
}
151159
})()

src/views/vuln/VulnDetail.vue

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,26 @@
192192
</div>
193193
<div class="split-line"></div>
194194
</template>
195-
195+
<div class="url-list">
196+
<UrlComponent
197+
v-for="(url, index) in urls"
198+
:key="index"
199+
:url="url"
200+
></UrlComponent>
201+
<div class="pagination-box">
202+
<el-pagination
203+
:current-page="headerPage"
204+
background
205+
:page-sizes="[10, 20, 50, 100]"
206+
:page-size="headerPageSize"
207+
layout=" prev, pager, next, jumper, sizes, total"
208+
:total="total"
209+
@size-change="handleSizeChange"
210+
@current-change="handleCurrentChange"
211+
>
212+
</el-pagination>
213+
</div>
214+
</div>
196215
<!-- Stain flow vul-->
197216
<div v-if="vulnObj.graphs.length" class="module-title">污点流图</div>
198217
<div v-if="vulnObj.graphs.length">
@@ -293,13 +312,16 @@ import qs from 'qs'
293312
import LinkList from './components/linkList.vue'
294313
import StacksList from './components/stacksList.vue'
295314
import Sync from './components/sync.vue'
315+
import UrlComponent from './components/urlComponent.vue'
316+
import emitter from '../taint/Emitter'
296317
297318
@Component({
298319
name: 'VulnDetail',
299320
components: {
300321
LinkList,
301322
StacksList,
302323
Sync,
324+
UrlComponent,
303325
},
304326
})
305327
export default class VulnDetail extends VueBase {
@@ -461,14 +483,20 @@ export default class VulnDetail extends VueBase {
461483
this.cardIndex = 0
462484
await this.getStatus()
463485
await this.getVulnDetail()
486+
await this.getUrls()
464487
this.syncInfo = {
465488
id: this.$route.params.id,
466489
}
467490
}
468491
async created() {
492+
emitter.on('getUrls', this.getUrls)
469493
this.init()
470494
}
471495
496+
async beforeDestroy() {
497+
emitter.off('getUrls', this.getUrls)
498+
}
499+
472500
private goToPoolDetail() {
473501
if (this.vulnObj.vul.method_pool_id) {
474502
const { href } = this.$router.resolve({
@@ -913,6 +941,33 @@ export default class VulnDetail extends VueBase {
913941
return className
914942
}
915943
944+
private urls: any = []
945+
private headerPage = 1
946+
private headerPageSize = 10
947+
async getUrls() {
948+
const res = await this.services.vuln.getHeaderVul({
949+
page: this.headerPage,
950+
page_size: this.headerPageSize,
951+
vul_id: this.selectedId,
952+
})
953+
if (res.status === 201) {
954+
this.urls = res.data
955+
this.total = res.page.alltotal
956+
} else {
957+
this.$message.error(res.msg)
958+
}
959+
}
960+
961+
handleSizeChange(val: number) {
962+
this.headerPageSize = val
963+
this.getUrls()
964+
}
965+
966+
handleCurrentChange(val: number) {
967+
this.headerPage = val
968+
this.getUrls()
969+
}
970+
916971
// exportVul() {
917972
// var projectName = this.vulnObj.vul.project_name
918973
// request
@@ -990,6 +1045,12 @@ export default class VulnDetail extends VueBase {
9901045
font-size: 14px;
9911046
}
9921047
1048+
.pagination-box {
1049+
padding-top: 12px;
1050+
display: flex;
1051+
justify-content: flex-end;
1052+
}
1053+
9931054
.fixed-warp {
9941055
position: fixed;
9951056
top: 0;
@@ -1121,7 +1182,7 @@ export default class VulnDetail extends VueBase {
11211182
border: 1px solid #e6e9ec;
11221183
border-radius: 2px;
11231184
background: #fff;
1124-
::v-deeptt {
1185+
::v-deep(tt) {
11251186
color: red !important;
11261187
font-style: normal !important;
11271188
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<template>
2+
<div class="url">
3+
<div class="top">
4+
<div class="title">
5+
{{ url.url }}
6+
</div>
7+
<div class="btn">
8+
<span>
9+
<i class="el-icon-delete-solid" @click="deleteHeaderVul"></i>
10+
</span>
11+
<span v-if="show" @click="show = !show">
12+
<span>
13+
<i class="el-icon-caret-top"></i>
14+
</span>
15+
</span>
16+
<span v-else @click="show = !show">
17+
<span>
18+
<i class="el-icon-caret-bottom"></i>
19+
</span>
20+
</span>
21+
</div>
22+
</div>
23+
<div v-show="show" class="bottom">
24+
<div class="selectForm">
25+
<div>
26+
<div
27+
v-for="item in httpOptions"
28+
:key="item.value"
29+
class="select-item"
30+
:class="item.value === state && 'active'"
31+
@click="state = item.value"
32+
>
33+
{{ item.label }}
34+
</div>
35+
</div>
36+
37+
<div class="replay-box">
38+
<!-- <div class="replay-btn" @click="goToPoolDetail">
39+
<i class="iconfont icon" style="margin-right: 4px; font-size: 12px"
40+
>&#xe6b3;</i
41+
>请求重放
42+
</div> -->
43+
<el-select
44+
v-model="requsetIndex"
45+
class="request-select"
46+
size="small"
47+
@change="changeRequest"
48+
>
49+
<el-option
50+
v-for="(request, key) in url.details"
51+
:key="key"
52+
:value="key"
53+
:label="request.agent_name"
54+
></el-option>
55+
</el-select>
56+
</div>
57+
</div>
58+
<div v-show="state === 1" class="markdownContent httpRequest">
59+
<MyMarkdownIt :content="req_md" style="color: #747c8c"></MyMarkdownIt>
60+
</div>
61+
<div v-show="state === 0" class="markdownContent httpRequest">
62+
<MyMarkdownIt :content="res_md" style="color: #747c8c"></MyMarkdownIt>
63+
</div>
64+
</div>
65+
</div>
66+
</template>
67+
68+
<script lang="ts">
69+
import { Prop, Component } from 'vue-property-decorator'
70+
import VueBase from '@/VueBase'
71+
import emitter from '@/views/taint/Emitter'
72+
73+
@Component({ name: 'UrlComponent' })
74+
export default class LinkList extends VueBase {
75+
@Prop() url: any
76+
77+
private state = 1
78+
private httpOptions = [
79+
{ value: 1, label: '请求' },
80+
{ value: 0, label: '响应' },
81+
]
82+
83+
private requsetIndex = 0
84+
private req_md = ''
85+
private res_md = ''
86+
87+
private changeRequest(e: any) {
88+
this.requsetIndex = e
89+
this.req_md = this.url.details[e].req_header
90+
this.res_md = this.url.details[e].res_header
91+
}
92+
93+
private show = false
94+
95+
private async deleteHeaderVul() {
96+
this.$confirm('确定删除该URL吗?', '提示', {
97+
confirmButtonText: '确定',
98+
cancelButtonText: '取消',
99+
type: 'warning',
100+
})
101+
.then(async () => {
102+
const res = await this.services.vuln.deleteHeaderVul(this.url.id)
103+
if (res.status === 201) {
104+
this.$message.success('删除成功')
105+
emitter.emit('getUrls')
106+
} else {
107+
this.$message.error('删除失败')
108+
}
109+
})
110+
.catch(() => {
111+
return false
112+
})
113+
}
114+
115+
created() {
116+
this.req_md = this.url.details[this.requsetIndex].req_header
117+
this.res_md = this.url.details[this.requsetIndex].res_header
118+
}
119+
}
120+
</script>
121+
122+
<style scoped lang="scss">
123+
.url {
124+
.top {
125+
padding: 12px 8px;
126+
border-top: 1px solid #e6e9ec;
127+
display: flex;
128+
justify-content: space-between;
129+
.btn {
130+
span {
131+
margin-left: 8px;
132+
cursor: pointer;
133+
}
134+
}
135+
}
136+
.bottom {
137+
.selectForm {
138+
display: flex;
139+
padding: 16px 0 0 0;
140+
justify-content: space-between;
141+
.select-item {
142+
display: inline-block;
143+
font-size: 14px;
144+
font-weight: 500;
145+
color: #959fb4;
146+
text-align: center;
147+
line-height: 32px;
148+
cursor: pointer;
149+
width: 60px;
150+
height: 32px;
151+
border-radius: 32px;
152+
}
153+
.select-item.active {
154+
color: #1a80f2;
155+
background: #f6f8fa;
156+
}
157+
.request-select {
158+
width: 364px;
159+
}
160+
}
161+
.markdownContent {
162+
height: 196px;
163+
overflow-y: auto;
164+
margin-top: 16px;
165+
padding: 6px;
166+
/* 分隔线 */
167+
border: 1px solid #e6e9ec;
168+
border-radius: 2px;
169+
background: #fff;
170+
::v-deep(tt) {
171+
color: red !important;
172+
font-style: normal !important;
173+
}
174+
}
175+
}
176+
}
177+
</style>

src/views/vuln/components/vulnCard.vue

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,49 @@
2929
:get-table-data="getTableData"
3030
:source_type="1"
3131
></Sync>
32-
<div class="top-stack">
33-
<i class="iconfont iconyuandianzhong"></i>
34-
<span>
35-
{{ item.top_stack }}
36-
</span>
37-
</div>
38-
<div class="bottom-stack">
39-
<i class="iconfont iconyuandianzhong"></i>
40-
<span>
41-
{{ item.bottom_stack }}
42-
</span>
43-
</div>
32+
<template v-if="item.is_header_vul">
33+
<div style="height: 120px; margin-top: 18px">
34+
<div
35+
v-for="(header_vul_url, index) in item.header_vul_urls.slice(0, 3)"
36+
:key="index"
37+
class="header-vul-url"
38+
>
39+
{{ header_vul_url.url }}
40+
</div>
41+
<el-tooltip
42+
class="item"
43+
effect="dark"
44+
placement="top-start"
45+
:disabled="item.header_vul_urls.length <= 2"
46+
>
47+
<template #content>
48+
<div style="max-height: 200px; overflow: auto">
49+
<div
50+
v-for="(header_vul_url, index) in item.header_vul_urls"
51+
:key="index"
52+
>
53+
{{ header_vul_url.url }}
54+
</div>
55+
</div>
56+
</template>
57+
<span>更多</span>
58+
</el-tooltip>
59+
</div>
60+
</template>
61+
<template v-else>
62+
<div class="top-stack">
63+
<i class="iconfont iconyuandianzhong"></i>
64+
<span>
65+
{{ item.top_stack }}
66+
</span>
67+
</div>
68+
<div class="bottom-stack">
69+
<i class="iconfont iconyuandianzhong"></i>
70+
<span>
71+
{{ item.bottom_stack }}
72+
</span>
73+
</div>
74+
</template>
4475

4576
<div class="infoLine flex-row-space-between">
4677
<div class="flex-row-space-between" style="width: 60%">
@@ -283,6 +314,10 @@ export default class VulnList extends VueBase {
283314
.card-content {
284315
padding: 0 12px;
285316
position: relative;
317+
.header-vul-url {
318+
color: #666;
319+
margin-bottom: 12px;
320+
}
286321
.top-stack {
287322
margin-top: 18px;
288323
position: relative;

0 commit comments

Comments
 (0)