claude code review changes

This commit is contained in:
2026-02-20 17:05:34 +05:30
parent 136957d75d
commit f1c5b9587b
9 changed files with 151 additions and 130 deletions

View File

@@ -109,7 +109,6 @@ func CORS(opts CORSOption) func(http.Handler) http.Handler {
ch.setAllowedMethods(opts.AllowedMethods)
ch.setExposedHeaders(opts.ExposedHeaders)
ch.setMaxAge(opts.MaxAge)
ch.maxAge = opts.MaxAge
ch.allowCredentials = opts.AllowCredentials
return ch

View File

@@ -56,7 +56,7 @@ type (
}
TransportSecurity struct {
// Age in seconts
// Age in seconds
MaxAge uint
IncludeSubDomains bool
Preload bool
@@ -111,110 +111,126 @@ const (
// Helmet headers to secure server response
func Helmet(opt HelmetOption) func(http.Handler) http.Handler {
// Precompute all static header values once at middleware creation time.
headers := buildHelmetHeaders(opt)
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Security-Policy", opt.ContentSecurityPolicy.value())
// Opener-Policy
if opt.CrossOriginOpenerPolicy == "" {
w.Header().Add("Cross-Origin-Opener-Policy", string(OpenerSameOrigin))
} else {
w.Header().Add("Cross-Origin-Opener-Policy", string(opt.CrossOriginOpenerPolicy))
for _, kv := range headers {
w.Header().Add(kv.key, kv.value)
}
// Resource-Policy
if opt.CrossOriginResourcePolicy == "" {
w.Header().Add("Cross-Origin-Resource-Policy", string(ResourceSameOrigin))
} else {
w.Header().Add("Cross-Origin-Resource-Policy", string(opt.CrossOriginResourcePolicy))
}
// Referrer-Policy
rpCount := len(opt.ReferrerPolicy)
if rpCount > 0 {
refP := make([]string, rpCount)
for i, r := range opt.ReferrerPolicy {
refP[i] = string(r)
}
w.Header().Add("Referrer-Policy", string(NoReferrer))
} else {
// default no referer
w.Header().Add("Referrer-Policy", string(NoReferrer))
}
// Origin-Agent-Cluster
if opt.OriginAgentCluster {
w.Header().Add("Origin-Agent-Cluster", "?1")
}
// Strict-Transport-Security
if opt.StrictTransportSecurity != nil {
var sb strings.Builder
if opt.StrictTransportSecurity.MaxAge == 0 {
opt.StrictTransportSecurity.MaxAge = YearDuration
}
sb.WriteString(fmt.Sprintf("max-age=%d", opt.StrictTransportSecurity.MaxAge))
if opt.StrictTransportSecurity.IncludeSubDomains {
sb.WriteString("; includeSubDomains")
}
if opt.StrictTransportSecurity.Preload {
sb.WriteString("; preload")
}
w.Header().Add("Strict-Transport-Security", sb.String())
}
if !opt.DisableSniffMimeType {
// MIME types advertised in the Content-Current headers should be followed and not be changed
w.Header().Add("X-Content-Type-Options", "nosniff")
}
if opt.DisableDNSPrefetch {
w.Header().Add("X-DNS-Prefetch-Control", "off")
} else {
w.Header().Add("X-DNS-Prefetch-Control", "on")
}
if !opt.DisableXDownload {
// Instructs Internet Explorer not to open the file directly but to offer it for download first.
w.Header().Add("X-Download-Options", "noopen")
}
// indicate whether a browser should be allowed to render a page in iframe | frame | embed | object
if opt.XFrameOption == "" {
w.Header().Add("X-Frame-Options", string(XFrameSameOrigin))
} else {
w.Header().Add("X-Frame-Options", string(opt.XFrameOption))
}
if opt.CrossDomainPolicies == "" {
w.Header().Add("X-Permitted-Cross-Domain-Policies", string(CDPNone))
} else {
w.Header().Add("X-Permitted-Cross-Domain-Policies", string(opt.CrossDomainPolicies))
}
w.Header().Del("X-Powered-By")
if opt.XssProtection {
// feature of IE, Chrome and Safari that stops pages from loading when they detect reflected
// cross-site scripting (XSS) attacks.
w.Header().Add("X-Xss-Protection", "1; mode=block")
} else {
// Following a decision by Google Chrome developers to disable Auditor,
// developers should be able to disable the auditor for older browsers and set it to 0.
// The X-XSS-PROTECTION header was found to have a multitude of issues, instead of helping the
// developers protect their application.
w.Header().Add("X-Xss-Protection", "0")
}
h.ServeHTTP(w, r)
})
}
}
type headerKV struct {
key string
value string
}
func buildHelmetHeaders(opt HelmetOption) []headerKV {
var headers []headerKV
add := func(key, value string) {
headers = append(headers, headerKV{key: key, value: value})
}
// Content-Security-Policy
add("Content-Security-Policy", opt.ContentSecurityPolicy.value())
// Cross-Origin-Opener-Policy
if opt.CrossOriginOpenerPolicy == "" {
add("Cross-Origin-Opener-Policy", string(OpenerSameOrigin))
} else {
add("Cross-Origin-Opener-Policy", string(opt.CrossOriginOpenerPolicy))
}
// Cross-Origin-Resource-Policy
if opt.CrossOriginResourcePolicy == "" {
add("Cross-Origin-Resource-Policy", string(ResourceSameOrigin))
} else {
add("Cross-Origin-Resource-Policy", string(opt.CrossOriginResourcePolicy))
}
// Referrer-Policy
if len(opt.ReferrerPolicy) > 0 {
refP := make([]string, len(opt.ReferrerPolicy))
for i, r := range opt.ReferrerPolicy {
refP[i] = string(r)
}
add("Referrer-Policy", strings.Join(refP, ","))
} else {
add("Referrer-Policy", string(NoReferrer))
}
// Origin-Agent-Cluster
if opt.OriginAgentCluster {
add("Origin-Agent-Cluster", "?1")
}
// Strict-Transport-Security
if opt.StrictTransportSecurity != nil {
var sb strings.Builder
maxAge := opt.StrictTransportSecurity.MaxAge
if maxAge == 0 {
maxAge = YearDuration
}
sb.WriteString(fmt.Sprintf("max-age=%d", maxAge))
if opt.StrictTransportSecurity.IncludeSubDomains {
sb.WriteString("; includeSubDomains")
}
if opt.StrictTransportSecurity.Preload {
sb.WriteString("; preload")
}
add("Strict-Transport-Security", sb.String())
}
// X-Content-Type-Options
if !opt.DisableSniffMimeType {
add("X-Content-Type-Options", "nosniff")
}
// X-DNS-Prefetch-Control
if opt.DisableDNSPrefetch {
add("X-DNS-Prefetch-Control", "off")
} else {
add("X-DNS-Prefetch-Control", "on")
}
// X-Download-Options
if !opt.DisableXDownload {
add("X-Download-Options", "noopen")
}
// X-Frame-Options
if opt.XFrameOption == "" {
add("X-Frame-Options", string(XFrameSameOrigin))
} else {
add("X-Frame-Options", string(opt.XFrameOption))
}
// X-Permitted-Cross-Domain-Policies
if opt.CrossDomainPolicies == "" {
add("X-Permitted-Cross-Domain-Policies", string(CDPNone))
} else {
add("X-Permitted-Cross-Domain-Policies", string(opt.CrossDomainPolicies))
}
// X-Xss-Protection
if opt.XssProtection {
add("X-Xss-Protection", "1; mode=block")
} else {
add("X-Xss-Protection", "0")
}
return headers
}
func (csp *CSP) value() string {
var sb strings.Builder

View File

@@ -64,6 +64,10 @@ func init() {
// where "random" is a base62 random string that uniquely identifies this go
// process, and where the last number is an atomically incremented request
// counter.
// maxRequestIDLen is the maximum length of an incoming request ID header
// to prevent log injection or memory abuse from malicious clients.
const maxRequestIDLen = 200
func RequestID(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
@@ -71,6 +75,8 @@ func RequestID(next http.Handler) http.Handler {
if requestID == "" {
myid := reqid.Add(1)
requestID = fmt.Sprintf("%s-%06d", prefix, myid)
} else if len(requestID) > maxRequestIDLen {
requestID = requestID[:maxRequestIDLen]
}
ctx = context.WithValue(ctx, RequestIDKey, requestID)
next.ServeHTTP(w, r.WithContext(ctx))