From 516d39d54f81d53127113cd2a1440f1f0a013fe3 Mon Sep 17 00:00:00 2001 From: Gwendal Leclerc Date: Fri, 3 Jul 2020 01:31:02 +0200 Subject: [PATCH 1/2] feat: add skip_verify_tls option on proxy mocks to authorize insecure redirects --- docs/.vuepress/public/smocker.schema.json | 1 + .../technical-documentation/mock-definition.md | 7 +++++-- server/types/mock.go | 7 +++++++ tests/data/proxy_mock_list.yml | 16 ++++++++++++++++ tests/features/set_mocks.yml | 12 +++++++----- tests/features/use_mocks.yml | 18 +++++++++++++++++- 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/docs/.vuepress/public/smocker.schema.json b/docs/.vuepress/public/smocker.schema.json index 39df1d1..b7c94ec 100644 --- a/docs/.vuepress/public/smocker.schema.json +++ b/docs/.vuepress/public/smocker.schema.json @@ -127,6 +127,7 @@ "host": { "type": "string" }, "delay": { "type": "string" }, "follow_redirect": { "type": "boolean" }, + "skip_verify_tls": { "type": "boolean" }, "keep_host": { "type": "boolean" }, "headers": { "$ref": "#/definitions/headers" } } diff --git a/docs/technical-documentation/mock-definition.md b/docs/technical-documentation/mock-definition.md index 89f795b..8e38578 100644 --- a/docs/technical-documentation/mock-definition.md +++ b/docs/technical-documentation/mock-definition.md @@ -139,7 +139,7 @@ query_params: - matcher: ShouldMatch value: bar.* - matcher: ShouldContainSubstring - value: baz + value: baz ``` --- @@ -312,6 +312,7 @@ It has the following format: proxy: host: # destination host follow_redirect: # optional boolean + skip_verify_tls: # optional boolean keep_host: # optional boolean headers: # optional map of string lists Forwarded: "for=unknown;host=www.example.com;proto=http" @@ -320,7 +321,9 @@ proxy: By default, redirect responses from the destination host are returned as any other response. Setting `follow_redirect` to `true` makes Smocker follow any redirect response before responding. -Host header is overriden using destination host value by default. With `keep_host` set to `true`, request sent to the +If you need to deal with hosts using HTTPS and self-signed certificates, you can define the proxy mock as **insecure** by setting `skip_verify_tls` to `true`. + +Host header is overriden using destination host value by default. With `keep_host` set to `true`, request sent to the destination host have same `Host` HTTP header as incoming request. Headers defined in the proxy mock definition are injected in the request sent to the destination host. If the header is already diff --git a/server/types/mock.go b/server/types/mock.go index 67de1bd..7ef9a35 100644 --- a/server/types/mock.go +++ b/server/types/mock.go @@ -1,6 +1,7 @@ package types import ( + "crypto/tls" "errors" "fmt" "io/ioutil" @@ -151,6 +152,7 @@ type MockProxy struct { Host string `json:"host" yaml:"host"` Delay time.Duration `json:"delay,omitempty" yaml:"delay,omitempty"` FollowRedirect bool `json:"follow_redirect,omitempty" yaml:"follow_redirect,omitempty"` + SkipVerifyTLS bool `json:"skip_verify_tls,omitempty" yaml:"skip_verify_tls,omitempty"` KeepHost bool `json:"keep_host,omitempty" yaml:"keep_host,omitempty"` Headers MapStringSlice `json:"headers,omitempty" yaml:"headers,omitempty"` } @@ -184,6 +186,11 @@ func (mp MockProxy) Redirect(req Request) (*MockResponse, error) { if !mp.FollowRedirect { client.CheckRedirect = noFollow } + if mp.SkipVerifyTLS { + client.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + } resp, err := client.Do(proxyReq) if err != nil { return nil, err diff --git a/tests/data/proxy_mock_list.yml b/tests/data/proxy_mock_list.yml index f2da034..0125cca 100644 --- a/tests/data/proxy_mock_list.yml +++ b/tests/data/proxy_mock_list.yml @@ -39,3 +39,19 @@ multi: - "foo" - "baz" +- request: + method: GET + headers: + X-Filter: badssl + X-Value: insecure + proxy: + host: https://self-signed.badssl.com + skip_verify_tls: true +- request: + method: GET + headers: + X-Filter: badssl + X-Value: secure + proxy: + host: https://self-signed.badssl.com + skip_verify_tls: false diff --git a/tests/features/set_mocks.yml b/tests/features/set_mocks.yml index a01fe4e..e5d31e4 100644 --- a/tests/features/set_mocks.yml +++ b/tests/features/set_mocks.yml @@ -170,11 +170,13 @@ testcases: url: http://localhost:8081/mocks assertions: - result.statuscode ShouldEqual 200 - - result.bodyjson.__len__ ShouldEqual 7 - - result.bodyjson.bodyjson6.proxy.host ShouldEqual https://jsonplaceholder.typicode.com - - result.bodyjson.bodyjson5.proxy.host ShouldEqual https://jsonplaceholder.typicode.com + - result.bodyjson.__len__ ShouldEqual 9 + - result.bodyjson.bodyjson8.proxy.host ShouldEqual https://jsonplaceholder.typicode.com + - result.bodyjson.bodyjson7.proxy.host ShouldEqual https://jsonplaceholder.typicode.com + - result.bodyjson.bodyjson6.proxy.host ShouldEqual https://httpbin.org + - result.bodyjson.bodyjson5.proxy.host ShouldEqual https://httpbin.org - result.bodyjson.bodyjson4.proxy.host ShouldEqual https://httpbin.org - result.bodyjson.bodyjson3.proxy.host ShouldEqual https://httpbin.org - result.bodyjson.bodyjson2.proxy.host ShouldEqual https://httpbin.org - - result.bodyjson.bodyjson1.proxy.host ShouldEqual https://httpbin.org - - result.bodyjson.bodyjson0.proxy.host ShouldEqual https://httpbin.org + - result.bodyjson.bodyjson1.proxy.host ShouldEqual https://self-signed.badssl.com + - result.bodyjson.bodyjson0.proxy.host ShouldEqual https://self-signed.badssl.com diff --git a/tests/features/use_mocks.yml b/tests/features/use_mocks.yml index b1bce3b..197cbe9 100644 --- a/tests/features/use_mocks.yml +++ b/tests/features/use_mocks.yml @@ -267,4 +267,20 @@ testcases: assertions: - result.statuscode ShouldEqual 200 - result.bodyjson.headers.custom ShouldEqual foobar - - result.bodyjson.headers.multi ShouldEqual foo,baz \ No newline at end of file + - result.bodyjson.headers.multi ShouldEqual foo,baz + - type: http + method: GET + url: http://localhost:8080/ + headers: + X-Filter: badssl + X-Value: insecure + assertions: + - result.statuscode ShouldEqual 200 + - type: http + method: GET + url: http://localhost:8080/ + headers: + X-Filter: badssl + X-Value: secure + assertions: + - result.statuscode ShouldEqual 602 From ea16f571c0032686b4ef764843d22da981a4df45 Mon Sep 17 00:00:00 2001 From: Gwendal Leclerc Date: Fri, 3 Jul 2020 15:36:09 +0200 Subject: [PATCH 2/2] feat: use default http transport instead of empty one when skip_verify_tls is setted on proxy mock --- server/types/mock.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/types/mock.go b/server/types/mock.go index 7ef9a35..0faa40b 100644 --- a/server/types/mock.go +++ b/server/types/mock.go @@ -187,9 +187,10 @@ func (mp MockProxy) Redirect(req Request) (*MockResponse, error) { client.CheckRedirect = noFollow } if mp.SkipVerifyTLS { - client.Transport = &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } + // we clone to avoid overwriting the default transport configuration + customTransport := http.DefaultTransport.(*http.Transport).Clone() + customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + client.Transport = customTransport } resp, err := client.Do(proxyReq) if err != nil {