A comprehensive security-focused Go SDK providing secure-by-default implementations for common operations that are prone to security vulnerabilities. This project is designed to be a one-stop-shop for security features and libraries for Go developers.
The Go Secure SDK is part of Datadog's commitment to secure software development. It provides a set of libraries to mitigate common security issues and vulnerabilities across various domains including compression, cryptography, I/O operations, networking, and filesystem operations.
- π Secure by Default: All components implement security best practices out of the box
- π‘οΈ Attack Prevention: Built-in protection against common attacks (zip-slip, SSRF, path traversal, etc.)
- β‘ Production Ready: Battle-tested code used in Datadog's production environments
- π¦ Modular Design: Use only the packages you need
- π§ͺ Well Tested: Comprehensive test coverage with security-focused test cases
- π Well Documented: Extensive documentation and examples for every package
go get github.com/DataDog/go-secure-sdk- Go 1.24.0 or higher
Secure TAR archive creation and extraction with protection against:
- Zip-slip attacks
- Path traversal attacks
- Archive bombs (size/count limits)
- Symbolic link recursion attacks
import "github.com/DataDog/go-secure-sdk/compression/archive/tar"
// Extract with security controls
err := tar.Extract(reader, "/safe/output/path",
tar.WithMaxArchiveSize(100 << 20), // 100MB max
tar.WithMaxEntryCount(10000), // Max 10k files
tar.WithMaxFileSize(10 << 20), // 10MB per file
)Hardened ZIP archive operations with similar security controls as TAR.
import "github.com/DataDog/go-secure-sdk/compression/archive/zip"
// Create with compression control
err := zip.Create(fileSystem, writer,
zip.WithCompressionLevel(flate.DefaultCompression),
zip.WithExcludeFilter(func(path string, fi fs.FileInfo) bool {
return strings.HasSuffix(path, ".zip")
}),
)Secure cryptographic hash functions with support for multiple algorithms in a single pass.
import "github.com/DataDog/go-secure-sdk/crypto/hashutil"
// Compute multiple hashes in one read
hashes, err := hashutil.FileHashes(root, "file.bin",
crypto.SHA256,
crypto.SHA384,
crypto.SHA512,
)Comprehensive cryptographic key management supporting multiple formats and operations.
import "github.com/DataDog/go-secure-sdk/crypto/keyutil"
// Generate key pair
pub, priv, err := keyutil.GenerateKeyPair(keyutil.EC)
// Convert to JWK
jwk, err := keyutil.ToJWK(priv)
// Encrypt JWK with password
encrypted, err := keyutil.ToEncryptedJWK(jwk, []byte("password"))Cryptographically secure random generation with math/rand compatible API.
import "github.com/DataDog/go-secure-sdk/generator/randomness"
// Drop-in replacement for math/rand with crypto/rand backing
randomNumber := randomness.Intn(100)
// Generate secure tokens
token, err := randomness.Alphanumeric(32)
verificationCode, err := randomness.VerificationCode(6)Hardened I/O operations with size limits and timeouts.
import "github.com/DataDog/go-secure-sdk/ioutil"
// Copy with size limit (prevents decompression bombs)
size, err := ioutil.LimitCopy(dst, src, 10 << 20) // Max 10MB
// Reader with timeout protection
timeoutReader := ioutil.TimeoutReader(slowReader, 5*time.Second)SSRF-safe HTTP client implementation with request/response filtering.
import "github.com/DataDog/go-secure-sdk/net/httpclient"
// Safe client blocks dangerous requests
client := httpclient.Safe()
// This will be blocked (metadata service)
resp, err := client.Get("http://169.254.169.254/")
// Error: address is link local unicast
// Customize with options
client = httpclient.Safe(
httpclient.WithTimeout(30*time.Second),
httpclient.WithFollowRedirect(true),
)TLS dialer with certificate pinning support.
import "github.com/DataDog/go-secure-sdk/net/tlsclient"
// Pin to specific certificate fingerprint
dialer := tlsclient.PinnedDialer(tlsConfig, fingerprint)
client := httpclient.Safe(
httpclient.WithTLSDialer(dialer),
)Virtual filesystem with security constraints preventing path traversal.
import "github.com/DataDog/go-secure-sdk/vfs"
// Create chrooted filesystem
fs, err := vfs.Chroot("/safe/base/path")
// Path traversal attempts are blocked
err = fs.Mkdir("../../../etc", 0755)
// Returns: ConstraintError
// Confirmed directories
tmpDir, err := vfs.NewTmpConfirmedDir()
safePath := tmpDir.Join("subdir/file.txt")This SDK is designed to help you follow security best practices:
- Input Validation: Always validate and sanitize user inputs before processing
- Size Limits: Use the built-in size limits to prevent resource exhaustion
- Timeouts: Apply reasonable timeouts to prevent hanging operations
- Least Privilege: Use chrooted filesystems and network restrictions
- Defense in Depth: Combine multiple security layers
// Extract user-uploaded archive safely
func extractUpload(uploadPath, destPath string) error {
f, err := os.Open(uploadPath)
if err != nil {
return err
}
defer f.Close()
// Create chrooted extraction directory
fs, err := vfs.Chroot(destPath)
if err != nil {
return err
}
// Extract with all safety checks
return tar.Extract(
io.LimitReader(f, 100<<20), // Max 100MB
fs.Root(),
tar.WithMaxEntryCount(1000),
tar.WithMaxFileSize(10<<20),
)
}// Fetch URL from user input safely
func fetchURL(userURL string) ([]byte, error) {
client := httpclient.Safe(
httpclient.WithTimeout(10*time.Second),
)
resp, err := client.Get(userURL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
// Read with size limit
return io.ReadAll(io.LimitReader(resp.Body, 1<<20))
}// Verify file integrity with multiple algorithms
func verifyFile(path string, expected map[crypto.Hash]string) error {
root := os.DirFS(filepath.Dir(path))
name := filepath.Base(path)
hashes, err := hashutil.FileHashes(root, name,
crypto.SHA256,
crypto.SHA512,
)
if err != nil {
return err
}
for algo, hash := range hashes {
if hex.EncodeToString(hash) != expected[algo] {
return fmt.Errorf("hash mismatch for %s", algo)
}
}
return nil
}Run the test suite:
go test ./...Run tests with race detection:
go test -race ./...Run tests with coverage:
go test -cover ./...We welcome contributions! Please see our contributing guidelines for more details.
Before submitting a pull request:
- Ensure all tests pass
- Add tests for new functionality
- Update documentation as needed
- Follow the existing code style
- Write clear commit messages
Security is our top priority. If you discover a security vulnerability, please follow our Security Policy.
Please DO NOT file a public issue. Instead, send your report privately to [email protected]
We greatly appreciate security reports and will publicly thank you for it (with your permission).
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Copyright 2024-present Datadog, Inc.
This SDK is developed and maintained by Datadog to support our open-source projects and is made available to the broader Go community.
- DataDog/datadog-agent - Datadog Agent
- DataDog/go-libddwaf - Go bindings for libddwaf
- π Documentation
- π Issue Tracker
- π¬ Discussions
Built with β€οΈ by Datadog