Graylog2 / Graylog2/graylog2-server
Syslog TCP input strips all backslashes from RFC 5424 structured data instead of unescaping properly
- Dominant language
- Java
- Stars
- 8.1k
- Forks
- 1.1k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 217
Description
## Summary
The Syslog TCP input incorrectly handles backslash escaping in RFC 5424 structured data PARAM-VALUEs. All backslashes are stripped entirely instead of being properly unescaped according to the RFC 5424 specification. This causes data loss — for example, Windows-style paths like `DOMAIN\\user` become `DOMAINuser`.
## Root Cause
The `unescape` method in the [syslog4j-graylog2](https://github.com/graylog-labs/syslog4j-graylog2) library at [`StructuredSyslogMessage.java` line 348](https://github.com/graylog-labs/syslog4j-graylog2/blob/49a861030c40374f5e2dd47579fdc28c3bb2beee/src/main/java/org/graylog2/syslog4j/impl/message/structured/StructuredSyslogMessage.java#L348) simply removes every backslash character:
```java
private String unescape(final String str)
{
if (str.indexOf('\\') == -1) {
return str;
}
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '\\') {
continue;
}
sb.append(str.charAt(i));
}
return sb.toString();
}
```
This is incorrect. Instead, the method should interpret backslashes as escape characters and unescape properly.
Note that the existing test coverage for `\"` and `\]` passes **by coincidence** — stripping the backslash happens to leave the correct character behind. The bug only becomes visible with escaped backslashes (`\\`) and invalid escape sequences, which have no test coverage.
## Expected Behavior (per RFC 5424)
[RFC 5424 Section 6.3.3](https://www.rfc-editor.org/rfc/rfc5424#section-6.3.3) specifies that the characters `"`, `\`, and `]` MUST be escaped within PARAM-VALUEs:
> ```
> PARAM-VALUE = UTF-8-STRING ; characters '"', '\' and
> ; ']' MUST be escaped.
> ```
The correct unescaping behavior should be:
| Input (raw PARAM-VALUE) | Current (buggy) output | Correct output |
|--------------------------|----------------------|----------------|
| `\\` (escaped backslash) | *(empty string)* | `\` |
| `\\\\` (two escaped backslashes) | *(empty string)* | `\\` |
| `\"` (escaped quote) | `"` | `"` (correct by accident) |
| `\]` (escaped bracket) | `]` | `]` (correct by accident) |
| `\n` (invalid escape sequence) | `n` | `\n` (preserve both) |
## Tolerant Behavior Consideration
Beyond strict RFC compliance, we should consider tolerant handling of single or uneven backslashes. Real-world syslog producers may not perfectly escape backslashes (e.g., sending a literal `DOMAIN\user` without escaping the backslash). In such cases, stripping the backslash causes silent data corruption. A tolerant parser should preserve backslashes that are not part of a recognized escape sequence (`\"`, `\\`, `\]`), aligning with the RFC's own guidance on invalid escape sequences: a backslash followed by none of the three special characters is considered an invalid escape sequence and both characters MUST be preserved as-is.
## Steps to Reproduce
1. Send an RFC 5424 syslog message via TCP to a Graylog Syslog TCP input
2. Include structured data with escaped backslashes in a PARAM-VALUE, e.g., a Windows path like `ParentProcessName="C:\\Windows\\System32\\cmd.exe"` or a user account like `UserAccount="DOMAIN\\user"`
3. Observe that all backslashes are stripped from the parsed values (e.g., `CWindowsSystem32cmd.exe`, `DOMAINuser`)
## Expected Result
Escaped backslashes should be unescaped to single backslashes (e.g., `C:\Windows\System32\cmd.exe`, `DOMAIN\user`).
## References
- Affected library: https://github.com/graylog-labs/syslog4j-graylog2
- Affected code: [`StructuredSyslogMessage.java#L348`](https://github.com/graylog-labs/syslog4j-graylog2/blob/49a861030c40374f5e2dd47579fdc28c3bb2beee/src/main/java/org/graylog2/syslog4j/impl/message/structured/StructuredSyslogMessage.java#L348)
- RFC 5424: https://www.rfc-editor.org/rfc/rfc5424#section-6.3.3
Contributor guide
Assessment
This issue has not been assessed yet.