Ldap Injection in Chi
How Ldap Injection Manifests in Chi
LDAP injection vulnerabilities in Chi applications typically emerge through user-controlled input that gets incorporated into LDAP queries without proper sanitization. In Chi's context, this often occurs when building search filters for directory services, authentication mechanisms, or attribute lookups.
The most common manifestation appears in authentication flows where usernames or search terms are directly concatenated into LDAP filters. Consider a Chi middleware that validates users against an LDAP directory:
func ldapAuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username := r.URL.Query().Get("username")
password := r.URL.Query().Get("password")
// Vulnerable LDAP filter construction
filter := "(&(objectClass=person)(uid=" + username + "))"
// Execute LDAP search...
next.ServeHTTP(w, r)
})
}An attacker could exploit this by submitting a username like john)(&(objectClass=*)(cn=*)), which would transform the filter into:
(&(objectClass=person)(uid=john)(&(objectClass=*)(cn=*)))This modified filter would match any objectClass and return all user records, potentially bypassing authentication entirely.
Another Chi-specific pattern involves route parameters used in LDAP queries. When building APIs that search organizational data stored in LDAP directories, developers might write:
router.Get("/api/departments/:dept", func(w http.ResponseWriter, r *http.Request) {
dept := chi.URLParam(r, "dept")
// Vulnerable: dept directly inserted into filter
filter := "(&(objectClass=organizationalUnit)(ou=" + dept + "))"
// LDAP search execution...
})Here, a department name like Sales)(objectClass=*) would cause the filter to become (&(objectClass=organizationalUnit)(ou=Sales)(objectClass=*)), potentially exposing all organizational units.
Chi's middleware architecture can also introduce LDAP injection risks when multiple layers process user input. A logging middleware might extract attributes from LDAP results and include them in responses without proper validation:
func auditMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Extract user attributes from LDAP
userAttr := getUserAttributeFromLDAP(r.Context(), "memberOf")
// Vulnerable: attribute value directly used
filter := "(&(objectClass=group)(member=" + userAttr + "))"
next.ServeHTTP(w, r)
})
}The vulnerability compounds when Chi applications integrate with LDAP-based authorization systems, where role or group membership checks use unvalidated input to construct queries.
Chi-Specific Detection
Detecting LDAP injection in Chi applications requires examining both the code patterns and runtime behavior. Static analysis should focus on these specific Chi patterns:
Route Parameter Extraction: Search for chi.URLParam, chi.URLParamFromCtx, and query parameter access patterns that feed directly into LDAP operations. Look for code where these values are concatenated without sanitization.
Middleware Chains: Chi's middleware architecture means LDAP injection vulnerabilities can propagate through multiple layers. Analyze middleware that accesses LDAP data and passes it to subsequent handlers without validation.
// Example vulnerable middleware chain
router.Use(authMiddleware)
router.Use(loggingMiddleware)
router.Use(auditMiddleware)
Each middleware in this chain could introduce or propagate LDAP injection vulnerabilities.
Dynamic Filter Construction: Identify patterns where LDAP filters are built using string concatenation rather than parameterized queries. Look for:
- String concatenation with
+operator fmt.Sprintfwith user input- Direct interpolation of variables into filter strings
Runtime Detection with middleBrick: middleBrick's black-box scanning approach is particularly effective for Chi applications because it tests the actual running API without requiring source code access. The scanner examines:
- Authentication endpoints for LDAP injection patterns
- Search/filter endpoints that might query LDAP directories
- Middleware processing chains that handle user input
- API responses that might leak LDAP structure information
middleBrick's LDAP injection checks specifically look for:
- Filter injection patterns: *, (, ), &, |, ! characters
- Authentication bypass attempts
- Directory traversal through LDAP
- Attribute disclosure via injection
The scanner tests these patterns across all 12 security categories, providing Chi developers with immediate feedback on vulnerable endpoints without requiring code changes or redeployment.
Chi-Specific Remediation
Remediating LDAP injection in Chi applications requires a defense-in-depth approach using Go's LDAP libraries and Chi's middleware capabilities. The primary defense is using parameterized LDAP queries rather than string concatenation.
Using ldap3's Filter Escaping: The Go ldap3 library provides proper escaping mechanisms:
import "github.com/go-ldap/ldap/v3"
func safeLdapAuth(w http.ResponseWriter, r *http.Request) {
username := r.URL.Query().Get("username")
password := r.URL.Query().Get("password")
// Properly escape LDAP filter components
escapedUsername := ldap.EscapeFilter(username)
// Use parameterized filter construction
filter := ldap.NewFilter().And(
ldap.NewFilter().Equal("objectClass", "person"),
ldap.NewFilter().Equal("uid", escapedUsername),
)
// Execute LDAP search with safe filter
searchRequest := ldap.NewSearchRequest(
"dc=example,dc=com",
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
filter.String(),
[]string{"dn", "cn", "mail"},
nil,
)
// LDAP connection and search execution...
}Chi Middleware for Input Validation: Create reusable middleware that validates and sanitizes LDAP input before it reaches handlers:
func ldapInputValidation(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Validate and sanitize all query parameters
params := r.URL.Query()
for key, values := range params {
for i, val := range values {
// Basic LDAP injection prevention
sanitized := ldap.EscapeFilter(val)
params[key][i] = sanitized
}
}
// Rebuild request with sanitized parameters
r.URL.RawQuery = params.Encode()
next.ServeHTTP(w, r)
})
}
// Apply middleware to specific routes
router.With(ldapInputValidation).Get("/api/search", searchHandler)Context-Based LDAP Operations: Use Chi's context capabilities to pass sanitized LDAP parameters through middleware chains:
func ldapContextMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Extract and sanitize parameters
username := ldap.EscapeFilter(r.URL.Query().Get("username"))
// Store in context for downstream handlers
ctx := context.WithValue(r.Context(), "sanitizedUsername", username)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
// Handler retrieves sanitized value from context
func searchHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
username := ctx.Value("sanitizedUsername").(string)
// Safe to use in LDAP query
filter := ldap.NewFilter().Equal("uid", username)
}Testing LDAP Injection Prevention: After implementing fixes, verify protection using middleBrick's continuous monitoring. The Pro plan's scheduled scanning will automatically retest your API endpoints, ensuring that LDAP injection vulnerabilities remain closed as your codebase evolves.
middleBrick's findings include specific remediation guidance for each detected issue, mapping to OWASP API Security Top 10 recommendations and providing exact code examples for Chi applications.