2026-02-12 13:48:01 +05:30
|
|
|
package interceptors
|
|
|
|
|
|
|
|
|
|
import (
|
2026-04-10 19:07:15 +05:30
|
|
|
"github.com/safedep/pmg/internal/audit"
|
2026-02-12 13:48:01 +05:30
|
|
|
"github.com/safedep/pmg/proxy"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// AuditLoggerInterceptor logs unknown outbound hosts observed by proxy mode.
|
|
|
|
|
// It is passive telemetry only and never blocks or mutates requests.
|
|
|
|
|
type AuditLoggerInterceptor struct{}
|
|
|
|
|
|
|
|
|
|
var _ proxy.Interceptor = (*AuditLoggerInterceptor)(nil)
|
|
|
|
|
var _ proxy.MITMDecider = (*AuditLoggerInterceptor)(nil)
|
|
|
|
|
|
|
|
|
|
func NewAuditLoggerInterceptor() *AuditLoggerInterceptor {
|
|
|
|
|
return &AuditLoggerInterceptor{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (i *AuditLoggerInterceptor) Name() string {
|
|
|
|
|
return "audit-logger-interceptor"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ShouldIntercept is always true so we can observe all proxied traffic.
|
|
|
|
|
func (i *AuditLoggerInterceptor) ShouldIntercept(_ *proxy.RequestContext) bool {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ShouldMITM is false because this interceptor is telemetry-only.
|
|
|
|
|
func (i *AuditLoggerInterceptor) ShouldMITM(_ *proxy.RequestContext) bool {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (i *AuditLoggerInterceptor) HandleRequest(ctx *proxy.RequestContext) (*proxy.InterceptorResponse, error) {
|
|
|
|
|
if ctx == nil || ctx.Hostname == "" {
|
|
|
|
|
return &proxy.InterceptorResponse{Action: proxy.ActionAllow}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if i.isKnownRegistryHost(ctx.Hostname) {
|
|
|
|
|
return &proxy.InterceptorResponse{Action: proxy.ActionAllow}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-10 19:07:15 +05:30
|
|
|
audit.LogProxyHostObserved(ctx.Hostname, ctx.Method, "audit_logger_interceptor", map[string]interface{}{
|
2026-02-12 13:48:01 +05:30
|
|
|
"request_id": ctx.RequestID,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return &proxy.InterceptorResponse{Action: proxy.ActionAllow}, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-03 18:19:31 +05:30
|
|
|
// wellKnownGoHosts are the default Go module-proxy and checksum-database
|
|
|
|
|
// hosts. Custom GOPROXY hosts are dynamic (known only to the Go interceptor's
|
|
|
|
|
// per-run config) and intentionally still surface here as observed hosts.
|
|
|
|
|
var wellKnownGoHosts = map[string]bool{
|
|
|
|
|
"proxy.golang.org": true,
|
|
|
|
|
"sum.golang.org": true,
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-12 13:48:01 +05:30
|
|
|
func (i *AuditLoggerInterceptor) isKnownRegistryHost(hostname string) bool {
|
2026-07-03 18:19:31 +05:30
|
|
|
return npmRegistryDomains.ContainsHostname(hostname) ||
|
|
|
|
|
pypiRegistryDomains.ContainsHostname(hostname) ||
|
|
|
|
|
wellKnownGoHosts[hostname]
|
2026-02-12 13:48:01 +05:30
|
|
|
}
|