Skip to content

Commit d6dbb00

Browse files
committed
fix:修复导出excel DDE漏洞 --bug=152262094 【CMDB】导出excel表格DDE漏洞
1 parent cc45f93 commit d6dbb00

File tree

6 files changed

+111
-38
lines changed

6 files changed

+111
-38
lines changed

pkg/excel/style.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ type Style struct {
2525
Fill *Fill
2626
Border []Border
2727
Font *Font
28+
NumFmt int
2829
}
2930

3031
func (s *Style) convert() (*excelize.Style, error) {
3132
style := new(excelize.Style)
33+
style.NumFmt = s.NumFmt
3234
if s.Fill != nil {
3335
fill, err := s.Fill.convert()
3436
if err != nil {

src/web_server/service/excel/operator/inst/exporter/inst_func.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,39 @@ var handleSpecialInstFieldFuncMap = make(map[string]handleInstFieldFunc)
3636
func init() {
3737
handleInstFieldFuncMap[common.FieldTypeInt] = getHandleIntFieldFunc()
3838
handleInstFieldFuncMap[common.FieldTypeFloat] = getHandleFloatFieldFunc()
39+
handleInstFieldFuncMap[common.FieldTypeSingleChar] = getHandleCharFieldFunc()
40+
handleInstFieldFuncMap[common.FieldTypeLongChar] = getHandleCharFieldFunc()
3941
handleInstFieldFuncMap[common.FieldTypeEnum] = getHandleEnumFieldFunc()
4042
handleInstFieldFuncMap[common.FieldTypeEnumMulti] = getHandleEnumMultiFieldFunc()
4143
handleInstFieldFuncMap[common.FieldTypeBool] = getHandleBoolFieldFunc()
4244
handleInstFieldFuncMap[common.FieldTypeInnerTable] = getHandleTableFieldFunc()
4345

4446
handleSpecialInstFieldFuncMap[common.BKCloudIDField] = getHandleInstCloudAreaFunc()
4547
}
48+
func getHandleCharFieldFunc() handleInstFieldFunc {
49+
return func(e *Exporter, property *core.ColProp, val interface{}) ([][]excel.Cell, error) {
50+
if val == nil {
51+
return [][]excel.Cell{getRowWithOneCell()}, nil
52+
}
53+
54+
strVal := util.GetStrByInterface(val)
55+
strVal = HandleDDE(strVal)
56+
handleFunc := getDefaultHandleFieldFunc()
57+
return handleFunc(e, property, strVal)
58+
}
59+
}
60+
61+
// HandleDDE Add a prefix of ' to the characters '=', '+', '-', '@' to disrupt the Excel DDE formula
62+
func HandleDDE(str string) string {
63+
prefix := strings.TrimSpace(str)
64+
if len(prefix) > 0 {
65+
switch prefix[0] {
66+
case '=', '+', '-', '@':
67+
prefix = `'` + prefix
68+
}
69+
}
70+
return prefix
71+
}
4672

4773
func getHandleInstFieldFunc(property *core.ColProp) handleInstFieldFunc {
4874
handleFunc, isSpecial := handleSpecialInstFieldFuncMap[property.ID]
@@ -231,13 +257,13 @@ func getHandleTableFieldFunc() handleInstFieldFunc {
231257

232258
func getDefaultHandleFieldFunc() handleInstFieldFunc {
233259
return func(e *Exporter, property *core.ColProp, val interface{}) ([][]excel.Cell, error) {
234-
var styleID int
260+
style := normalField
235261
if property.NotEditable {
236-
var err error
237-
styleID, err = e.styleCreator.getStyle(noEditField)
238-
if err != nil {
239-
return nil, err
240-
}
262+
style = noEditField
263+
}
264+
styleID, err := e.styleCreator.getStyle(style, property.PropertyType)
265+
if err != nil {
266+
return nil, err
241267
}
242268

243269
result := make([][]excel.Cell, singleCellLen)

src/web_server/service/excel/operator/inst/exporter/property_func.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func getHandleBoolTypeFunc() handleColPropFunc {
136136
return nil, err
137137
}
138138
if err = t.GetExcel().AddValidation(t.GetObjID(),
139-
&excel.ValidationParam{Type: excel.Bool, Sqref: sqref, Option: property.Name}); err != nil {
139+
&excel.ValidationParam{Type: excel.Bool, Sqref: sqref, Option: HandleDDE(property.Name)}); err != nil {
140140
return nil, err
141141
}
142142

@@ -147,11 +147,11 @@ func getHandleBoolTypeFunc() handleColPropFunc {
147147

148148
func getHandleTableTypeFunc() handleColPropFunc {
149149
return func(t *TmplOp, property *core.ColProp) ([][]excel.Cell, error) {
150-
nameStyle, err := t.styleCreator.getStyle(firstRow)
150+
nameStyle, err := t.styleCreator.getStyle(firstRow, property.PropertyType)
151151
if err != nil {
152152
return nil, err
153153
}
154-
headerStyle, err := t.styleCreator.getStyle(generalHeader)
154+
headerStyle, err := t.styleCreator.getStyle(generalHeader, property.PropertyType)
155155
if err != nil {
156156
return nil, err
157157
}
@@ -160,7 +160,8 @@ func getHandleTableTypeFunc() handleColPropFunc {
160160
propertyType := core.GetTypeAliasName(ccLang, property.PropertyType)
161161

162162
result := make([][]excel.Cell, core.InstHeaderLen)
163-
result[core.NameRowIdx] = append(result[core.NameRowIdx], excel.Cell{Value: property.Name, StyleID: nameStyle})
163+
result[core.NameRowIdx] = append(result[core.NameRowIdx], excel.Cell{Value: HandleDDE(property.Name),
164+
StyleID: nameStyle})
164165
result[core.TypeRowIdx] = append(result[core.TypeRowIdx],
165166
excel.Cell{Value: propertyType, StyleID: headerStyle})
166167
result[core.IDRowIdx] = append(result[core.IDRowIdx], excel.Cell{Value: property.ID, StyleID: headerStyle})
@@ -204,7 +205,7 @@ func getHandleTableTypeFunc() handleColPropFunc {
204205
result[core.TableIDRowIdx] = append(result[core.TableIDRowIdx], properyResult[core.IDRowIdx]...)
205206
}
206207

207-
tableHeaderStyle, err := t.styleCreator.getStyle(tableHeader)
208+
tableHeaderStyle, err := t.styleCreator.getStyle(tableHeader, property.PropertyType)
208209
if err != nil {
209210
return nil, err
210211
}
@@ -228,11 +229,11 @@ func getDefaultHandleTypeFunc() handleColPropFunc {
228229
headerStyleType = noEditHeader
229230
}
230231

231-
nameStyle, err := t.styleCreator.getStyle(nameStyleType)
232+
nameStyle, err := t.styleCreator.getStyle(nameStyleType, property.PropertyType)
232233
if err != nil {
233234
return nil, err
234235
}
235-
headerStyle, err := t.styleCreator.getStyle(headerStyleType)
236+
headerStyle, err := t.styleCreator.getStyle(headerStyleType, property.PropertyType)
236237
if err != nil {
237238
return nil, err
238239
}
@@ -241,7 +242,8 @@ func getDefaultHandleTypeFunc() handleColPropFunc {
241242
propertyType := core.GetTypeAliasName(ccLang, property.PropertyType)
242243

243244
result := make([][]excel.Cell, core.InstHeaderLen)
244-
result[core.NameRowIdx] = append(result[core.NameRowIdx], excel.Cell{Value: property.Name, StyleID: nameStyle})
245+
result[core.NameRowIdx] = append(result[core.NameRowIdx],
246+
excel.Cell{Value: HandleDDE(property.Name), StyleID: nameStyle})
245247
result[core.TypeRowIdx] = append(result[core.TypeRowIdx], excel.Cell{Value: propertyType, StyleID: headerStyle})
246248
result[core.IDRowIdx] = append(result[core.IDRowIdx], excel.Cell{Value: property.ID, StyleID: headerStyle})
247249

src/web_server/service/excel/operator/inst/exporter/style.go

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package exporter
1818

1919
import (
2020
"configcenter/pkg/excel"
21+
"configcenter/src/common"
2122
)
2223

2324
type styleType string
@@ -37,6 +38,8 @@ const (
3738
noEditField styleType = "noEditField"
3839
// example 例子数据的单元格类型
3940
example styleType = "example"
41+
// normalField 普通数据单元格类型
42+
normalField styleType = "normal"
4043

4144
requiredFieldColor = "#FF0000"
4245
noEditHeaderColor = "fabf8f"
@@ -63,14 +66,48 @@ func init() {
6366
createStyleFuncMap[generalHeader] = getGeneralHeaderStyleFunc()
6467
createStyleFuncMap[tableHeader] = getTableHeaderStyleFunc()
6568
createStyleFuncMap[example] = getExampleStyleFunc()
69+
createStyleFuncMap[normalField] = getNormalStyleFunc()
6670
}
6771

68-
type createStyleFunc func(s *styleCreator) (int, error)
72+
type createStyleFunc func(s *styleCreator, numFmt int) (int, error)
73+
74+
// handlePropertyTypeNumFmt propType->excel code
75+
func handlePropertyTypeNumFmt(propType string) int {
76+
switch propType {
77+
case common.FieldTypeInt:
78+
return 1
79+
case common.FieldTypeFloat:
80+
return 2
81+
case common.FieldTypeLongChar, common.FieldTypeSingleChar:
82+
return 49
83+
case common.FieldTypeInnerTable,
84+
common.FieldTypeEnum,
85+
common.FieldTypeEnumMulti,
86+
common.FieldTypeBool:
87+
return 0
88+
default:
89+
return 0
90+
}
91+
}
6992

7093
func getNoEditHeaderStyleFunc() createStyleFunc {
71-
return func(s *styleCreator) (int, error) {
94+
return func(s *styleCreator, numFmt int) (int, error) {
7295
style := &excel.Style{Fill: &excel.Fill{Type: "pattern", Color: []string{noEditHeaderColor}, Pattern: 1},
73-
Border: generalBorder}
96+
Border: generalBorder, NumFmt: numFmt}
97+
98+
result, err := s.excel.NewStyle(style)
99+
if err != nil {
100+
return 0, err
101+
}
102+
103+
return result, nil
104+
}
105+
}
106+
107+
func getNormalStyleFunc() createStyleFunc {
108+
return func(s *styleCreator, numFmt int) (int, error) {
109+
style := &excel.Style{Fill: &excel.Fill{Type: "pattern", Color: []string{}, Pattern: 1},
110+
Border: generalBorder, NumFmt: numFmt}
74111

75112
result, err := s.excel.NewStyle(style)
76113
if err != nil {
@@ -82,9 +119,9 @@ func getNoEditHeaderStyleFunc() createStyleFunc {
82119
}
83120

84121
func getNoEditFieldStyleFunc() createStyleFunc {
85-
return func(s *styleCreator) (int, error) {
122+
return func(s *styleCreator, numFmt int) (int, error) {
86123
style := &excel.Style{Fill: &excel.Fill{Type: excel.Pattern, Color: []string{noEditFieldColor}, Pattern: 1},
87-
Border: generalBorder}
124+
Border: generalBorder, NumFmt: numFmt}
88125

89126
result, err := s.excel.NewStyle(style)
90127
if err != nil {
@@ -96,9 +133,9 @@ func getNoEditFieldStyleFunc() createStyleFunc {
96133
}
97134

98135
func getFirstRowStyleFunc() createStyleFunc {
99-
return func(s *styleCreator) (int, error) {
136+
return func(s *styleCreator, numFmt int) (int, error) {
100137
style := &excel.Style{Fill: &excel.Fill{Type: excel.Pattern, Color: []string{firstRowColor}, Pattern: 1},
101-
Border: generalBorder}
138+
Border: generalBorder, NumFmt: numFmt}
102139

103140
result, err := s.excel.NewStyle(style)
104141
if err != nil {
@@ -110,9 +147,9 @@ func getFirstRowStyleFunc() createStyleFunc {
110147
}
111148

112149
func getGeneralHeaderStyleFunc() createStyleFunc {
113-
return func(s *styleCreator) (int, error) {
150+
return func(s *styleCreator, numFmt int) (int, error) {
114151
style := &excel.Style{Fill: &excel.Fill{Type: excel.Pattern, Color: []string{generalHeaderColor}, Pattern: 1},
115-
Border: generalBorder}
152+
Border: generalBorder, NumFmt: numFmt}
116153

117154
result, err := s.excel.NewStyle(style)
118155
if err != nil {
@@ -124,9 +161,9 @@ func getGeneralHeaderStyleFunc() createStyleFunc {
124161
}
125162

126163
func getTableHeaderStyleFunc() createStyleFunc {
127-
return func(s *styleCreator) (int, error) {
164+
return func(s *styleCreator, numFmt int) (int, error) {
128165
style := &excel.Style{Fill: &excel.Fill{Type: excel.Pattern, Color: []string{tableHeaderColor}, Pattern: 1},
129-
Border: generalBorder}
166+
Border: generalBorder, NumFmt: numFmt}
130167

131168
result, err := s.excel.NewStyle(style)
132169
if err != nil {
@@ -138,9 +175,9 @@ func getTableHeaderStyleFunc() createStyleFunc {
138175
}
139176

140177
func getExampleStyleFunc() createStyleFunc {
141-
return func(s *styleCreator) (int, error) {
178+
return func(s *styleCreator, numFmt int) (int, error) {
142179
style := &excel.Style{Fill: &excel.Fill{Type: excel.Pattern, Color: []string{exampleColor}, Pattern: 1},
143-
Border: generalBorder}
180+
Border: generalBorder, NumFmt: numFmt}
144181

145182
result, err := s.excel.NewStyle(style)
146183
if err != nil {
@@ -152,9 +189,9 @@ func getExampleStyleFunc() createStyleFunc {
152189
}
153190

154191
func getRequiredFieldStyleFunc() createStyleFunc {
155-
return func(s *styleCreator) (int, error) {
192+
return func(s *styleCreator, numFmt int) (int, error) {
156193
style := &excel.Style{Fill: &excel.Fill{Type: excel.Pattern, Color: []string{firstRowColor}, Pattern: 1},
157-
Border: generalBorder, Font: &excel.Font{Color: requiredFieldColor}}
194+
Border: generalBorder, Font: &excel.Font{Color: requiredFieldColor}, NumFmt: numFmt}
158195

159196
result, err := s.excel.NewStyle(style)
160197
if err != nil {
@@ -192,12 +229,13 @@ func setExcel(excel *excel.Excel) styleOperatorFunc {
192229
}
193230
}
194231

195-
func (s *styleCreator) getStyle(style styleType) (int, error) {
232+
func (s *styleCreator) getStyle(style styleType, propType string) (int, error) {
196233
result, ok := s.styleMap[style]
197234
if !ok {
198235
styleFunc := createStyleFuncMap[style]
199236
var err error
200-
result, err = styleFunc(s)
237+
numFmt := handlePropertyTypeNumFmt(propType)
238+
result, err = styleFunc(s, numFmt)
201239
if err != nil {
202240
return 0, err
203241
}

src/web_server/service/excel/operator/inst/exporter/tmpl_operator.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func (t *TmplOp) writeInstHeader(colProps []core.ColProp) error {
176176
func (t *TmplOp) handleProperty(colProps []core.ColProp) ([][]excel.Cell, error) {
177177
ccLang := t.GetLang().CreateDefaultCCLanguageIf(httpheader.GetLanguage(t.GetKit().Header))
178178

179-
firstColStyle, err := t.styleCreator.getStyle(noEditHeader)
179+
firstColStyle, err := t.styleCreator.getStyle(noEditHeader, "")
180180
if err != nil {
181181
blog.Errorf("get style failed, style: %s, err: %v, rid: %s", noEditHeader, err, t.GetKit().Rid)
182182
return nil, err
@@ -197,7 +197,7 @@ func (t *TmplOp) handleProperty(colProps []core.ColProp) ([][]excel.Cell, error)
197197
header[idx][0] = excel.Cell{Value: fieldName, StyleID: firstColStyle}
198198
}
199199

200-
requiredStyle, err := t.styleCreator.getStyle(requiredField)
200+
requiredStyle, err := t.styleCreator.getStyle(requiredField, "")
201201
if err != nil {
202202
blog.Errorf("get style failed, style: %s, err: %v, rid: %s", requiredField, err, t.GetKit().Rid)
203203
return nil, err
@@ -326,7 +326,7 @@ func (t *TmplOp) writeAsstHeader() error {
326326
lang := t.GetLang().CreateDefaultCCLanguageIf(httpheader.GetLanguage(t.GetKit().Header))
327327

328328
// 设置关联关系sheet表头第一列数据
329-
firstColStyle, err := t.styleCreator.getStyle(noEditHeader)
329+
firstColStyle, err := t.styleCreator.getStyle(noEditHeader, "")
330330
if err != nil {
331331
blog.Errorf("get style failed, style: %s, err: %v, rid: %s", noEditHeader, err, t.GetKit().Rid)
332332
return err
@@ -336,7 +336,7 @@ func (t *TmplOp) writeAsstHeader() error {
336336
}
337337

338338
// 设置关联关系sheet表头第一行数据(除第一列的单元格)
339-
firstRowStyle, err := t.styleCreator.getStyle(firstRow)
339+
firstRowStyle, err := t.styleCreator.getStyle(firstRow, "")
340340
if err != nil {
341341
return err
342342
}
@@ -348,7 +348,7 @@ func (t *TmplOp) writeAsstHeader() error {
348348
}
349349

350350
// 设置关联关系sheet表头第二行数据(除第一列的单元格)
351-
exampleStyle, err := t.styleCreator.getStyle(example)
351+
exampleStyle, err := t.styleCreator.getStyle(example, "")
352352
if err != nil {
353353
return err
354354
}

src/web_server/service/excel/operator/model/operator.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package model
1818

1919
import (
20+
"configcenter/src/web_server/service/excel/operator/inst/exporter"
2021
"encoding/json"
2122
"fmt"
2223
"strconv"
@@ -216,8 +217,12 @@ func (op *Operator) setExcelData() error {
216217
data[rowIdx][idx].Value = string(value)
217218
continue
218219
}
219-
220-
data[rowIdx][idx].Value = cell
220+
switch value := cell.(type) {
221+
case string:
222+
data[rowIdx][idx].Value = exporter.HandleDDE(value)
223+
default:
224+
data[rowIdx][idx].Value = cell
225+
}
221226
}
222227
}
223228

0 commit comments

Comments
 (0)