diff --git a/CHANGELOG.md b/CHANGELOG.md index 64e6bbf..812840a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +- [Bug: Normalize both url path and capability substring for endpoint authorization #170](https://github.com/xmidt-org/bascule/issues/170) ## [v0.11.3] - [Remove deprecated sallust code #167](https://github.com/xmidt-org/bascule/pull/167) diff --git a/basculechecks/endpointchecks.go b/basculechecks/endpointchecks.go index 6eeed75..abf005c 100644 --- a/basculechecks/endpointchecks.go +++ b/basculechecks/endpointchecks.go @@ -69,6 +69,8 @@ type RegexEndpointCheck struct { // there to be an endpoint regular expression and an http method - separated by // a colon. The expected format of a capability is: : +// Note, the endpoint url path and the capabilities substring (used for authorization) +// will be normalized to have a leading `/` if missing. func NewRegexEndpointCheck(prefix string, acceptAllMethod string) (RegexEndpointCheck, error) { matchPrefix, err := regexp.Compile("^" + prefix + "(.+):(.+?)$") if err != nil { @@ -97,12 +99,12 @@ func (r RegexEndpointCheck) Authorized(capability string, urlToMatch string, met return false } - re, err := regexp.Compile(matches[1]) //url regex that capability grants access to + re, err := regexp.Compile(urlPathNormalization(matches[1])) //url regex that capability grants access to if err != nil { return false } - matchIdxs := re.FindStringIndex(urlToMatch) + matchIdxs := re.FindStringIndex(urlPathNormalization(urlToMatch)) if matchIdxs == nil || matchIdxs[0] != 0 { return false } @@ -114,3 +116,13 @@ func (r RegexEndpointCheck) Authorized(capability string, urlToMatch string, met func (e RegexEndpointCheck) Name() string { return "regex" } + +// urlPathNormalization returns an url path with a leading `/` if missing, +// otherwise the same unmodified url path is returned. +func urlPathNormalization(url string) string { + if url[0] == '/' { + return url + } + + return "/" + url +} diff --git a/go.mod b/go.mod index 07f9b6f..492c770 100644 --- a/go.mod +++ b/go.mod @@ -65,13 +65,13 @@ require ( go.opentelemetry.io/otel/trace v1.11.2 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/dig v1.16.0 // indirect + go.uber.org/dig v1.16.1 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/crypto v0.5.0 // indirect golang.org/x/net v0.5.0 // indirect golang.org/x/sys v0.4.0 // indirect golang.org/x/text v0.6.0 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/genproto v0.0.0-20230117162540-28d6b9783ac4 // indirect google.golang.org/grpc v1.52.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index ad04c7c..5cba34f 100644 --- a/go.sum +++ b/go.sum @@ -587,8 +587,8 @@ go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.10.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw= go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= -go.uber.org/dig v1.16.0 h1:O48QoUEj4ePocypAIE5jz+SrxVdG/izHM1CZ/Yjrwww= -go.uber.org/dig v1.16.0/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= +go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= +go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= go.uber.org/fx v1.13.1/go.mod h1:bREWhavnedxpJeTq9pQT53BbvwhUv7TcpsOqcH4a+3w= go.uber.org/fx v1.18.1/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= go.uber.org/fx v1.19.1 h1:JwYIYAQzXBuBBwSZ1/tn/95pnQO/Sp3yE8lWj9eSAzI= @@ -972,8 +972,8 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230117162540-28d6b9783ac4 h1:yF0uHwqqYt2tIL2F4hxRWA1ZFX43SEunWAK8MnQiclk= +google.golang.org/genproto v0.0.0-20230117162540-28d6b9783ac4/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=