Skip to content

Commit 77d631c

Browse files
author
Jim Minter
committed
Disallow @ character in URL patterns, so that people don't mistakenly try
to add URL patterns of the form username@hostname/path. Extend admission controller to reject invalid URL patterns on secrets to provide early feedback to end users when their patterns are wrong.
1 parent a994ae6 commit 77d631c

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

pkg/build/admission/secretinjector/admission.go

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import (
77

88
"github.com/golang/glog"
99

10+
"k8s.io/apimachinery/pkg/api/errors"
1011
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/apimachinery/pkg/util/validation/field"
1113
"k8s.io/apiserver/pkg/admission"
1214
restclient "k8s.io/client-go/rest"
1315
"k8s.io/kubernetes/pkg/api"
@@ -21,7 +23,7 @@ import (
2123
func init() {
2224
admission.RegisterPlugin("openshift.io/BuildConfigSecretInjector", func(config io.Reader) (admission.Interface, error) {
2325
return &secretInjector{
24-
Handler: admission.NewHandler(admission.Create),
26+
Handler: admission.NewHandler(admission.Create, admission.Update),
2527
}, nil
2628
})
2729
}
@@ -34,11 +36,20 @@ type secretInjector struct {
3436
var _ = oadmission.WantsRESTClientConfig(&secretInjector{})
3537

3638
func (si *secretInjector) Admit(attr admission.Attributes) (err error) {
37-
bc, ok := attr.GetObject().(*buildapi.BuildConfig)
38-
if !ok {
39-
return nil
39+
obj := attr.GetObject()
40+
41+
if bc, ok := obj.(*buildapi.BuildConfig); ok && attr.GetOperation() == admission.Create {
42+
return si.admitNewBuildConfig(attr, bc)
4043
}
4144

45+
if secret, ok := obj.(*api.Secret); ok {
46+
return si.admitSecret(attr, secret)
47+
}
48+
49+
return nil
50+
}
51+
52+
func (si *secretInjector) admitNewBuildConfig(attr admission.Attributes, bc *buildapi.BuildConfig) (err error) {
4253
if bc.Spec.Source.SourceSecret != nil || bc.Spec.Source.Git == nil {
4354
return nil
4455
}
@@ -98,6 +109,30 @@ func (si *secretInjector) Admit(attr admission.Attributes) (err error) {
98109
return nil
99110
}
100111

112+
func (si *secretInjector) admitSecret(attr admission.Attributes, secret *api.Secret) (err error) {
113+
errs := field.ErrorList{}
114+
115+
for k, v := range secret.GetAnnotations() {
116+
if strings.HasPrefix(k, buildapi.BuildSourceSecretMatchURIAnnotationPrefix) {
117+
v = strings.TrimSpace(v)
118+
if v == "" {
119+
continue
120+
}
121+
122+
_, err := urlpattern.NewURLPattern(v)
123+
if err != nil {
124+
errs = append(errs, field.Invalid(field.NewPath("metadata.annotations", k), v, err.Error()))
125+
}
126+
}
127+
}
128+
129+
if len(errs) > 0 {
130+
return errors.NewInvalid(api.Kind("secret"), secret.Name, errs)
131+
}
132+
133+
return nil
134+
}
135+
101136
func (si *secretInjector) SetRESTClientConfig(restClientConfig restclient.Config) {
102137
si.restClientConfig = restClientConfig
103138
}

pkg/util/urlpattern/urlpattern.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var InvalidPatternError = errors.New("invalid pattern")
1212

1313
var urlPatternRegex = regexp.MustCompile(`^` +
1414
`(?:(\*|git|http|https|ssh)://)` +
15-
`(\*|(?:\*\.)?[^/*]+)` +
15+
`(\*|(?:\*\.)?[^@/*]+)` +
1616
`(/.*)` +
1717
`$`)
1818

pkg/util/urlpattern/urlpattern_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func TestMatchPattern(t *testing.T) {
4444
expectedScheme: `^(git|http|https|ssh)$`,
4545
expectedHost: `^.*$`,
4646
expectedPath: `^/.*$`,
47-
expectedMatch: []string{`https://github.com/`},
47+
expectedMatch: []string{`https://github.com/`, `https://user:[email protected]/`, `ssh://[email protected]/`},
4848
expectedNotMatch: []string{`ftp://github.com/`},
4949
},
5050
{
@@ -80,15 +80,15 @@ func TestMatchPattern(t *testing.T) {
8080
expectedScheme: `^https$`,
8181
expectedHost: `^github\.com$`,
8282
expectedPath: `^/.*$`,
83-
expectedMatch: []string{`https://github.com/`},
83+
expectedMatch: []string{`https://github.com/`, `https://user:[email protected]/`},
8484
expectedNotMatch: []string{`https://test.github.com/`},
8585
},
8686
{
8787
pattern: `https://*.github.com/*`,
8888
expectedScheme: `^https$`,
8989
expectedHost: `^(?:.*\.)?github\.com$`,
9090
expectedPath: `^/.*$`,
91-
expectedMatch: []string{`https://github.com/`, `https://test.github.com/`},
91+
expectedMatch: []string{`https://github.com/`, `https://user:[email protected]/`, `https://test.github.com/`},
9292
},
9393
{
9494
pattern: `https://\.+?()|[]{}^$/*`,
@@ -108,6 +108,10 @@ func TestMatchPattern(t *testing.T) {
108108
pattern: `https://git*hub.com/*`,
109109
expectedErr: true,
110110
},
111+
{
112+
pattern: `*://[email protected]/*`,
113+
expectedErr: true,
114+
},
111115
{
112116
pattern: `https://github.com/`,
113117
expectedScheme: `^https$`,

0 commit comments

Comments
 (0)