mirror of
https://github.com/dataease/dataease.git
synced 2026-06-11 07:17:01 +08:00
fix: 分享链接安全漏洞
This commit is contained in:
committed by
fit2cloud-chenyw
parent
980537339d
commit
c4e85a981e
@@ -92,6 +92,8 @@ public class ChartDataManage {
|
||||
view.setChartExtRequest(chartExtRequest);
|
||||
}
|
||||
|
||||
chartViewManege.checkLinkChart(view);
|
||||
|
||||
//excel导出,如果是从仪表板获取图表数据,则仪表板的查询模式,查询结果的数量,覆盖图表对应的属性
|
||||
if (view.getIsExcelExport()) {
|
||||
view.setResultMode(ChartConstants.VIEW_RESULT_MODE.CUSTOM);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.dataease.chart.manage;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
@@ -10,6 +12,7 @@ import io.dataease.chart.dao.auto.entity.CoreChartView;
|
||||
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
|
||||
import io.dataease.chart.dao.ext.entity.ChartBasePO;
|
||||
import io.dataease.chart.dao.ext.mapper.ExtChartViewMapper;
|
||||
import io.dataease.constant.AuthConstant;
|
||||
import io.dataease.constant.CommonConstants;
|
||||
import io.dataease.dataset.dao.auto.entity.CoreDatasetTableField;
|
||||
import io.dataease.dataset.dao.auto.mapper.CoreDatasetTableFieldMapper;
|
||||
@@ -34,6 +37,7 @@ import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.IDUtils;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import io.dataease.utils.ServletUtils;
|
||||
import io.dataease.visualization.dao.auto.entity.DataVisualizationInfo;
|
||||
import io.dataease.visualization.dao.auto.entity.SnapshotCoreChartView;
|
||||
import io.dataease.visualization.dao.auto.mapper.DataVisualizationInfoMapper;
|
||||
@@ -159,6 +163,32 @@ public class ChartViewManege {
|
||||
return dto;
|
||||
}
|
||||
|
||||
public void checkLinkChart(ChartViewDTO view) {
|
||||
Long resourceId = view.getSceneId();
|
||||
Long viewId = view.getId();
|
||||
Long tableId = view.getTableId();
|
||||
|
||||
String linkToken = ServletUtils.getHead(AuthConstant.LINK_TOKEN_KEY);
|
||||
if (StringUtils.isBlank(linkToken)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DecodedJWT jwt = JWT.decode(linkToken);
|
||||
Long tokenResourceId = jwt.getClaim("resourceId").asLong();
|
||||
if (!tokenResourceId.equals(resourceId)) {
|
||||
DEException.throwException("超出分享链接权限");
|
||||
}
|
||||
|
||||
CoreChartView chartView = coreChartViewMapper.selectById(viewId);
|
||||
if (chartView == null) {
|
||||
DEException.throwException(Translator.get("i18n_chart_delete"));
|
||||
}
|
||||
|
||||
if (!chartView.getTableId().equals(tableId)) {
|
||||
DEException.throwException("超出分享链接权限");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sceneId 为仪表板或者数据大屏id
|
||||
*/
|
||||
|
||||
@@ -261,15 +261,18 @@ public class XpackShareManage {
|
||||
vo.setInIframeError(false);
|
||||
return vo;
|
||||
}
|
||||
String defaultPwd = shareSecretManage.getDefaultPwd();
|
||||
String secret = StringUtils.isBlank(xpackShare.getPwd()) ? defaultPwd : xpackShare.getPwd();
|
||||
String linkToken = LinkTokenUtil.generate(xpackShare.getCreator(), xpackShare.getResourceId(), xpackShare.getExp(), secret, xpackShare.getOid());
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
response.addHeader(AuthConstant.LINK_TOKEN_KEY, linkToken);
|
||||
|
||||
Integer type = xpackShare.getType();
|
||||
String typeText = (ObjectUtils.isNotEmpty(type) && type == 1) ? "dashboard" : "dataV";
|
||||
TicketValidVO validVO = shareTicketManage.validateTicket(request.getTicket(), xpackShare);
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp(xpackShare), pwdValid(xpackShare, request.getCiphertext()), typeText, inIframeError, false, true, validVO);
|
||||
|
||||
boolean linkExp = linkExp(xpackShare);
|
||||
boolean pwdValid = pwdValid(xpackShare, request.getCiphertext());
|
||||
|
||||
if (!linkExp && pwdValid && validVO.isTicketValid() && !validVO.isTicketExp()) {
|
||||
generateLinkToken(xpackShare);
|
||||
}
|
||||
return new XpackShareProxyVO(xpackShare.getResourceId(), xpackShare.getCreator(), linkExp, pwdValid, typeText, inIframeError, false, true, validVO);
|
||||
}
|
||||
|
||||
private boolean linkExp(XpackShare xpackShare) {
|
||||
@@ -307,7 +310,20 @@ public class XpackShareManage {
|
||||
QueryWrapper<XpackShare> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("uuid", uuid);
|
||||
XpackShare xpackShare = xpackShareMapper.selectOne(queryWrapper);
|
||||
return StringUtils.equals(xpackShare.getUuid(), uuid) && StringUtils.equals(xpackShare.getPwd(), pwd);
|
||||
boolean valid = StringUtils.equals(xpackShare.getUuid(), uuid) && StringUtils.equals(xpackShare.getPwd(), pwd);
|
||||
if (valid) {
|
||||
generateLinkToken(xpackShare);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
private void generateLinkToken(XpackShare xpackShare) {
|
||||
String defaultPwd = shareSecretManage.getDefaultPwd();
|
||||
String secret = StringUtils.isBlank(xpackShare.getPwd()) ? defaultPwd : xpackShare.getPwd();
|
||||
String linkToken = LinkTokenUtil.generate(xpackShare.getCreator(), xpackShare.getResourceId(), xpackShare.getExp(), secret, xpackShare.getOid());
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
assert response != null;
|
||||
response.addHeader(AuthConstant.LINK_TOKEN_KEY, linkToken);
|
||||
}
|
||||
|
||||
public Map<String, String> queryRelationByUserId(Long uid) {
|
||||
|
||||
@@ -74,6 +74,7 @@ public class WhitelistUtils {
|
||||
|| StringUtils.startsWithAny(requestURI, "/static-resource/")
|
||||
|| StringUtils.startsWithAny(requestURI, "/appearance/image/")
|
||||
|| StringUtils.startsWithAny(requestURI, "/share/proxyInfo")
|
||||
|| StringUtils.startsWithAny(requestURI, "/share/validate")
|
||||
|| StringUtils.startsWithAny(requestURI, "/xpackComponent/content")
|
||||
|| StringUtils.startsWithAny(requestURI, "/xpackComponent/pluginStaticInfo")
|
||||
|| StringUtils.startsWithAny(requestURI, "/geo/")
|
||||
|
||||
Reference in New Issue
Block a user