55 * @Date : 2024/5/19 19:03
66 */
77const vul1ReflectRaw = "// 原生漏洞场景,未加任何过滤,Controller接口返回Json类型结果\n" +
8- "public R vul1(String content ) {\n" +
9- " return R.ok(content );\n" +
8+ "public R vul1(String payload ) {\n" +
9+ " return R.ok(payload );\n" +
1010 "}\n" +
1111 "// R 是对返回结果的封装工具util\n" +
1212 "// 返回结果:\n" +
@@ -17,19 +17,19 @@ const vul1ReflectRaw = "// 原生漏洞场景,未加任何过滤,Controller接
1717 "// payload在json中是不会触发xss的 需要解析到页面中\n" +
1818 "\n" +
1919 "// 原生漏洞场景,未加任何过滤,Controller接口返回String类型结果\n" +
20- "public String vul2(String content ) {\n" +
21- " return content ;\n" +
20+ "public String vul2(String payload ) {\n" +
21+ " return payload ;\n" +
2222 "}"
2323const vul2ReflectContentType = "// Tomcat内置HttpServletResponse,Content-Type导致反射XSS\n" +
24- "public void vul3(String type,String content , HttpServletResponse response) {\n" +
24+ "public void vul3(String type,String payload , HttpServletResponse response) {\n" +
2525 " switch (type) {\n" +
2626 " case \"html\":\n" +
27- " response.getWriter().print(content );\n" +
27+ " response.getWriter().print(payload );\n" +
2828 " response.setContentType(\"text/html;charset=utf-8\");\n" +
2929 " response.getWriter().flush();\n" +
3030 " break;\n" +
3131 " case \"plain\":\n" +
32- " response.getWriter().print(content );\n" +
32+ " response.getWriter().print(payload );\n" +
3333 " response.setContentType(\"text/plain;charset=utf-8\");\n" +
3434 " response.getWriter().flush();\n" +
3535 " ...\n" +
@@ -51,51 +51,51 @@ const safe1CheckUserInput = "// 对用户输入的数据进行验证和过滤,
5151 "private static final String WHITELIST_REGEX = \"^[a-zA-Z0-9_\\\\s]+$\";\n" +
5252 "private static final Pattern pattern = Pattern.compile(WHITELIST_REGEX);\n" +
5353 "\n" +
54- "Matcher matcher = pattern.matcher(content );\n" +
54+ "Matcher matcher = pattern.matcher(payload );\n" +
5555 "if (matcher.matches()){\n" +
56- " return R.ok(content );\n" +
56+ " return R.ok(payload );\n" +
5757 "}else return R.error(\"输入内容包含非法字符,请检查输入\");"
5858const safe2CSP = "// 内容安全策略(Content Security Policy)是一种由浏览器实施的安全机制,旨在减少和防范跨站脚本攻击(XSS)等安全威胁。它通过允许网站管理员定义哪些内容来源是可信任的,从而防止恶意内容的加载和执行\n" +
5959 "// 前端Meta配置\n" +
6060 "<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; script-src 'self' https://apis.example.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' data: https://*.example.com;\">\n" +
6161 "\n" +
6262 "\n" +
6363 "// 后端Header配置\n" +
64- "public String safe2(String content ,HttpServletResponse response) {\n" +
64+ "public String safe2(String payload ,HttpServletResponse response) {\n" +
6565 " response.setHeader(\"Content-Security-Policy\",\"default-src self\");\n" +
66- " return content ;\n" +
66+ " return payload ;\n" +
6767 "}"
6868
6969const safe3EntityEscape = '// 特殊字符实体转义是一种将HTML中的特殊字符转换为预定义实体表示的过程\n' +
7070 '// 这种转义是为了确保在HTML页面中正确显示特定字符,同时避免它们被浏览器误解为HTML标签或JavaScript代码的一部分,从而导致页面结构混乱或安全漏洞\n' +
71- 'public R safe3(@ApiParam(String type, String content ) {\n' +
71+ 'public R safe3(@ApiParam(String type, String payload ) {\n' +
7272 ' String filterContented = "";\n' +
7373 ' switch (type){\n' +
7474 ' case "manual":\n' +
75- ' content = StringUtils.replace(content , "&", "&");\n' +
76- ' content = StringUtils.replace(content , "<", "<");\n' +
77- ' content = StringUtils.replace(content , ">", ">");\n' +
78- ' content = StringUtils.replace(content , "\\"", """);\n' +
79- ' content = StringUtils.replace(content , "\'", "'");\n' +
80- ' content = StringUtils.replace(content , "/", "/");\n' +
81- ' filterContented = content ;\n' +
75+ ' payload = StringUtils.replace(payload , "&", "&");\n' +
76+ ' payload = StringUtils.replace(payload , "<", "<");\n' +
77+ ' payload = StringUtils.replace(payload , ">", ">");\n' +
78+ ' payload = StringUtils.replace(payload , "\\"", """);\n' +
79+ ' payload = StringUtils.replace(payload , "\'", "'");\n' +
80+ ' payload = StringUtils.replace(payload , "/", "/");\n' +
81+ ' filterContented = payload ;\n' +
8282 ' break;\n' +
8383 ' case "spring":\n' +
84- ' filterContented = HtmlUtils.htmlEscape(content );\n' +
84+ ' filterContented = HtmlUtils.htmlEscape(payload );\n' +
8585 ' break;\n' +
8686 ' ...\n' +
8787 ' }\n' +
8888 '}'
8989
9090const safe4HttpOnly = "// HttpOnly是HTTP响应头属性,用于增强Web应用程序安全性。它防止客户端脚本访问(只能通过http/https协议访问)带有HttpOnly标记的 cookie,从而减少跨站点脚本攻击(XSS)的风险\n" +
9191 "// 单个接口配置\n" +
92- "public R safe4(String content , HttpServletRequest request,HttpServletResponse response) {\n" +
92+ "public R safe4(String payload , HttpServletRequest request,HttpServletResponse response) {\n" +
9393 " Cookie cookie = request.getCookies()[ueditor];\n" +
9494 " cookie.setHttpOnly(true); // 设置为 HttpOnly\n" +
9595 " cookie.setMaxAge(600); // 这里设置生效时间为十分钟\n" +
9696 " cookie.setPath(\"/\");\n" +
9797 " response.addCookie(cookie);\n" +
98- " return R.ok(content );\n" +
98+ " return R.ok(payload );\n" +
9999 "}\n" +
100100 "\n" +
101101 "// 全局配置\n" +
@@ -120,9 +120,9 @@ const safe4HttpOnly = "// HttpOnly是HTTP响应头属性,用于增强Web应用
120120
121121const vul1StoreRaw = "// 原生漏洞场景,未加任何过滤,将用户输入存储到数据库中\n" +
122122 "// Controller层\n" +
123- "public R vul(String content ,HttpServletRequest request) {\n" +
123+ "public R vul(String payload ,HttpServletRequest request) {\n" +
124124 " String ua = request.getHeader(\"User-Agent\");\n" +
125- " final int code = xssService.insertOne(content ,ua);\n" +
125+ " final int code = xssService.insertOne(payload ,ua);\n" +
126126 " ...\n" +
127127 "}\n" +
128128 "// Service层\n" +
@@ -203,11 +203,11 @@ const vul1OtherUpload = "public String uploadFile(MultipartFile file, String suf
203203 " }\n" +
204204 "}"
205205
206- const vul2OtherTemplate = "public String handleTemplateInjection(String content ,String type, Model model) {\n" +
206+ const vul2OtherTemplate = "public String handleTemplateInjection(String payload ,String type, Model model) {\n" +
207207 " if (\"html\".equals(type)) {\n" +
208- " model.addAttribute(\"html\", content );\n" +
208+ " model.addAttribute(\"html\", payload );\n" +
209209 " } else if (\"text\".equals(type)) {\n" +
210- " model.addAttribute(\"text\", content );\n" +
210+ " model.addAttribute(\"text\", payload );\n" +
211211 " }\n" +
212212 " return \"vul/xss/other\";\n" +
213213 "}\n" +
@@ -1177,7 +1177,121 @@ const safeHorizon = "public R safe(String username){\n" +
11771177 "}"
11781178
11791179// 支付漏洞
1180+ const vul1Pay = "public R vul1(@RequestParam String count, @RequestParam String price) {\n" +
1181+ " try {\n" +
1182+ " double totalPrice = Integer.parseInt(count) * Double.parseDouble(price);\n" +
1183+ " log.info(\"用户需支付金额:\" + totalPrice);\n" +
1184+ " \n" +
1185+ " // 直接使用客户端传入的价格,未与服务端商品实际价格进行校验\n" +
1186+ " BigDecimal currentMoney = userMoney.get();\n" +
1187+ " if (currentMoney.compareTo(BigDecimal.valueOf(totalPrice)) < 0) {\n" +
1188+ " return R.error(\"支付金额不足,支付失败!\");\n" +
1189+ " }\n" +
1190+ " userMoney.set(currentMoney.subtract(BigDecimal.valueOf(totalPrice)));\n" +
1191+ " return R.ok(\"支付成功!剩余余额:\" + userMoney.get());\n" +
1192+ " } catch (Exception e) {\n" +
1193+ " return R.error(e.toString());\n" +
1194+ " }\n" +
1195+ "}" ;
11801196
1197+ const vul2Pay = "public R vul2(@RequestParam String orderId, @RequestParam double amount) {\n" +
1198+ " // 未检查订单是否已支付\n" +
1199+ " // 这里应该使用paymentStatusMap检查订单是否已支付,但为了演示漏洞,故意不检查\n" +
1200+ " BigDecimal currentMoney = userMoney.get();\n" +
1201+ " if (currentMoney.compareTo(BigDecimal.valueOf(amount)) < 0) {\n" +
1202+ " return R.error(\"余额不足\");\n" +
1203+ " }\n" +
1204+ " userMoney.set(currentMoney.subtract(BigDecimal.valueOf(amount)));\n" +
1205+ " return R.ok(\"支付成功!剩余余额:\" + userMoney.get());\n" +
1206+ "}" ;
1207+
1208+ const vul3Pay = "public R vul3(@RequestParam String orderId, @RequestParam double amount) {\n" +
1209+ " // 模拟处理延迟\n" +
1210+ " try {\n" +
1211+ " Thread.sleep(1000);\n" +
1212+ " } catch (InterruptedException e) {\n" +
1213+ " Thread.currentThread().interrupt();\n" +
1214+ " }\n" +
1215+ "\n" +
1216+ " BigDecimal currentMoney = userMoney.get();\n" +
1217+ " if (currentMoney.compareTo(BigDecimal.valueOf(amount)) < 0) {\n" +
1218+ " return R.error(\"余额不足\");\n" +
1219+ " }\n" +
1220+ " userMoney.set(currentMoney.subtract(BigDecimal.valueOf(amount)));\n" +
1221+ " return R.ok(\"支付成功!剩余余额:\" + userMoney.get());\n" +
1222+ "}" ;
1223+
1224+ const vul4Pay = "@ApiOperation(\"支付流程绕过漏洞 - 创建订单\")\n" +
1225+ "@RequestMapping(\"/vul4/create\")\n" +
1226+ "public R createOrder(@RequestParam String orderId, @RequestParam double amount) {\n" +
1227+ " OrderStatus status = new OrderStatus(orderId, BigDecimal.valueOf(amount));\n" +
1228+ " orderStatusMap.put(orderId, status);\n" +
1229+ " Map<String, Object> data = new HashMap<>();\n" +
1230+ " data.put(\"orderId\", orderId);\n" +
1231+ " data.put(\"amount\", amount);\n" +
1232+ " return R.ok(\"订单创建成功\").put(\"data\", data);\n" +
1233+ "}\n" +
1234+ "\n" +
1235+ "@ApiOperation(\"支付流程绕过漏洞 - 查询订单状态\")\n" +
1236+ "@RequestMapping(\"/vul4/status\")\n" +
1237+ "public R getOrderStatus(@RequestParam String orderId) {\n" +
1238+ " OrderStatus status = orderStatusMap.get(orderId);\n" +
1239+ " if (status == null) {\n" +
1240+ " return R.error(\"订单不存在\");\n" +
1241+ " }\n" +
1242+ " Map<String, Object> data = new HashMap<>();\n" +
1243+ " data.put(\"orderId\", status.orderId);\n" +
1244+ " data.put(\"amount\", status.amount);\n" +
1245+ " data.put(\"isPaid\", status.isPaid);\n" +
1246+ " return R.ok().put(\"data\", data);\n" +
1247+ "}\n" +
1248+ "\n" +
1249+ "@ApiOperation(\"支付流程绕过漏洞 - 支付通知\")\n" +
1250+ "@RequestMapping(\"/vul4/notify\")\n" +
1251+ "public R paymentNotify(@RequestParam String orderId, @RequestParam boolean success) {\n" +
1252+ " // 未验证通知来源,直接更新订单状态\n" +
1253+ " OrderStatus status = orderStatusMap.get(orderId);\n" +
1254+ " if (status == null) {\n" +
1255+ " return R.error(\"订单不存在\");\n" +
1256+ " }\n" +
1257+ " status.isPaid = success;\n" +
1258+ " return R.ok(\"状态更新成功\");\n" +
1259+ "}" ;
1260+ const vul5Pay = "public R integerOverflow(@RequestParam String count, @RequestParam String price) {\n" +
1261+ " try {\n" +
1262+ " Integer countValue = Integer.valueOf(count);\n" +
1263+ " Integer priceValue = Integer.valueOf(price);\n" +
1264+ "\n" +
1265+ " // 整数溢出场景:当 count 或 price 数值过大时,可能会导致溢出\n" +
1266+ " int totalAmount = countValue * priceValue;\n" +
1267+ " log.info(\"用户需支付金额:\" + totalAmount);\n" +
1268+ "\n" +
1269+ " BigDecimal currentMoney = userMoney.get();\n" +
1270+ " if (currentMoney.compareTo(BigDecimal.valueOf(totalAmount)) < 0) {\n" +
1271+ " return R.error(\"支付金额不足,支付失败!\");\n" +
1272+ " }\n" +
1273+ " userMoney.set(currentMoney.subtract(BigDecimal.valueOf(totalAmount)));\n" +
1274+ " return R.ok(\"支付成功!剩余余额:\" + userMoney.get());\n" +
1275+ " } catch (Exception e) {\n" +
1276+ " return R.error(\"无效的输入,请输入有效的数量和价格!\");\n" +
1277+ " }\n" +
1278+ "}" ;
1279+ const vul6Pay = "public R floatingPointPrecision(@RequestParam String count, @RequestParam String price) {\n" +
1280+ " try {\n" +
1281+ " // 使用BigDecimal处理金额计算,避免浮点数精度问题\n" +
1282+ " BigDecimal amountValue = new BigDecimal(price).multiply(new BigDecimal(count));\n" +
1283+ " log.info(\"用户需支付金额:\" + amountValue);\n" +
1284+ "\n" +
1285+ " BigDecimal currentMoney = userMoney.get();\n" +
1286+ " if (currentMoney.compareTo(amountValue) < 0) {\n" +
1287+ " return R.error(\"支付金额不足,支付失败!\");\n" +
1288+ " }\n" +
1289+ " userMoney.set(currentMoney.subtract(amountValue));\n" +
1290+ " return R.ok(\"支付成功!剩余余额:\" + userMoney.get());\n" +
1291+ " } catch (Exception e) {\n" +
1292+ " return R.error(\"无效的输入,请输入有效的数量和价格!\");\n" +
1293+ " }\n" +
1294+ "}" ;
11811295
11821296// 其他漏洞
11831297const vul1SpringMvcRedirect = "// 基于Spring MVC的重定向方式\n" +
@@ -1766,6 +1880,11 @@ const vul2Reverse = "const publicKey = `-----BEGIN PUBLIC KEY-----\n" +
17661880 "{\"encryptedUsername\":\"iDF5BNv1zaM0V9qog0qzlUES3sCGYqmvrKiqPIvUgP5qE0pYn9XN3btW3PbRwLuySeruK2i8lem+L67w5+fFQBuRrpettLrHl8izIRp2W+nq9o9Kg/LSa3/+JynFoUHxrvQ2taNM1nustROpkBjJMbTOK52S6ZBa0quMw+wjfR1XExlzc99U1WJQfRAqj7Gsl9EPydRIh8vs4S/Nen5kf/dL3ZikfMbCUUBonRlYy6a3nWJ412P+hxRbSl80Z8aQKw9lH4+Iju80oFmQ6DuS6Ce70h88z/Va+xzXHDzM8w6h5iqQLzq3Kj/E+b/wsn6eM7v+LEC8LwLQ/t8z8tki9g==\",\n" +
17671881 "\"encryptedPassword\":\"nDI0/PBwsFHnRRw7Z4gHZ6G8Uaq7BUjUxnTDw7bkR9nrTkoHfcDLKUddj2JS7WWbOyuwsUFce3/tXJYQWNMFQqGRtf6jXxFAlvTvBkRdsZXOIU+Abb4EqYw670xd5UTeAQ0lI5KNXtw6e/VbnXyX+STJdN2SO7FLbvZ4sM6gLQSVWLo/+pZsYxKlEUNxew2svlzDZtqKnyF12bzakWfzaWuovLnYCCEXV1oAJCErjgfoOS2wJADdgU0wE6KlFDMNjsCvONmO6KZpmJQ1GOq3MpyqySq8eyJkYG3cDSRo5nDo2YOcevOHifzMnKbrU9gh4/RUj8sxrykdqgLmzX3rhw==\"}"
17681882
1883+ const vul1Credential = "vul1Credential"
1884+
1885+ const vul2Credential = "vul2Credential"
1886+
1887+
17691888// java专题 SPEL注入
17701889const spelVul = "public R vul(String ex) {\n" +
17711890 " // 创建SpEL解析器,ExpressionParser接口用于表示解析器,SpelExpressionParser为默认实现\n" +
@@ -2075,3 +2194,21 @@ const vulShiro = "public R getShiroKey(){\n" +
20752194 " <artifactId>shiro-spring</artifactId>\n" +
20762195 " <version>1.2.4</version>\n" +
20772196 "</dependency>"
2197+ const JdbcDeserial = "public R vul() {\n" +
2198+ " ...\n" +
2199+ " Connection conn = DriverManager.getConnection(url, username, password);\n" +
2200+ " String selectQuery = \"SELECT malicious_object FROM objects WHERE id = 1\";\n" +
2201+ " Statement stmt = conn.createStatement();\n" +
2202+ " ResultSet rs = stmt.executeQuery(selectQuery);\n" +
2203+ "\n" +
2204+ " if (rs.next()) {\n" +
2205+ " // 查询并获取恶意对象的字节数据\n" +
2206+ " byte[] maliciousObjectBytes = rs.getBytes(\"malicious_object\");\n" +
2207+ " // 反序列化恶意对象\n" +
2208+ " ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(maliciousObjectBytes);\n" +
2209+ " ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);\n" +
2210+ "\n" +
2211+ " // 触发反序列化漏洞\n" +
2212+ " MaliciousObject maliciousObject = (MaliciousObject) objectInputStream.readObject();\n" +
2213+ " }\n" +
2214+ " ..."
0 commit comments