github.com/waldiirawan/apm-agent-go/v2@v2.2.2/sanitizer_test.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package apm_test
    19  
    20  import (
    21  	"context"
    22  	"net/http"
    23  	"testing"
    24  
    25  	"github.com/pkg/errors"
    26  	"github.com/stretchr/testify/assert"
    27  	"github.com/stretchr/testify/require"
    28  
    29  	"github.com/waldiirawan/apm-agent-go/v2"
    30  	"github.com/waldiirawan/apm-agent-go/v2/apmtest"
    31  	"github.com/waldiirawan/apm-agent-go/v2/model"
    32  	"github.com/waldiirawan/apm-agent-go/v2/transport/transporttest"
    33  )
    34  
    35  func TestSanitizeRequestResponse(t *testing.T) {
    36  	req, _ := http.NewRequest("GET", "http://server.testing/", nil)
    37  	req.SetBasicAuth("foo", "bar")
    38  	req.Header.Set("X-Custom-Preauth-Header", "fubar")
    39  
    40  	for _, c := range []*http.Cookie{
    41  		{Name: "secret", Value: "top"},
    42  		{Name: "Custom-Credit-Card-Number", Value: "top"},
    43  		{Name: "sessionid", Value: "123"},
    44  		{Name: "user_id", Value: "456"},
    45  	} {
    46  		req.AddCookie(c)
    47  	}
    48  
    49  	tx, _, errors := apmtest.WithTransaction(func(ctx context.Context) {
    50  		e := apm.CaptureError(ctx, errors.New("boom!"))
    51  		defer e.Send()
    52  
    53  		tx := apm.TransactionFromContext(ctx)
    54  		tx.Context.SetHTTPRequest(req)
    55  		e.Context.SetHTTPRequest(req)
    56  
    57  		h := make(http.Header)
    58  		h.Add("Set-Cookie", (&http.Cookie{Name: "foo", Value: "bar"}).String())
    59  		h.Add("Set-Cookie", (&http.Cookie{Name: "baz", Value: "qux"}).String())
    60  		h.Set("X-Custom-Authly-Header", "bazquux")
    61  		tx.Context.SetHTTPResponseHeaders(h)
    62  		tx.Context.SetHTTPStatusCode(http.StatusTeapot)
    63  		e.Context.SetHTTPResponseHeaders(h)
    64  		e.Context.SetHTTPStatusCode(http.StatusTeapot)
    65  	})
    66  
    67  	checkContext := func(context *model.Context) {
    68  		assert.Equal(t, context.Request.Cookies, model.Cookies{
    69  			{Name: "Custom-Credit-Card-Number", Value: "[REDACTED]"},
    70  			{Name: "secret", Value: "[REDACTED]"},
    71  			{Name: "sessionid", Value: "[REDACTED]"},
    72  			{Name: "user_id", Value: "456"},
    73  		})
    74  		assert.Equal(t, model.Headers{
    75  			{
    76  				Key:    "Authorization",
    77  				Values: []string{"[REDACTED]"},
    78  			},
    79  			{
    80  				Key:    "X-Custom-Preauth-Header",
    81  				Values: []string{"[REDACTED]"},
    82  			},
    83  		}, context.Request.Headers)
    84  
    85  		// NOTE: the response includes multiple Set-Cookie headers,
    86  		// but we only report a single "[REDACTED]" value.
    87  		assert.Equal(t, model.Headers{
    88  			{
    89  				Key:    "Set-Cookie",
    90  				Values: []string{"[REDACTED]"},
    91  			},
    92  			{
    93  				Key:    "X-Custom-Authly-Header",
    94  				Values: []string{"[REDACTED]"},
    95  			},
    96  		}, context.Response.Headers)
    97  	}
    98  	checkContext(tx.Context)
    99  	for _, e := range errors {
   100  		checkContext(e.Context)
   101  	}
   102  }
   103  
   104  func TestSetSanitizedFieldNamesNone(t *testing.T) {
   105  	testSetSanitizedFieldNames(t, "top")
   106  }
   107  
   108  func TestSetSanitizedFieldNamesCaseSensitivity(t *testing.T) {
   109  	// patterns are matched case-insensitively by default
   110  	testSetSanitizedFieldNames(t, "[REDACTED]", "Secret")
   111  
   112  	// patterns can be made case-sensitive by clearing the "i" flag.
   113  	testSetSanitizedFieldNames(t, "top", "(?-i:Secret)")
   114  }
   115  
   116  func testSetSanitizedFieldNames(t *testing.T, expect string, sanitized ...string) {
   117  	tracer, transport := transporttest.NewRecorderTracer()
   118  	defer tracer.Close()
   119  	tracer.SetSanitizedFieldNames(sanitized...)
   120  
   121  	req, _ := http.NewRequest("GET", "http://server.testing/", nil)
   122  	req.AddCookie(&http.Cookie{Name: "secret", Value: "top"})
   123  
   124  	tx := tracer.StartTransaction("name", "type")
   125  	tx.Context.SetHTTPRequest(req)
   126  	tx.End()
   127  	tracer.Flush(nil)
   128  	payloads := transport.Payloads()
   129  	require.Len(t, payloads.Transactions, 1)
   130  
   131  	assert.Equal(t, payloads.Transactions[0].Context.Request.Cookies, model.Cookies{
   132  		{Name: "secret", Value: expect},
   133  	})
   134  }