Skip to content

Commit 38dbe2a

Browse files
committed
feat: VulnShop前端视觉设计改进和日志功能修复
- 改进整体UI设计,优化颜色搭配和视觉效果 - 修复'查看日志'功能点击无反应的问题 - 添加现代化的日志查看器界面 - 支持三种日志类型切换和行数选择
1 parent 8b980f5 commit 38dbe2a

11 files changed

Lines changed: 3004 additions & 13 deletions

File tree

src/vulnTestServer/handlers/cart_handlers.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,185 @@ def handle_cart_update(self, data):
125125
self.send_json_response({'success': False, 'message': f'Failed to update cart: {str(e)}'}, 500)
126126
finally:
127127
conn.close()
128+
129+
def handle_cart_delete(self, data):
130+
"""
131+
删除购物车项 - XML格式 - 安全接口,使用参数化查询
132+
133+
请求体示例 (application/xml):
134+
<?xml version="1.0" encoding="UTF-8"?>
135+
<request>
136+
<cart_id>1</cart_id>
137+
<reason>Removed by user</reason>
138+
<session_id>abc123</session_id>
139+
<csrf_token>xyz789</csrf_token>
140+
</request>
141+
142+
注意:此接口使用参数化查询,不存在SQL注入漏洞
143+
(数据修改操作需保护,避免测试数据污染)
144+
"""
145+
cart_id = data.get('cart_id', '')
146+
reason = data.get('reason', '')
147+
session_id = data.get('session_id', '')
148+
csrf_token = data.get('csrf_token', '')
149+
150+
if not cart_id:
151+
self.send_xml_response({'success': 'false', 'message': 'cart_id is required'}, 400)
152+
return
153+
154+
# 验证cart_id是否为有效数字
155+
try:
156+
cart_id_int = int(cart_id)
157+
except ValueError:
158+
self.send_xml_response({'success': 'false', 'message': 'Invalid cart ID'}, 400)
159+
return
160+
161+
if DEBUG:
162+
logger.debug("[CartDelete] session_id=%s, csrf_token=%s", session_id, csrf_token)
163+
164+
conn = get_db_connection()
165+
cursor = conn.cursor()
166+
167+
try:
168+
# 使用参数化查询删除购物车项
169+
cursor.execute('DELETE FROM cart WHERE id = ?', (cart_id_int,))
170+
conn.commit()
171+
172+
if cursor.rowcount > 0:
173+
self.send_xml_response({
174+
'success': 'true',
175+
'message': 'Cart item deleted successfully',
176+
'data': {
177+
'cart_id': cart_id,
178+
'reason': reason,
179+
'session_id': session_id
180+
}
181+
})
182+
else:
183+
self.send_xml_response({
184+
'success': 'false',
185+
'message': 'Cart item not found'
186+
}, 404)
187+
except sqlite3.Error as e:
188+
self.send_xml_response({'success': 'false', 'message': f'Failed to delete cart item: {str(e)}'}, 500)
189+
finally:
190+
conn.close()
191+
192+
def handle_cart_clear(self, data):
193+
"""
194+
清空购物车 - JSON格式 - 安全接口,使用参数化查询
195+
196+
请求体示例 (application/json):
197+
{
198+
"user_id": 1,
199+
"session_id": "abc123",
200+
"csrf_token": "xyz789"
201+
}
202+
203+
注意:此接口使用参数化查询,不存在SQL注入漏洞
204+
(数据修改操作需保护,避免测试数据污染)
205+
"""
206+
user_id = data.get('user_id', '')
207+
session_id = data.get('session_id', '')
208+
csrf_token = data.get('csrf_token', '')
209+
210+
if not user_id:
211+
self.send_json_response({'success': False, 'message': 'user_id is required'}, 400)
212+
return
213+
214+
# 验证user_id是否为有效数字
215+
try:
216+
user_id_int = int(user_id)
217+
except ValueError:
218+
self.send_json_response({'success': False, 'message': 'Invalid user ID'}, 400)
219+
return
220+
221+
if DEBUG:
222+
logger.debug("[CartClear] session_id=%s, csrf_token=%s", session_id, csrf_token)
223+
224+
conn = get_db_connection()
225+
cursor = conn.cursor()
226+
227+
try:
228+
# 使用参数化查询清空用户购物车
229+
cursor.execute('DELETE FROM cart WHERE user_id = ?', (user_id_int,))
230+
deleted_count = cursor.rowcount
231+
conn.commit()
232+
233+
self.send_json_response({
234+
'success': True,
235+
'message': 'Cart cleared successfully',
236+
'data': {
237+
'user_id': user_id,
238+
'deleted_count': deleted_count,
239+
'session_id': session_id
240+
}
241+
})
242+
except sqlite3.Error as e:
243+
self.send_json_response({'success': False, 'message': f'Failed to clear cart: {str(e)}'}, 500)
244+
finally:
245+
conn.close()
246+
247+
def handle_cart_query(self, data):
248+
"""
249+
购物车查询 - JSON格式 - 保留SQL注入漏洞(只读查询)
250+
251+
漏洞点:用户ID直接拼接到SQL语句
252+
测试payload: user_id=1' OR '1'='1
253+
254+
注意:此接口保留SQL注入以供测试,但不支持堆叠查询
255+
"""
256+
waf = get_waf()
257+
user_id = waf.filter_input(data.get('user_id', ''))
258+
session_id = waf.filter_input(data.get('session_id', ''))
259+
260+
if not user_id:
261+
self.send_json_response({'success': False, 'message': 'user_id is required'}, 400)
262+
return
263+
264+
conn = get_db_connection()
265+
cursor = conn.cursor()
266+
267+
# 构建存在漏洞的SQL(字符串拼接)
268+
sql = f"""SELECT c.id, c.user_id, c.product_id, c.quantity, c.session_id,
269+
p.name as product_name, p.price as product_price
270+
FROM cart c
271+
JOIN products p ON c.product_id = p.id
272+
WHERE c.user_id = {user_id}"""
273+
274+
if session_id:
275+
sql += f" AND c.session_id = '{session_id}'"
276+
277+
if DEBUG:
278+
sql_logger.debug("[SQL] %s", sql)
279+
280+
try:
281+
cursor.execute(sql)
282+
items = cursor.fetchall()
283+
284+
result = []
285+
total = 0
286+
for item in items:
287+
subtotal = item[3] * item[6] # quantity * price
288+
total += subtotal
289+
result.append({
290+
'cart_id': item[0],
291+
'user_id': item[1],
292+
'product_id': item[2],
293+
'quantity': item[3],
294+
'session_id': item[4],
295+
'product_name': item[5],
296+
'product_price': item[6],
297+
'subtotal': subtotal
298+
})
299+
300+
self.send_json_response({
301+
'success': True,
302+
'data': result,
303+
'count': len(result),
304+
'total': total
305+
})
306+
except sqlite3.Error as e:
307+
self.send_error_response(f'Query error: {str(e)}', 500, sql_error=e)
308+
finally:
309+
conn.close()

0 commit comments

Comments
 (0)