shadow1ng/fscan · error
credential contains line break
Error message
credential contains line break
What it means
A defensive injection guard: text-protocol credentials (STOMP, IMAP-adjacent login helpers) are scanned for CR/LF and rejected because a line break would let an attacker inject extra protocol commands (CRLF injection). rejectLineBreaks returns this plain (non-i18n) error if any supplied value contains \r or \n.
Source
Thrown at plugins/services/text_protocol.go:18
//go:build !plugin_selective || plugin_activemq || plugin_imap || plugin_pop3 || plugin_redis
package services
import (
"fmt"
"strconv"
"strings"
)
func hasLineBreak(s string) bool {
return strings.ContainsAny(s, "\r\n")
}
func rejectLineBreaks(values ...string) error {
for _, value := range values {
if hasLineBreak(value) {
return fmt.Errorf("credential contains line break")
}
}
return nil
}
func imapQuotedString(s string) (string, error) {
if hasLineBreak(s) {
return "", fmt.Errorf("imap credential contains line break")
}
return strconv.Quote(s), nil
}
func buildIMAPLoginCommand(tag, username, password string) (string, error) {
quotedUser, err := imapQuotedString(username)
if err != nil {
return "", err
}
quotedPass, err := imapQuotedString(password)View on GitHub (pinned to 95cc12e753)
Solutions
- Trim CR/LF from credential values before calling the authenticate functions.
- Validate credentials at load time and reject any containing line breaks.
- Fix the source (config parser/file reader) so values are read without trailing newlines.
- Keep the guard in place — do not bypass it, since it prevents protocol injection.
Example fix
// before
password := strings.TrimSpace(string(data)) // may still embed internal \n
err := tryLogin(conn, user, password)
// after
if strings.ContainsAny(password, "\r\n") {
return fmt.Errorf("credential contains line break")
}
err := tryLogin(conn, user, password) Defensive patterns
Strategy: validation
Validate before calling
if strings.ContainsAny(username, "\r\n") || strings.ContainsAny(password, "\r\n") {
return errors.New("credential contains line break")
} Type guard
func safeCredential(s string) bool { return s != "" && !strings.ContainsAny(s, "\r\n") } Try / catch
if err := rejectLineBreaks(user, pass); err != nil {
// sanitize or reject the credential before sending to the protocol
} Prevention
- Trim credentials read from files/configs
- Validate credentials at load time, before use
- Never pass raw user input into protocol login helpers
- Keep injection guards enabled in production paths
When it happens
Trigger: Calling authenticateSTOMP or tryLogin with a username or password containing '\n' or '\r', typically from untrusted input such as a config file, environment variable, or scan target list.
Common situations: Credentials read from files without trimming trailing newlines (e.g. password read via scanner including '\n'); YAML/JSON configs with embedded newlines; intentionally malicious inputs during testing.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- imap credential contains line break
- result cannot be nil
- result cannot be nil
- output file not specified
- invalid output format: %s
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/2cf4e1d6d9c125c1.
Report an issue: GitHub.