Skip to content

Commit

Permalink
Added global and local ignore path rewriting support to path configur…
Browse files Browse the repository at this point in the history
…ations.
  • Loading branch information
jacobm-splunk authored and daveshanley committed Jun 14, 2024
1 parent 0ac01b6 commit 1357ba0
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 19 deletions.
21 changes: 20 additions & 1 deletion cmd/root_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,12 @@ var (
}

// paths
if len(config.PathConfigurations) > 0 || len(config.StaticPaths) > 0 || len(config.HARPathAllowList) > 0 {
if len(config.PathConfigurations) > 0 || len(config.StaticPaths) > 0 || len(config.HARPathAllowList) > 0 || len(config.IgnorePathRewrite) > 0 {
config.CompilePaths()
if len(config.IgnorePathRewrite) > 0 {
printLoadedIgnorePathRewrite(config.IgnorePathRewrite)
}

if len(config.PathConfigurations) > 0 {
printLoadedPathConfigurations(config.PathConfigurations)
}
Expand Down Expand Up @@ -680,6 +684,17 @@ func Execute(version, commit, date string, fs embed.FS) {
}
}

func printLoadedIgnorePathRewrite(ignoreRewritePaths []*shared.IgnoreRewriteConfig) {
pterm.Info.Printf("Loaded %d %s on which to globally ignore rewriting", len(ignoreRewritePaths),
shared.Pluralize(len(ignoreRewritePaths), "path", "paths"))
pterm.Println()

for _, ignoreRewrite := range ignoreRewritePaths {
pterm.Printf("🙅 Paths matching '%s' will not be re-written regardless of Path Rewrite configuration\n", pterm.LightCyan(ignoreRewrite.Path))
}
pterm.Println()
}

func printLoadedPathConfigurations(configs map[string]*shared.WiretapPathConfig) {
pterm.Info.Printf("Loaded %d path %s:\n", len(configs),
shared.Pluralize(len(configs), "configuration", "configurations"))
Expand All @@ -698,6 +713,10 @@ func printLoadedPathConfigurations(configs map[string]*shared.WiretapPathConfig)
pterm.Printf("🗑️ '%s' is being %s\n", pterm.LightCyan(h), pterm.LightRed("dropped"))
}
}
for _, ignoreRewrite := range v.IgnoreRewrite {
pterm.Printf("🙅 Paths matching '%s' will not be re-written for this path configuration\n", pterm.LightCyan(ignoreRewrite.Path))
}

if v.Auth != "" {
pterm.Printf("🔒 Basic authentication implemented for '%s'\n", pterm.LightMagenta(k))
}
Expand Down
56 changes: 45 additions & 11 deletions config/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package config
import (
"fmt"
"github.com/pb33f/wiretap/shared"
"github.com/pterm/pterm"
"strings"
)

Expand Down Expand Up @@ -65,15 +66,56 @@ func PathValidationAllowListed(path string, configuration *shared.WiretapConfigu
return false
}

func rewriteTaget(path string, pathConfig *shared.WiretapPathConfig, configuration *shared.WiretapConfiguration) string {
scheme := "http://"
if pathConfig.Secure {
scheme = "https://"
}
target := strings.ReplaceAll(strings.ReplaceAll(configuration.ReplaceWithVariables(pathConfig.Target),
"http://", ""), "https://", "")

if path[0] != '/' && pathConfig.Target[len(pathConfig.Target)-1] != '/' {
path = fmt.Sprintf("/%s", path)
}
return fmt.Sprintf("%s%s%s", scheme, target, path)
}

