Skip to content

Commit 5714744

Browse files
kasimtjk.torgaev
andauthored
Feature/mask query 3 (#506)
* mask query * mask query * mask query * mask query * mask query * mask query --------- Co-authored-by: k.torgaev <[email protected]>
1 parent 3f05408 commit 5714744

File tree

8 files changed

+99
-5
lines changed

8 files changed

+99
-5
lines changed

config/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ type Config struct {
6464
// Whether to print debug logs
6565
LogDebug bool `yaml:"log_debug,omitempty"`
6666

67+
LogMasks []LogMask `yaml:"log_masks,omitempty"`
68+
6769
// Whether to ignore security warnings
6870
HackMePlease bool `yaml:"hack_me_please,omitempty"`
6971

@@ -1216,3 +1218,8 @@ func (c Config) checkVulnerabilities() error {
12161218
}
12171219
return nil
12181220
}
1221+
1222+
type LogMask struct {
1223+
Regex string `yaml:"regex"`
1224+
Replacement string `yaml:"replacement"`
1225+
}

config/config_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ var fullConfig = Config{
9393
},
9494
LogDebug: true,
9595

96+
LogMasks: []LogMask{
97+
{
98+
Regex: `(s3\(\s*'(?:(?:\\'|[^'])*)'\s*,\s*'(?:(?:\\'|[^'])*)'\s*,\s*')((?:\\'|[^'])*)(')`,
99+
Replacement: "$1******$3",
100+
},
101+
},
102+
96103
Clusters: []Cluster{
97104
{
98105
Name: "first cluster",
@@ -879,6 +886,9 @@ users:
879886
- 1.2.3.0/24
880887
deny_https: true
881888
log_debug: true
889+
log_masks:
890+
- regex: (s3\(\s*'(?:(?:\\'|[^'])*)'\s*,\s*'(?:(?:\\'|[^'])*)'\s*,\s*')((?:\\'|[^'])*)(')
891+
replacement: $1******$3
882892
hack_me_please: true
883893
network_groups:
884894
- name: office

config/testdata/full.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
# By default debug logs are disabled.
44
log_debug: true
55

6+
# Optional log masks, for example replace s3('', '', 'secret', '') -> s3('', '', '******', '')
7+
log_masks:
8+
- regex: (s3\(\s*'(?:(?:\\'|[^'])*)'\s*,\s*'(?:(?:\\'|[^'])*)'\s*,\s*')((?:\\'|[^'])*)(')
9+
replacement: $1******$3
10+
611
# Whether to ignore security checks during config parsing.
712
#
813
# By default security checks are enabled.

docs/src/content/docs/cn/index.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,11 @@ caches:
352352
# By default debug logs are disabled.
353353
log_debug: true
354354
355+
# Optional log masks, for example replace s3('', '', 'secret', '') -> s3('', '', '******', '')
356+
log_masks:
357+
- regex: (s3\(\s*'(?:(?:\\'|[^'])*)'\s*,\s*'(?:(?:\\'|[^'])*)'\s*,\s*')((?:\\'|[^'])*)(')
358+
replacement: $1******$3
359+
355360
# Whether to ignore security checks during config parsing.
356361
#
357362
# By default security checks are enabled.

docs/src/content/docs/configuration/default.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ Example of [full](https://github.com/contentsquare/chproxy/blob/master/config/te
1515
# By default debug logs are disabled.
1616
log_debug: true
1717

18+
# Optional log masks, for example replace s3('', '', 'secret', '') -> s3('', '', '******', '')
19+
log_masks:
20+
- regex: (s3\(\s*'(?:(?:\\'|[^'])*)'\s*,\s*'(?:(?:\\'|[^'])*)'\s*,\s*')((?:\\'|[^'])*)(')
21+
replacement: $1******$3
22+
1823
# Whether to ignore security checks during config parsing.
1924
#
2025
# By default security checks are enabled.

log/log.go

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import (
55
"io"
66
"log"
77
"os"
8+
"regexp"
89
"sync/atomic"
10+
11+
"github.com/contentsquare/chproxy/config"
912
)
1013

1114
var (
@@ -52,30 +55,58 @@ func Debugf(format string, args ...interface{}) {
5255
return
5356
}
5457
s := fmt.Sprintf(format, args...)
55-
debugLogger.Output(outputCallDepth, s) // nolint
58+
debugLogger.Output(outputCallDepth, mask(s)) // nolint
5659
}
5760

5861
// Infof prints info message according to a format
5962
func Infof(format string, args ...interface{}) {
6063
s := fmt.Sprintf(format, args...)
61-
infoLogger.Output(outputCallDepth, s) // nolint
64+
infoLogger.Output(outputCallDepth, mask(s)) // nolint
6265
}
6366

6467
// Errorf prints warning message according to a format
6568
func Errorf(format string, args ...interface{}) {
6669
s := fmt.Sprintf(format, args...)
67-
errorLogger.Output(outputCallDepth, s) // nolint
70+
errorLogger.Output(outputCallDepth, mask(s)) // nolint
6871
}
6972

7073
// ErrorWithCallDepth prints err into error log using the given callDepth.
7174
func ErrorWithCallDepth(err error, callDepth int) {
7275
s := err.Error()
73-
errorLogger.Output(outputCallDepth+callDepth, s) //nolint
76+
errorLogger.Output(outputCallDepth+callDepth, mask(s)) //nolint
7477
}
7578

7679
// Fatalf prints fatal message according to a format and exits program
7780
func Fatalf(format string, args ...interface{}) {
7881
s := fmt.Sprintf(format, args...)
79-
fatalLogger.Output(outputCallDepth, s) // nolint
82+
fatalLogger.Output(outputCallDepth, mask(s)) // nolint
8083
os.Exit(1)
8184
}
85+
86+
type regexReplacer struct {
87+
regex *regexp.Regexp
88+
replacement string
89+
}
90+
91+
var replacers []regexReplacer
92+
93+
func InitReplacer(logMasks []config.LogMask) error {
94+
for _, logMask := range logMasks {
95+
re, err := regexp.Compile(logMask.Regex)
96+
if err != nil {
97+
return fmt.Errorf("error compiling regex %s: %w", logMask.Regex, err)
98+
}
99+
replacers = append(replacers, regexReplacer{
100+
regex: re,
101+
replacement: logMask.Replacement,
102+
})
103+
}
104+
return nil
105+
}
106+
107+
func mask(s string) string {
108+
for _, r := range replacers {
109+
s = r.regex.ReplaceAllString(s, r.replacement)
110+
}
111+
return s
112+
}

log/log_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package log
2+
3+
import (
4+
"bytes"
5+
"log"
6+
"testing"
7+
8+
"github.com/contentsquare/chproxy/config"
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestLogMask(t *testing.T) {
13+
err := InitReplacer([]config.LogMask{
14+
{
15+
Regex: `(s3\(\s*'(?:(?:\\'|[^'])*)'\s*,\s*'(?:(?:\\'|[^'])*)'\s*,\s*')((?:\\'|[^'])*)(')`,
16+
Replacement: "$1******$3",
17+
},
18+
})
19+
assert.NoError(t, err)
20+
var b bytes.Buffer
21+
testLogger := log.New(&b, "DEBUG: ", stdLogFlags)
22+
err = testLogger.Output(outputCallDepth,
23+
mask("select * from s3('http://s3server/bucket', 'access-key', 'seret-key', 'CSVWithNamesAndTypes')"))
24+
assert.NoError(t, err)
25+
res, err := b.ReadString('\n')
26+
assert.NoError(t, err)
27+
assert.Contains(t, res, "select * from s3('http://s3server/bucket', 'access-key', '******', 'CSVWithNamesAndTypes')")
28+
}

main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ func main() {
5353
if err != nil {
5454
log.Fatalf("error while loading config: %s", err)
5555
}
56+
if err = log.InitReplacer(cfg.LogMasks); err != nil {
57+
log.Fatalf("error while log replacer init: %s", err)
58+
}
5659
registerMetrics(cfg)
5760
if err = applyConfig(cfg); err != nil {
5861
log.Fatalf("error while applying config: %s", err)

0 commit comments

Comments
 (0)