@@ -363,6 +363,16 @@ func TestNewMtlsSanDNS_CreateFilter(t *testing.T) {
363363 args : []any {"10.0.0.0/8" , "example.com" , "spiffe://trust-domain/svc" },
364364 wantErr : true ,
365365 },
366+ {
367+ name : "valid glob *.host.example" ,
368+ args : []any {"*.host.example" },
369+ wantErr : false ,
370+ },
371+ {
372+ name : "mix exact and glob" ,
373+ args : []any {"exact.example.com" , "*.host.example" },
374+ wantErr : false ,
375+ },
366376 } {
367377 t .Run (tt .name , func (t * testing.T ) {
368378 f , err := spec .CreateFilter (tt .args )
@@ -466,6 +476,16 @@ func TestNewMtlsSanURI_CreateFilter(t *testing.T) {
466476 args : []any {"10.0.0.0/8" , "example.com" , "spiffe://trust-domain/svc" },
467477 wantErr : true ,
468478 },
479+ {
480+ name : "valid URI glob spiffe://services.example/applications/*" ,
481+ args : []any {"spiffe://services.example/applications/*" },
482+ wantErr : false ,
483+ },
484+ {
485+ name : "mix exact URI and glob" ,
486+ args : []any {"spiffe://other.example/svc" , "spiffe://services.example/applications/*" },
487+ wantErr : false ,
488+ },
469489 } {
470490 t .Run (tt .name , func (t * testing.T ) {
471491 f , err := spec .CreateFilter (tt .args )
@@ -1102,6 +1122,136 @@ func TestMtlsSAN_Request(t *testing.T) {
11021122 expectedStatus : http .StatusForbidden ,
11031123 expectServed : true ,
11041124 },
1125+ // DNS glob matching
1126+ {
1127+ name : "DNS glob *.host.example matches foo.host.example" ,
1128+ tlsState : buildConnStateWithSANs (nil , []string {"foo.host.example" }, nil , nil ),
1129+ spec : NewMtlsSanDNS (),
1130+ filterArgs : []any {"*.host.example" },
1131+ expectedStatus : 0 ,
1132+ expectServed : false ,
1133+ },
1134+ {
1135+ name : "DNS glob *.host.example is case-insensitive" ,
1136+ tlsState : buildConnStateWithSANs (nil , []string {"FOO.Host.Example" }, nil , nil ),
1137+ spec : NewMtlsSanDNS (),
1138+ filterArgs : []any {"*.host.example" },
1139+ expectedStatus : 0 ,
1140+ expectServed : false ,
1141+ },
1142+ {
1143+ name : "DNS glob *.host.example does not match two-level sub foo.bar.host.example" ,
1144+ tlsState : buildConnStateWithSANs (nil , []string {"foo.bar.host.example" }, nil , nil ),
1145+ spec : NewMtlsSanDNS (),
1146+ filterArgs : []any {"*.host.example" },
1147+ expectedStatus : http .StatusForbidden ,
1148+ expectServed : true ,
1149+ },
1150+ {
1151+ name : "DNS glob *.host.example does not match host.example itself" ,
1152+ tlsState : buildConnStateWithSANs (nil , []string {"host.example" }, nil , nil ),
1153+ spec : NewMtlsSanDNS (),
1154+ filterArgs : []any {"*.host.example" },
1155+ expectedStatus : http .StatusForbidden ,
1156+ expectServed : true ,
1157+ },
1158+ {
1159+ name : "DNS glob does not match unrelated domain" ,
1160+ tlsState : buildConnStateWithSANs (nil , []string {"evil.com" }, nil , nil ),
1161+ spec : NewMtlsSanDNS (),
1162+ filterArgs : []any {"*.host.example" },
1163+ expectedStatus : http .StatusForbidden ,
1164+ expectServed : true ,
1165+ },
1166+ {
1167+ name : "DNS mix exact and glob — exact matches" ,
1168+ tlsState : buildConnStateWithSANs (nil , []string {"exact.example.com" }, nil , nil ),
1169+ spec : NewMtlsSanDNS (),
1170+ filterArgs : []any {"exact.example.com" , "*.host.example" },
1171+ expectedStatus : 0 ,
1172+ expectServed : false ,
1173+ },
1174+ {
1175+ name : "DNS mix exact and glob — glob matches" ,
1176+ tlsState : buildConnStateWithSANs (nil , []string {"sub.host.example" }, nil , nil ),
1177+ spec : NewMtlsSanDNS (),
1178+ filterArgs : []any {"exact.example.com" , "*.host.example" },
1179+ expectedStatus : 0 ,
1180+ expectServed : false ,
1181+ },
1182+ // URI glob matching
1183+ {
1184+ name : "URI glob spiffe://services.example/applications/* matches leaf path" ,
1185+ tlsState : buildConnStateWithSANs (nil , nil , nil ,
1186+ []* url.URL {{Scheme : "spiffe" , Host : "services.example" , Path : "/applications/myapp" }}),
1187+ spec : NewMtlsSanURI (),
1188+ filterArgs : []any {"spiffe://services.example/applications/*" },
1189+ expectedStatus : 0 ,
1190+ expectServed : false ,
1191+ },
1192+ {
1193+ name : "URI glob spiffe://services.example/applications/* matches leaf path without query" ,
1194+ tlsState : buildConnStateWithSANs (nil , nil , nil ,
1195+ []* url.URL {{Scheme : "spiffe" , Host : "services.example" , Path : "/applications/myapp" , RawQuery : "role=admin" }}),
1196+ spec : NewMtlsSanURI (),
1197+ filterArgs : []any {"spiffe://services.example/applications/*" },
1198+ expectedStatus : 0 ,
1199+ expectServed : false ,
1200+ },
1201+ {
1202+ name : "URI glob spiffe://services.example/applications/* matches leaf path Syamala" ,
1203+ tlsState : buildConnStateWithSANs (nil , nil , nil ,
1204+ []* url.URL {{Scheme : "spiffe" , Host : "services.example" , Path : "/applications/myappXrole=admin" }}),
1205+ spec : NewMtlsSanURI (),
1206+ filterArgs : []any {"spiffe://services.example/applications/*" },
1207+ expectedStatus : 0 ,
1208+ expectServed : false ,
1209+ },
1210+ {
1211+ name : "URI glob spiffe://services.example/applications/* does not match nested path" ,
1212+ tlsState : buildConnStateWithSANs (nil , nil , nil ,
1213+ []* url.URL {{Scheme : "spiffe" , Host : "services.example" , Path : "/applications/a/b" }}),
1214+ spec : NewMtlsSanURI (),
1215+ filterArgs : []any {"spiffe://services.example/applications/*" },
1216+ expectedStatus : http .StatusForbidden ,
1217+ expectServed : true ,
1218+ },
1219+ {
1220+ name : "URI glob does not match different host" ,
1221+ tlsState : buildConnStateWithSANs (nil , nil , nil ,
1222+ []* url.URL {{Scheme : "spiffe" , Host : "evil.example" , Path : "/applications/myapp" }}),
1223+ spec : NewMtlsSanURI (),
1224+ filterArgs : []any {"spiffe://services.example/applications/*" },
1225+ expectedStatus : http .StatusForbidden ,
1226+ expectServed : true ,
1227+ },
1228+ {
1229+ name : "URI mix exact and glob — glob matches" ,
1230+ tlsState : buildConnStateWithSANs (nil , nil , nil ,
1231+ []* url.URL {{Scheme : "spiffe" , Host : "services.example" , Path : "/applications/myapp" }}),
1232+ spec : NewMtlsSanURI (),
1233+ filterArgs : []any {"spiffe://other.example/svc" , "spiffe://services.example/applications/*" },
1234+ expectedStatus : 0 ,
1235+ expectServed : false ,
1236+ },
1237+ {
1238+ name : "URI mix exact and glob — exact matches" ,
1239+ tlsState : buildConnStateWithSANs (nil , nil , nil ,
1240+ []* url.URL {{Scheme : "spiffe" , Host : "other.example" , Path : "/svc" }}),
1241+ spec : NewMtlsSanURI (),
1242+ filterArgs : []any {"spiffe://other.example/svc" , "spiffe://services.example/applications/*" },
1243+ expectedStatus : 0 ,
1244+ expectServed : false ,
1245+ },
1246+ {
1247+ name : "URI glob — none match — 403 Forbidden" ,
1248+ tlsState : buildConnStateWithSANs (nil , nil , nil ,
1249+ []* url.URL {{Scheme : "spiffe" , Host : "evil.example" , Path : "/applications/myapp" }}),
1250+ spec : NewMtlsSanURI (),
1251+ filterArgs : []any {"spiffe://other.example/svc" , "spiffe://services.example/applications/*" },
1252+ expectedStatus : http .StatusForbidden ,
1253+ expectServed : true ,
1254+ },
11051255 } {
11061256 t .Run (tt .name , func (t * testing.T ) {
11071257 t .Parallel ()
0 commit comments