func RewritePath(path string, configuration *shared.WiretapConfiguration) string {
paths := FindPaths(path, configuration)
var replaced string = path
if len(paths) > 0 {
// extract first path
pathConfig := paths[0]
replaced = ""

for _, globalIgnoreRewrite := range configuration.CompiledIgnorePathRewrite {
// If the current path matches the ignore rewrite, we should skip rewriting,
// and instead check if we even want to rewrite the target
if globalIgnoreRewrite.CompiledIgnoreRewrite.Match(path) {
if globalIgnoreRewrite.RewriteTarget {
return rewriteTaget(path, pathConfig, configuration)
} else {
pterm.Info.Printf("[wiretap] Not re-writing path '%s' due to global ignore rewrite configuration\n", path)
return path
}
}
}

for key := range pathConfig.CompiledPath.CompiledPathRewrite {
if pathConfig.CompiledPath.CompiledPathRewrite[key].MatchString(path) {

// Check if this path matches a local ignore rewrite. If so, then check if we need to rewrite the target
for _, ignoreRewrite := range pathConfig.CompiledIgnoreRewrite {
if ignoreRewrite.CompiledIgnoreRewrite.Match(path) {
if ignoreRewrite.RewriteTarget {
return rewriteTaget(path, pathConfig, configuration)
} else {
pterm.Info.Printf("[wiretap] Not re-writing path '%s' due to local ignore rewrite configuration\n", path)
return path
}
}
}

replace := pathConfig.PathRewrite[key]
rex := pathConfig.CompiledPath.CompiledPathRewrite[key]
replacedPath := rex.ReplaceAllString(path, replace)
Expand All @@ -92,20 +134,12 @@ func RewritePath(path string, configuration *shared.WiretapConfiguration) string
break
}
}

// no rewriting, just replace target.
if replaced == "" {
scheme := "http://"
if pathConfig.Secure {
scheme = "https://"
}
target := strings.ReplaceAll(strings.ReplaceAll(configuration.ReplaceWithVariables(pathConfig.Target),
"http://", ""), "https://", "")

if path[0] != '/' && pathConfig.Target[len(pathConfig.Target)-1] != '/' {
path = fmt.Sprintf("/%s", path)
}
replaced = fmt.Sprintf("%s%s%s", scheme, target, path)
replaced = rewriteTaget(path, pathConfig, configuration)
}

}

return replaced
Expand Down
46 changes: 39 additions & 7 deletions shared/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type WiretapConfiguration struct {
IgnoreValidation []string `json:"ignoreValidation,omitempty" yaml:"ignoreValidation,omitempty"`
ValidationAllowList []string `json:"validationAllowList,omitempty" yaml:"validationAllowList,omitempty"`
StrictRedirectLocation bool `json:"strictRedirectLocation,omitempty" yaml:"strictRedirectLocation,omitempty"`
IgnorePathRewrite []*IgnoreRewriteConfig `json:"ignorePathRewrite,omitempty" yaml:"ignorePathRewrite,omitempty"`
HARFile *harhar.HAR `json:"-" yaml:"-"`
CompiledPathDelays map[string]*CompiledPathDelay `json:"-" yaml:"-"`
CompiledVariables map[string]*CompiledVariable `json:"-" yaml:"-"`
Expand All @@ -63,6 +64,7 @@ type WiretapConfiguration struct {
CompiledRedirectAllowList []*CompiledRedirect `json:"-" yaml:"-"`
CompiledIgnoreValidations []*CompiledRedirect `json:"-" yaml:"-"`
CompiledValidationAllowList []*CompiledRedirect `json:"-" yaml:"-"`
CompiledIgnorePathRewrite []*CompiledIgnoreRewrite `json:"-" yaml:"-"`
FS embed.FS `json:"-"`
Logger *slog.Logger
}
Expand All @@ -79,6 +81,16 @@ func (wtc *WiretapConfiguration) CompilePaths() {
}
wtc.StaticPathsCompiled = comp
}
if len(wtc.IgnorePathRewrite) > 0 {
compiledPaths := make([]*CompiledIgnoreRewrite, len(wtc.IgnorePathRewrite))
for x, ignoreRewrite := range wtc.IgnorePathRewrite {
compiledPaths[x] = &CompiledIgnoreRewrite{
RewriteTarget: ignoreRewrite.RewriteTarget,
CompiledIgnoreRewrite: glob.MustCompile(ignoreRewrite.Path),
}
}
wtc.CompiledIgnorePathRewrite = compiledPaths
}
}

func (wtc *WiretapConfiguration) CompilePathDelays() {
Expand Down Expand Up @@ -181,13 +193,25 @@ type WiretapWebsocketConfig struct {
}

type WiretapPathConfig struct {
Target string `json:"target,omitempty" yaml:"target,omitempty"`
PathRewrite map[string]string `json:"pathRewrite,omitempty" yaml:"pathRewrite,omitempty"`
ChangeOrigin bool `json:"changeOrigin,omitempty" yaml:"changeOrigin,omitempty"`
Headers *WiretapHeaderConfig `json:"headers,omitempty" yaml:"headers,omitempty"`
Secure bool `json:"secure,omitempty" yaml:"secure,omitempty"`
Auth string `json:"auth,omitempty" yaml:"auth,omitempty"`
CompiledPath *CompiledPath `json:"-"`
Target string `json:"target,omitempty" yaml:"target,omitempty"`
PathRewrite map[string]string `json:"pathRewrite,omitempty" yaml:"pathRewrite,omitempty"`
ChangeOrigin bool `json:"changeOrigin,omitempty" yaml:"changeOrigin,omitempty"`
Headers *WiretapHeaderConfig `json:"headers,omitempty" yaml:"headers,omitempty"`
Secure bool `json:"secure,omitempty" yaml:"secure,omitempty"`
Auth string `json:"auth,omitempty" yaml:"auth,omitempty"`
IgnoreRewrite []*IgnoreRewriteConfig `json:"ignoreRewrite,omitempty" yaml:"ignoreRewrite,omitempty"`
CompiledPath *CompiledPath `json:"-"`
CompiledIgnoreRewrite []*CompiledIgnoreRewrite `json:"-"`
}

type IgnoreRewriteConfig struct {
RewriteTarget bool `json:"rewriteTarget,omitempty" yaml:"rewriteTarget,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
}

type CompiledIgnoreRewrite struct {
RewriteTarget bool
CompiledIgnoreRewrite glob.Glob
}

type CompiledPath struct {
Expand Down Expand Up @@ -235,6 +259,14 @@ func (wpc *WiretapPathConfig) Compile(key string) *CompiledPath {
for x := range wpc.PathRewrite {
cp.CompiledPathRewrite[x] = regexp.MustCompile(x)
}

wpc.CompiledIgnoreRewrite = make([]*CompiledIgnoreRewrite, len(wpc.IgnoreRewrite))
for i, ignoreRewrite := range wpc.IgnoreRewrite {
wpc.CompiledIgnoreRewrite[i] = &CompiledIgnoreRewrite{
RewriteTarget: ignoreRewrite.RewriteTarget,
CompiledIgnoreRewrite: glob.MustCompile(ignoreRewrite.Path),
}
}
return cp
}

Expand Down

0 comments on commit 1357ba0

Please # to comment.