Headline
CVE-2021-45788: [BUG]Time-based SQL Injetion in v1.15.4 · Issue #8651 · metersphere/metersphere
Time-based SQL Injection vulnerabilities were found in Metersphere v1.15.4 via the “orders” parameter.
Version
v1.15.4
Description
Authenticated users can control the parameters in the “order by” statement, which causing SQL injection.
API: /test/case/list/{goPage}/{pageSize}
Vulnerable source code:
ExtTestPlanTestCaseMapper.xml
<select id="list" resultType="io.metersphere.track.dto.TestPlanCaseDTO">
select test_plan_test_case.id as id, test_case.id as caseId, test_case.name, test_case.priority,
test_case.type,test_case.test_id as testId,test_case.node_id, test_case.tags, test_case.maintainer,
test_case.custom_fields,
test_case.node_path, test_case.method, if(project.custom_num = 0, cast(test_case.num as char),
test_case.custom_num) as customNum, test_plan_test_case.executor, test_plan_test_case.status,
test_plan_test_case.actual_result,
test_plan_test_case.update_time, test_plan_test_case.create_time,test_case_node.name as model, project.name as
projectName,test_plan_test_case.issues as issues,test_plan_test_case.issues_count as issuesCount,
test_plan_test_case.plan_id as planId
from test_plan_test_case
inner join test_case on test_plan_test_case.case_id = test_case.id
left join test_case_node on test_case_node.id = test_case.node_id
inner join project on project.id = test_case.project_id
<include refid="queryWhereCondition"/>
<if test="request.orders != null and request.orders.size() > 0">
order by
<foreach collection="request.orders" separator="," item="order">
<choose>
<when test="order.name == 'custom_num'">
customNum ${order.type}
</when>
<when test="order.name == 'name'">
test_case.name ${order.type}
</when>
<otherwise>
test_plan_test_case.${order.name} ${order.type}
</otherwise>
</choose>
</foreach>
</if>
</select>
TestPlanTestCaseService.java
public List<TestPlanCaseDTO> list(QueryTestPlanCaseRequest request) {
request.setOrders(ServiceUtils.getDefaultSortOrder(request.getOrders()));
List<TestPlanCaseDTO> list = extTestPlanTestCaseMapper.list(request);
QueryMemberRequest queryMemberRequest = new QueryMemberRequest();
queryMemberRequest.setProjectId(request.getProjectId());
Map<String, String> userMap = userService.getProjectMemberList(queryMemberRequest)
.stream().collect(Collectors.toMap(User::getId, User::getName));
list.forEach(item -> {
item.setExecutorName(userMap.get(item.getExecutor()));
item.setMaintainerName(userMap.get(item.getMaintainer()));
});
return list;
}
To Reproduce
I have tested this vulnerability on the demo website https://demo.metersphere.com/.
Set the value of the “orders” parameter
"orders":[{"name":"name","type":",if(1=1,sleep(2),0)"}]
As we have seen, this lead to time-based sqli
Some other APIs also have sqli,such as
/test/plan/case/list/all
/test/plan/case/list/ids
/issues/list/{goPage}/{pageSize}
/test/case/list/{goPage}/{pageSize}