mirror of
https://github.com/nabbar/golib.git
synced 2025-12-24 11:51:02 +08:00
- ADD flag to register temp file creation
- ADD function to check flag is temp
[ static ]
- FIX bugs & race detection
- UPDATE code: refactor & optimize code, improve security &
preformances
- ADD Path Security: add options & code to improve security
- ADD Rate Limiting: add option to limit capabilities of burst request
- ADD HTTP Security Headers: add option to customize header, improve
security & allow cache crontol
- ADD Suspicious Access Detection: add option to identify & log
suspicious request
- ADD Security Backend Integration: add option to plug WAF/IDF/EDR
backend (with CEF Format or not)
- ADD documentation: add enhanced README and TESTING guidelines
- ADD tests: complete test suites with benchmarks, concurrency, and edge cases
354 lines
12 KiB
Go
354 lines
12 KiB
Go
/*
|
|
* MIT License
|
|
*
|
|
* Copyright (c) 2022 Nicolas JUHEL
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
package static
|
|
|
|
import "time"
|
|
|
|
// HeadersConfig configures HTTP headers for caching and content-type validation.
|
|
//
|
|
// This configuration allows fine-grained control over:
|
|
// - HTTP caching (Cache-Control, Expires, ETag)
|
|
// - Content-Type detection and validation
|
|
// - MIME type whitelisting/blacklisting
|
|
type HeadersConfig struct {
|
|
// EnableCacheControl activates HTTP cache control headers
|
|
EnableCacheControl bool
|
|
|
|
// CacheMaxAge is the cache duration in seconds (e.g., 3600 = 1 hour)
|
|
CacheMaxAge int
|
|
|
|
// CachePublic when true, cache is public (CDN), otherwise private (browser only)
|
|
CachePublic bool
|
|
|
|
// EnableETag activates ETag generation for cache validation
|
|
EnableETag bool
|
|
|
|
// EnableContentType activates Content-Type detection and validation
|
|
EnableContentType bool
|
|
|
|
// AllowedMimeTypes is a list of allowed MIME types (empty = all allowed)
|
|
AllowedMimeTypes []string
|
|
|
|
// DenyMimeTypes is a list of forbidden MIME types
|
|
DenyMimeTypes []string
|
|
|
|
// CustomMimeTypes overrides MIME detection (extension -> mime-type mapping)
|
|
CustomMimeTypes map[string]string
|
|
}
|
|
|
|
// SecurityEventType represents the type of security event that occurred.
|
|
// It is used to categorize security incidents for monitoring and analysis.
|
|
type SecurityEventType string
|
|
|
|
const (
|
|
// EventTypePathTraversal indicates an attempt to access files outside the allowed directory
|
|
EventTypePathTraversal SecurityEventType = "path_traversal"
|
|
|
|
// EventTypeRateLimit indicates that an IP exceeded the allowed request rate
|
|
EventTypeRateLimit SecurityEventType = "rate_limit_exceeded"
|
|
|
|
// EventTypeSuspiciousAccess indicates suspicious file access patterns
|
|
EventTypeSuspiciousAccess SecurityEventType = "suspicious_access"
|
|
|
|
// EventTypeMimeTypeDenied indicates an attempt to access a file with a blocked MIME type
|
|
EventTypeMimeTypeDenied SecurityEventType = "mime_type_denied"
|
|
|
|
// EventTypeDotFileAccess indicates an attempt to access hidden files (starting with .)
|
|
EventTypeDotFileAccess SecurityEventType = "dot_file_access"
|
|
|
|
// EventTypePatternBlocked indicates an attempt to access a path matching a blocked pattern
|
|
EventTypePatternBlocked SecurityEventType = "pattern_blocked"
|
|
|
|
// EventTypePathDepth indicates a path exceeding the maximum allowed depth
|
|
EventTypePathDepth SecurityEventType = "path_depth_exceeded"
|
|
)
|
|
|
|
// SecuEvtCallback is a callback function to process security events.
|
|
// It receives security events and can be used for custom handling, logging,
|
|
// or integration with external monitoring systems.
|
|
// The event parameter is of private type secEvt which contains detailed
|
|
// information about the security incident.
|
|
type SecuEvtCallback func(event secEvt)
|
|
|
|
// SecurityConfig configures the integration with WAF (Web Application Firewall),
|
|
// IDS (Intrusion Detection System), or EDR (Endpoint Detection and Response) systems.
|
|
//
|
|
// This configuration allows the static file handler to report security events to
|
|
// external systems via webhooks or callbacks. Events can be sent individually or
|
|
// batched for efficiency.
|
|
//
|
|
// Example usage:
|
|
//
|
|
// handler.SetSecurityBackend(static.SecurityConfig{
|
|
// Enabled: true,
|
|
// WebhookURL: "https://waf.example.com/events",
|
|
// WebhookHeaders: map[string]string{"Authorization": "Bearer token"},
|
|
// WebhookAsync: true,
|
|
// MinSeverity: "medium",
|
|
// BatchSize: 100,
|
|
// BatchTimeout: 30 * time.Second,
|
|
// })
|
|
type SecurityConfig struct {
|
|
// Enabled activates the security integration
|
|
Enabled bool
|
|
|
|
// WebhookURL is the URL to send security events to (WAF/SIEM/IDS endpoint)
|
|
WebhookURL string
|
|
|
|
// WebhookTimeout is the timeout for webhook HTTP requests
|
|
WebhookTimeout time.Duration
|
|
|
|
// WebhookHeaders are custom HTTP headers to include in webhook requests (e.g., Authorization)
|
|
WebhookHeaders map[string]string
|
|
|
|
// WebhookAsync when true, sends webhooks asynchronously (non-blocking)
|
|
WebhookAsync bool
|
|
|
|
// Callbacks is a list of Go callback functions for custom event processing
|
|
Callbacks []SecuEvtCallback
|
|
|
|
// MinSeverity is the minimum severity level to notify (low, medium, high, critical)
|
|
MinSeverity string
|
|
|
|
// BatchSize is the number of events to accumulate before sending a batch (0 = real-time)
|
|
BatchSize int
|
|
|
|
// BatchTimeout is the maximum duration before sending an incomplete batch
|
|
BatchTimeout time.Duration
|
|
|
|
// EnableCEFFormat enables CEF (Common Event Format) for SIEM compatibility
|
|
// See: https://www.microfocus.com/documentation/arcsight/arcsight-smartconnectors/
|
|
EnableCEFFormat bool
|
|
}
|
|
|
|
// PathSecurityConfig configures path validation and security rules.
|
|
//
|
|
// This configuration protects against various path-based attacks including
|
|
// path traversal, dot file access, and access to sensitive directories.
|
|
type PathSecurityConfig struct {
|
|
// Enabled activates or deactivates strict path validation
|
|
Enabled bool
|
|
|
|
// AllowDotFiles permits access to files starting with "." (default: false)
|
|
// When false, blocks access to .env, .git, .htaccess, etc.
|
|
AllowDotFiles bool
|
|
|
|
// MaxPathDepth is the maximum allowed path depth (0 = unlimited)
|
|
MaxPathDepth int
|
|
|
|
// BlockedPatterns are path patterns to block (e.g., []string{"wp-admin", ".git"})
|
|
BlockedPatterns []string
|
|
}
|
|
|
|
// RateLimitConfig configures IP-based rate limiting to prevent scraping and DoS attacks.
|
|
//
|
|
// The rate limiting tracks unique file paths requested per IP address within a time window.
|
|
// This helps protect against malicious clients that attempt to enumerate or download
|
|
// all files from the static file handler.
|
|
//
|
|
// Example usage:
|
|
//
|
|
// handler.SetRateLimit(static.RateLimitConfig{
|
|
// Enabled: true,
|
|
// MaxRequests: 100,
|
|
// Window: time.Minute,
|
|
// CleanupInterval: 5 * time.Minute,
|
|
// WhitelistIPs: []string{"127.0.0.1", "::1"},
|
|
// })
|
|
//
|
|
// The rate limiting is thread-safe and uses atomic operations without mutexes.
|
|
type RateLimitConfig struct {
|
|
// Enabled activates or deactivates rate limiting
|
|
Enabled bool
|
|
|
|
// MaxRequests is the maximum number of different files allowed per IP
|
|
MaxRequests int
|
|
|
|
// Window is the time duration for rate counting (e.g., 1 minute)
|
|
Window time.Duration
|
|
|
|
// CleanupInterval is the interval for automatic cache cleanup (e.g., 5 minutes)
|
|
CleanupInterval time.Duration
|
|
|
|
// WhitelistIPs is a list of IP addresses exempt from rate limiting (e.g., ["127.0.0.1", "::1"])
|
|
WhitelistIPs []string
|
|
|
|
// TrustedProxies is a list of trusted proxy IPs to extract real client IP
|
|
TrustedProxies []string
|
|
}
|
|
|
|
// SuspiciousConfig configures the detection and logging of suspicious file access patterns.
|
|
//
|
|
// This feature helps identify potential security threats by monitoring access to
|
|
// files that are commonly targeted in attacks (e.g., .env files, backup files,
|
|
// configuration files).
|
|
//
|
|
// Example usage:
|
|
//
|
|
// handler.SetSuspicious(static.SuspiciousConfig{
|
|
// Enabled: true,
|
|
// LogSuccessfulAccess: true,
|
|
// SuspiciousPatterns: []string{".env", ".git", "wp-admin"},
|
|
// SuspiciousExtensions: []string{".php", ".exe"},
|
|
// })
|
|
type SuspiciousConfig struct {
|
|
// Enabled activates or deactivates suspicious access detection
|
|
Enabled bool
|
|
|
|
// LogSuccessfulAccess also logs suspicious accesses that succeed (200 OK)
|
|
LogSuccessfulAccess bool
|
|
|
|
// SuspiciousPatterns are path patterns considered suspicious
|
|
SuspiciousPatterns []string
|
|
|
|
// SuspiciousExtensions are file extensions considered suspicious
|
|
SuspiciousExtensions []string
|
|
}
|
|
|
|
// DefaultHeadersConfig returns a default HTTP headers configuration.
|
|
//
|
|
// Default values:
|
|
// - EnableCacheControl: true
|
|
// - CacheMaxAge: 3600 seconds (1 hour)
|
|
// - CachePublic: true (allows CDN caching)
|
|
// - EnableETag: true
|
|
// - EnableContentType: true
|
|
// - AllowedMimeTypes: empty (all allowed by default)
|
|
// - DenyMimeTypes: executable types blocked
|
|
// - CustomMimeTypes: includes wasm and webp
|
|
func DefaultHeadersConfig() HeadersConfig {
|
|
return HeadersConfig{
|
|
EnableCacheControl: true,
|
|
CacheMaxAge: 3600, // 1 hour
|
|
CachePublic: true,
|
|
EnableETag: true,
|
|
EnableContentType: true,
|
|
AllowedMimeTypes: []string{}, // All allowed by default
|
|
DenyMimeTypes: []string{
|
|
"application/x-executable",
|
|
"application/x-msdownload",
|
|
"application/x-sh",
|
|
},
|
|
CustomMimeTypes: map[string]string{
|
|
".wasm": "application/wasm",
|
|
".webp": "image/webp",
|
|
},
|
|
}
|
|
}
|
|
|
|
// DefaultSecurityConfig returns a default security backend configuration.
|
|
//
|
|
// Default values:
|
|
// - Enabled: false (must be explicitly enabled)
|
|
// - WebhookTimeout: 5 seconds
|
|
// - WebhookAsync: true (non-blocking)
|
|
// - MinSeverity: "medium"
|
|
// - BatchSize: 0 (real-time, no batching)
|
|
// - BatchTimeout: 30 seconds
|
|
// - EnableCEFFormat: false (JSON format)
|
|
func DefaultSecurityConfig() SecurityConfig {
|
|
return SecurityConfig{
|
|
Enabled: false, // Disabled by default
|
|
WebhookTimeout: 5 * time.Second,
|
|
WebhookAsync: true,
|
|
MinSeverity: "medium",
|
|
BatchSize: 0, // Real-time by default
|
|
BatchTimeout: 30 * time.Second,
|
|
EnableCEFFormat: false,
|
|
}
|
|
}
|
|
|
|
// DefaultRateLimitConfig returns a secure default rate limiting configuration.
|
|
//
|
|
// Default values:
|
|
// - Enabled: true
|
|
// - MaxRequests: 100 unique files per window
|
|
// - Window: 1 minute
|
|
// - CleanupInterval: 5 minutes
|
|
// - WhitelistIPs: localhost (IPv4 and IPv6)
|
|
// - TrustedProxies: empty
|
|
func DefaultRateLimitConfig() RateLimitConfig {
|
|
return RateLimitConfig{
|
|
Enabled: true,
|
|
MaxRequests: 100,
|
|
Window: 1 * time.Minute,
|
|
CleanupInterval: 5 * time.Minute,
|
|
WhitelistIPs: []string{"127.0.0.1", "::1"},
|
|
TrustedProxies: []string{},
|
|
}
|
|
}
|
|
|
|
// DefaultPathSecurityConfig returns a secure default path security configuration.
|
|
//
|
|
// Default values:
|
|
// - Enabled: true
|
|
// - AllowDotFiles: false (blocks .env, .git, etc.)
|
|
// - MaxPathDepth: 10
|
|
// - BlockedPatterns: [".git", ".svn", ".env", "node_modules"]
|
|
func DefaultPathSecurityConfig() PathSecurityConfig {
|
|
return PathSecurityConfig{
|
|
Enabled: true,
|
|
AllowDotFiles: false,
|
|
MaxPathDepth: 10,
|
|
BlockedPatterns: []string{".git", ".svn", ".env", "node_modules"},
|
|
}
|
|
}
|
|
|
|
// DefaultSuspiciousConfig returns a default suspicious access detection configuration.
|
|
//
|
|
// Default patterns include:
|
|
// - Configuration files (.env, .git, wp-config, etc.)
|
|
// - Backup files (.bak, .old, .swp, etc.)
|
|
// - Admin panels (wp-admin, phpmyadmin, etc.)
|
|
// - Sensitive paths (etc/passwd, windows/system32)
|
|
// - Database files (.sql, .db)
|
|
// - Executable extensions (.php, .exe, .sh)
|
|
func DefaultSuspiciousConfig() SuspiciousConfig {
|
|
return SuspiciousConfig{
|
|
Enabled: true,
|
|
LogSuccessfulAccess: true,
|
|
SuspiciousPatterns: []string{
|
|
// Configuration files
|
|
".env", ".git", ".svn", ".htaccess", ".htpasswd",
|
|
"web.config", "config.php", "wp-config",
|
|
// Backup files
|
|
".bak", ".backup", ".old", ".orig", ".save", ".swp",
|
|
// Admin panels
|
|
"admin", "wp-admin", "administrator", "phpmyadmin",
|
|
// Sensitive paths
|
|
"etc/passwd", "etc/shadow", "windows/system32",
|
|
// Database
|
|
".sql", ".db", ".sqlite",
|
|
// Archives that might contain source
|
|
".tar.gz", ".zip",
|
|
},
|
|
SuspiciousExtensions: []string{
|
|
".php", ".asp", ".aspx", ".jsp", ".cgi",
|
|
".exe", ".sh", ".bat", ".cmd",
|
|
},
|
|
}
|
|
}
|