github.com/DataDog/datadog-agent/pkg/security/secl@v0.55.0-devel.0.20240517055856-10c4965fea94/model/model_test.go (about) 1 // Unless explicitly stated otherwise all files in this repository are licensed 2 // under the Apache License Version 2.0. 3 // This product includes software developed at Datadog (https://www.datadoghq.com/). 4 // Copyright 2016-present Datadog, Inc. 5 6 //go:build linux 7 8 // Package model holds model related files 9 package model 10 11 import ( 12 "errors" 13 "net" 14 "reflect" 15 "strings" 16 "testing" 17 18 "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" 19 ) 20 21 func TestPathValidation(t *testing.T) { 22 mod := &Model{} 23 24 var maxDepthPath string 25 for i := 0; i <= MaxPathDepth; i++ { 26 maxDepthPath += "a/" 27 } 28 29 var maxSegmentPath string 30 for i := 0; i <= MaxSegmentLength; i++ { 31 maxSegmentPath += "a" 32 } 33 34 tests := []struct { 35 val string 36 errMessage string 37 fieldValueType eval.FieldValueType 38 }{ 39 { 40 val: "/var/log/*", 41 }, 42 { 43 val: "~/apache/httpd.conf", 44 errMessage: ErrPathMustBeAbsolute, 45 }, 46 { 47 val: "../../../etc/apache/httpd.conf", 48 errMessage: ErrPathMustBeAbsolute, 49 }, 50 { 51 val: "/etc/apache/./httpd.conf", 52 errMessage: ErrPathMustBeAbsolute, 53 }, 54 { 55 val: "*/", 56 errMessage: ErrPathMustBeAbsolute, 57 }, 58 { 59 val: "~/", 60 errMessage: ErrPathMustBeAbsolute, 61 }, 62 { 63 val: "/run/..data", 64 fieldValueType: eval.PatternValueType, 65 }, 66 { 67 val: "./data", 68 fieldValueType: eval.PatternValueType, 69 errMessage: ErrPathMustBeAbsolute, 70 }, 71 { 72 val: "../data", 73 fieldValueType: eval.PatternValueType, 74 errMessage: ErrPathMustBeAbsolute, 75 }, 76 { 77 val: "/data/../a", 78 fieldValueType: eval.PatternValueType, 79 errMessage: ErrPathMustBeAbsolute, 80 }, 81 { 82 val: "*/data", 83 fieldValueType: eval.PatternValueType, 84 }, 85 { 86 val: ".*", 87 fieldValueType: eval.RegexpValueType, 88 errMessage: ErrPathMustBeAbsolute, 89 }, 90 { 91 val: "/etc/*", 92 fieldValueType: eval.PatternValueType, 93 }, 94 { 95 val: "*", 96 fieldValueType: eval.PatternValueType, 97 errMessage: ErrPathMustBeAbsolute, 98 }, 99 { 100 val: maxDepthPath, 101 errMessage: ErrPathMustBeAbsolute, 102 }, 103 { 104 val: maxSegmentPath, 105 errMessage: ErrPathMustBeAbsolute, 106 }, 107 } 108 109 for _, test := range tests { 110 err := mod.ValidateField("open.file.path", eval.FieldValue{Value: test.val}) 111 if err != nil && test.errMessage == "" { 112 t.Errorf("shouldn't return an error: %s", err) 113 } 114 if err != nil && !strings.Contains(err.Error(), test.errMessage) { 115 t.Errorf("Error message is `%s`, wanted it to contain `%s`", err.Error(), test.errMessage) 116 } 117 } 118 } 119 120 func TestSetFieldValue(t *testing.T) { 121 var readOnlyError *eval.ErrFieldReadOnly 122 var fieldNotSupportedError *eval.ErrNotSupported 123 124 event := NewFakeEvent() 125 for _, field := range event.GetFields() { 126 kind, err := event.GetFieldType(field) 127 if err != nil { 128 t.Fatal(err) 129 } 130 131 switch kind { 132 case reflect.String: 133 err = event.SetFieldValue(field, "aaa") 134 if err != nil { 135 if errors.As(err, &readOnlyError) { 136 continue 137 } 138 t.Error(err) 139 } 140 value, err := event.GetFieldValue(field) 141 if err != nil { 142 if errors.As(err, &fieldNotSupportedError) { 143 continue 144 } 145 t.Errorf("unable to get the expected `%s` value: %v", field, err) 146 } 147 switch v := value.(type) { 148 case string: 149 if v != "aaa" { 150 t.Errorf("unable to get the expected `%s` value: %v", field, v) 151 } 152 case []string: 153 if v[0] != "aaa" { 154 t.Errorf("unable to get the expected `%s` value: %v", field, v) 155 } 156 default: 157 t.Errorf("unable to get the expected `%s` value: %v", field, v) 158 } 159 case reflect.Int: 160 err = event.SetFieldValue(field, 123) 161 if err != nil { 162 if errors.As(err, &readOnlyError) { 163 continue 164 } 165 t.Error(err) 166 } 167 value, err := event.GetFieldValue(field) 168 if err != nil { 169 if errors.As(err, &fieldNotSupportedError) { 170 continue 171 } 172 t.Errorf("unable to get the expected `%s` value: %v", field, err) 173 } 174 switch v := value.(type) { 175 case int: 176 if v != 123 { 177 t.Errorf("unable to get the expected `%s` value: %v", field, v) 178 } 179 case []int: 180 if v[0] != 123 { 181 t.Errorf("unable to get the expected `%s` value: %v", field, v) 182 } 183 default: 184 t.Errorf("unable to get the expected `%s` value: %v", field, v) 185 } 186 case reflect.Bool: 187 err = event.SetFieldValue(field, true) 188 if err != nil { 189 if errors.As(err, &readOnlyError) { 190 continue 191 } 192 t.Error(err) 193 } 194 value, err := event.GetFieldValue(field) 195 if err != nil { 196 if errors.As(err, &fieldNotSupportedError) { 197 continue 198 } 199 t.Errorf("unable to get the expected `%s` value: %v", field, err) 200 } 201 switch v := value.(type) { 202 case bool: 203 if !v { 204 t.Errorf("unable to get the expected `%s` value: %v", field, v) 205 } 206 case []bool: 207 if !v[0] { 208 t.Errorf("unable to get the expected `%s` value: %v", field, v) 209 } 210 default: 211 t.Errorf("unable to get the expected `%s` value: %v", field, v) 212 } 213 case reflect.Struct: 214 switch field { 215 case "network.destination.ip", "network.source.ip": 216 ip, ipnet, err := net.ParseCIDR("127.0.0.1/24") 217 if err != nil { 218 t.Error(err) 219 } 220 221 if err = event.SetFieldValue(field, *ipnet); err != nil { 222 t.Error(err) 223 } 224 if value, err := event.GetFieldValue(field); err != nil || value.(net.IPNet).IP.Equal(ip) { 225 t.Errorf("unable to get the expected value: %v", err) 226 } 227 } 228 default: 229 t.Errorf("type of field %s unknown: %v", field, kind) 230 } 231 } 232 }