Browse Source

REPORT-56220 数据连接越权漏洞修复

bugfix/11.0
Henry.Wang 3 years ago
parent
commit
5c372857cf
  1. 19
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  2. 16
      designer-base/src/main/java/com/fr/design/mainframe/authority/DSColumnAuthorityChecker.java
  3. 26
      designer-base/src/main/java/com/fr/design/mainframe/authority/ElementAuthorityChecker.java
  4. 27
      designer-base/src/main/java/com/fr/design/mainframe/authority/FormulaAuthorityChecker.java
  5. 147
      designer-base/src/main/java/com/fr/design/mainframe/authority/JTemplateAuthorityChecker.java
  6. 17
      designer-base/src/main/java/com/fr/design/mainframe/authority/NameDatabaseConnectionAuthorityChecker.java
  7. 16
      designer-base/src/main/java/com/fr/design/mainframe/authority/NameTableDataAuthorityChecker.java

19
designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java

@ -43,6 +43,7 @@ import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.authority.JTemplateAuthorityChecker;
import com.fr.design.mainframe.chart.info.ChartInfoCollector;
import com.fr.design.mainframe.check.CheckButton;
import com.fr.design.mainframe.template.info.TemplateProcessInfo;
@ -247,6 +248,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
}
}
private void stopListenThemeConfig() {
if (themeConfigChangeListener != null) {
TemplateThemeConfig<? extends TemplateTheme> config = getUsingTemplateThemeConfig();
@ -1404,7 +1406,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
* @return 按钮组
*/
public UIButton[] createExtraButtons() {
UIButton[] uiButtons = new UIButton[] {
UIButton[] uiButtons = new UIButton[]{
(UIButton) new CompileAction().createToolBarComponent()
};
Set<DesignerFrameUpButtonProvider> providers = ExtraDesignClassManager.getInstance().getArray(DesignerFrameUpButtonProvider.XML_TAG);
@ -1549,13 +1551,16 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
private boolean saveRealFile() throws Exception {
FILE editingFILE = this.getEditingFILE();
if (editingFILE == null || editingFILE instanceof MemFILE) {
return false;
if (new JTemplateAuthorityChecker(this).isAuthority()) {
FILE editingFILE = this.getEditingFILE();
if (editingFILE == null || editingFILE instanceof MemFILE) {
return false;
}
this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE));
this.editingFILE = editingFILE;
return true;
}
this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE));
this.editingFILE = editingFILE;
return true;
return false;
}
private CallbackSaveWorker saveAs(boolean showLoc) {

16
designer-base/src/main/java/com/fr/design/mainframe/authority/DSColumnAuthorityChecker.java

@ -0,0 +1,16 @@
package com.fr.design.mainframe.authority;
import com.fr.report.cell.cellattr.core.group.DSColumn;
import java.util.Set;
public class DSColumnAuthorityChecker extends ElementAuthorityChecker<DSColumn> {
@Override
String checkDatasetName(DSColumn dsColumn, Set<String> authDatasetNames) {
if (!authDatasetNames.contains(dsColumn.getDSName())) {
return dsColumn.getDSName();
}
return null;
}
}

26
designer-base/src/main/java/com/fr/design/mainframe/authority/ElementAuthorityChecker.java

@ -0,0 +1,26 @@
package com.fr.design.mainframe.authority;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import java.lang.reflect.Type;
import java.util.Set;
public abstract class ElementAuthorityChecker<T> {
//检查是否有越权的数据连接,如果有返回名称,没有返回null
String checkConnectionName(T t, Set<String> authConnectionNames) {
return null;
}
//检查是否有越权的服务器数据集,如果有返回名称,没有返回null
String checkDatasetName(T t, Set<String> authDatasetNames) {
return null;
}
//要检查对象的className
String getCheckClassName() {
ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) this.getClass().getGenericSuperclass();
Type type = parameterizedType.getActualTypeArguments()[0];
return type.getTypeName();
}
}

27
designer-base/src/main/java/com/fr/design/mainframe/authority/FormulaAuthorityChecker.java

@ -0,0 +1,27 @@
package com.fr.design.mainframe.authority;
import com.fr.base.Formula;
import com.fr.parser.FunctionCall;
import com.fr.parser.StringLiteral;
import com.fr.script.Calculator;
import java.lang.reflect.Field;
import java.util.Set;
public class FormulaAuthorityChecker extends ElementAuthorityChecker<Formula> {
@Override
public String checkConnectionName(Formula formula, Set<String> authConnectionNames) {
String content = formula.getContent();
try {
FunctionCall functionCall = (FunctionCall) Calculator.createCalculator().parse(content).getConditionalExpression();
StringLiteral stringLiteral = (StringLiteral) functionCall.getArguments()[0];
String connectionName = (String) Calculator.createCalculator().evalValue(stringLiteral);
if (!authConnectionNames.contains(connectionName)) {
return connectionName;
}
} catch (Exception ignore) {
}
return null;
}
}

147
designer-base/src/main/java/com/fr/design/mainframe/authority/JTemplateAuthorityChecker.java

@ -0,0 +1,147 @@
package com.fr.design.mainframe.authority;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.invoke.ClassHelper;
import com.fr.log.FineLoggerFactory;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.authority.user.UserAuthority;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
public class JTemplateAuthorityChecker {
JTemplate<?, ?> jTemplate;
Set<String> authConnectionNames;
Set<String> authDatasetNames;
Map<String, ElementAuthorityChecker> checkerMap = new HashMap<>();
Set<String> authFailConnectionNames = new HashSet<>();
Set<String> authFailDatasetNames = new HashSet<>();
public JTemplateAuthorityChecker(JTemplate<?, ?> jTemplate) {
long s = System.currentTimeMillis();
this.jTemplate = jTemplate;
this.initAuthNames();
this.initChecker();
FineLoggerFactory.getLogger().info("JTemplateAuthorityChecker init time consume:" + (System.currentTimeMillis() - s));
}
private void initAuthNames() {
UserAuthority templateAuthority = WorkContext.getCurrent().get(UserAuthority.class);
Map<String, Set<String>> allAuthNames = templateAuthority.getAuthServerDataSetAndConnectionNames();
//有权限的数据连接名称
authConnectionNames = allAuthNames.get(UserAuthority.AUTH_CONNECTION_NAMES);
//有权限的数据集名称(模板数据集和服务器数据集)
authDatasetNames = allAuthNames.get(UserAuthority.AUTH_SERVER_DATASET_NAMES);
Iterator<String> iterator = jTemplate.getTarget().getTableDataNameIterator();
while (iterator.hasNext()) {
String datasetName = iterator.next();
authDatasetNames.add(datasetName);
}
}
private void initChecker() {
registerChecker(new NameDatabaseConnectionAuthorityChecker());
registerChecker(new DSColumnAuthorityChecker());
registerChecker(new FormulaAuthorityChecker());
registerChecker(new NameTableDataAuthorityChecker());
}
private void registerChecker(ElementAuthorityChecker checker) {
checkerMap.put(checker.getCheckClassName(), checker);
}
public boolean isAuthority() {
long s = System.currentTimeMillis();
//遍历模板对象,根据checkerMap.keySet()把感兴趣的对象找出来
Map<String, Collection<Object>> targetObjects = ClassHelper.searchObject(jTemplate.getTarget(), checkerMap.keySet());
//找到对应的checker,对对象进行检查
for (String name : targetObjects.keySet()) {
ElementAuthorityChecker checker = checkerMap.get(name);
for (Object object : targetObjects.get(name)) {
String authFailName = checker.checkConnectionName(object, authConnectionNames);
if (authFailName != null) {
authFailConnectionNames.add(authFailName);
}
authFailName = checker.checkDatasetName(object, authDatasetNames);
if (authFailName != null) {
authFailDatasetNames.add(authFailName);
}
}
}
FineLoggerFactory.getLogger().info("JTemplateAuthorityChecker check time consume:" + (System.currentTimeMillis() - s));
if (authFailConnectionNames.size() == 0 && authFailDatasetNames.size() == 0) {
return true;
} else {
//如果存在越权的,弹出弹框,并返回false
authorityFailPrompt();
return false;
}
}
private void authorityFailPrompt() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(Toolkit.i18nText("Fine-Design-Basic_Save_Failure"));
stringBuffer.append("\n");
if (authFailDatasetNames.size() > 0) {
stringBuffer.append(Toolkit.i18nText("Fine-Design_Template_Authority_Check_Current_Operator_Miss"));
stringBuffer.append(authFailDatasetNames.size());
stringBuffer.append(Toolkit.i18nText("Fine-Design_Report_Ge"));
stringBuffer.append(Toolkit.i18nText("Fine-Design_Template_Authority_Check_Server_Dataset_Authority"));
stringBuffer.append("\n");
stringBuffer.append(getNoAuthNameSequence(authFailDatasetNames));
}
if (authFailConnectionNames.size() > 0) {
stringBuffer.append(Toolkit.i18nText("Fine-Design_Template_Authority_Check_Current_Operator_Miss"));
stringBuffer.append(authFailConnectionNames.size());
stringBuffer.append(Toolkit.i18nText("Fine-Design_Report_Ge"));
stringBuffer.append(Toolkit.i18nText("Fine-Design_Template_Authority_Check_Data_Connection_Authority"));
stringBuffer.append("\n");
stringBuffer.append(getNoAuthNameSequence(authFailConnectionNames));
}
FineJOptionPane.showMessageDialog(
DesignerContext.getDesignerFrame(),
stringBuffer.toString(),
Toolkit.i18nText("Fine-Design_Basic_Alert"),
WARNING_MESSAGE);
}
private String getNoAuthNameSequence(Set<String> names) {
StringBuffer stringBuffer = new StringBuffer();
int showMaxCount = 3;
int count = 0;
for (String name : names) {
if (count == showMaxCount) {
stringBuffer.append(Toolkit.i18nText("Fine-Design_Template_Authority_Check_Etc"));
break;
}
stringBuffer.append(name);
if (count != names.size() - 1 && count != showMaxCount - 1) {
stringBuffer.append(";");
}
count++;
}
stringBuffer.append("\n");
return stringBuffer.toString();
}
}

17
designer-base/src/main/java/com/fr/design/mainframe/authority/NameDatabaseConnectionAuthorityChecker.java

@ -0,0 +1,17 @@
package com.fr.design.mainframe.authority;
import com.fr.data.impl.NameDatabaseConnection;
import java.util.Set;
public class NameDatabaseConnectionAuthorityChecker extends ElementAuthorityChecker<NameDatabaseConnection> {
@Override
String checkConnectionName(NameDatabaseConnection nameDatabaseConnection, Set<String> authConnectionNames) {
String name = nameDatabaseConnection.getName();
if (!authConnectionNames.contains(name)) {
return name;
}
return null;
}
}

16
designer-base/src/main/java/com/fr/design/mainframe/authority/NameTableDataAuthorityChecker.java

@ -0,0 +1,16 @@
package com.fr.design.mainframe.authority;
import com.fr.data.impl.NameTableData;
import java.util.Set;
public class NameTableDataAuthorityChecker extends ElementAuthorityChecker<NameTableData> {
@Override
String checkDatasetName(NameTableData nameTableData, Set<String> authDatasetNames) {
if (!authDatasetNames.contains(nameTableData.getName())) {
return nameTableData.getName();
}
return null;
}
}
Loading…
Cancel
Save