Skip to content

Commit bd525f8

Browse files
Fixed syslog source panic on invalid or chunked input (trufflesecurity#4366)
* Fixed syslog source panic on invalid or chunked input * update test name
1 parent 9d7c0af commit bd525f8

File tree

3 files changed

+128
-3
lines changed

3 files changed

+128
-3
lines changed

main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ var (
179179
syslogProtocol = syslogScan.Flag("protocol", "Protocol to listen on. udp or tcp").String()
180180
syslogTLSCert = syslogScan.Flag("cert", "Path to TLS cert.").String()
181181
syslogTLSKey = syslogScan.Flag("key", "Path to TLS key.").String()
182-
syslogFormat = syslogScan.Flag("format", "Log format. Can be rfc3164 or rfc5424").String()
182+
syslogFormat = syslogScan.Flag("format", "Log format. Can be rfc3164 or rfc5424").Required().String()
183183

184184
circleCiScan = cli.Command("circleci", "Scan CircleCI")
185185
circleCiScanToken = circleCiScan.Flag("token", "CircleCI token. Can also be provided with environment variable").Envar("CIRCLECI_TOKEN").Required().String()
@@ -451,7 +451,6 @@ func run(state overseer.State) {
451451
// OSS Default APK handling on
452452
feature.EnableAPKHandler.Store(true)
453453

454-
455454
// OSS Default Use Git Mirror on
456455
feature.UseGitMirror.Store(true)
457456

pkg/sources/syslog/syslog.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,11 @@ func (s *Source) monitorConnection(ctx context.Context, conn net.Conn, chunksCha
270270
ctx.Logger().V(5).Info(string(input))
271271
metadata, err := s.parseSyslogMetadata(input, remote.String())
272272
if err != nil {
273-
ctx.Logger().V(2).Info("failed to generate metadata", "error", err)
273+
// set metadata as empty to avoid panics in case parsing failed
274+
metadata = &source_metadatapb.MetaData{}
275+
ctx.Logger().V(2).Error(err, "failed to generate metadata")
274276
}
277+
275278
chunksChan <- &sources.Chunk{
276279
SourceName: s.syslog.sourceName,
277280
SourceID: s.syslog.sourceID,
@@ -317,8 +320,11 @@ func (s *Source) acceptUDPConnections(ctx context.Context, netListener net.Packe
317320
}
318321
metadata, err := s.parseSyslogMetadata(input, remote.String())
319322
if err != nil {
323+
// set metadata as empty to avoid panics in case parsing failed
324+
metadata = &source_metadatapb.MetaData{}
320325
ctx.Logger().V(2).Info("failed to parse metadata", "error", err)
321326
}
327+
322328
chunksChan <- &sources.Chunk{
323329
SourceName: s.syslog.sourceName,
324330
SourceID: s.syslog.sourceID,

pkg/sources/syslog/syslog_test.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package syslog
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"google.golang.org/protobuf/types/known/anypb"
9+
10+
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
11+
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/source_metadatapb"
12+
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/sourcespb"
13+
)
14+
15+
func TestSource_parseSyslogMetadata(t *testing.T) {
16+
type args struct {
17+
format string
18+
input []byte
19+
remote string
20+
}
21+
tests := []struct {
22+
name string
23+
args args
24+
want *source_metadatapb.MetaData
25+
wantErr bool
26+
}{
27+
{
28+
name: "success - rfc5424",
29+
args: args{
30+
format: "rfc5424",
31+
input: []byte("<14>1 2025-08-05T12:00:00Z my-host my-app 1234 ID47 - Test message"),
32+
remote: "127.0.0.1:5140",
33+
},
34+
want: &source_metadatapb.MetaData{
35+
Data: &source_metadatapb.MetaData_Syslog{
36+
Syslog: &source_metadatapb.Syslog{
37+
Hostname: "my-host",
38+
Appname: "my-app",
39+
Procid: "1234",
40+
Timestamp: "2025-08-05 12:00:00 +0000 UTC",
41+
Client: "127.0.0.1:5140",
42+
},
43+
},
44+
},
45+
wantErr: false,
46+
},
47+
{
48+
name: "success - rfc5424",
49+
args: args{
50+
format: "rfc5424",
51+
input: []byte("<34>1 2023-08-05T14:30:22.123Z webserver nginx 1234 access-log - 192.168.1.100 GET /index.html 200"),
52+
remote: "127.0.0.1:5140",
53+
},
54+
want: &source_metadatapb.MetaData{
55+
Data: &source_metadatapb.MetaData_Syslog{
56+
Syslog: &source_metadatapb.Syslog{
57+
Hostname: "webserver",
58+
Appname: "nginx",
59+
Procid: "1234",
60+
Timestamp: "2023-08-05 14:30:22.123 +0000 UTC",
61+
Client: "127.0.0.1:5140",
62+
},
63+
},
64+
},
65+
wantErr: false,
66+
},
67+
{
68+
name: "success - rfc3164",
69+
args: args{
70+
format: "rfc3164",
71+
input: []byte("<34>Oct 11 22:14:15 mymachine su: 'su root' failed for lonvick on /dev/pts/8"),
72+
remote: "127.0.0.1:5140",
73+
},
74+
want: &source_metadatapb.MetaData{
75+
Data: &source_metadatapb.MetaData_Syslog{
76+
Syslog: &source_metadatapb.Syslog{
77+
Hostname: "mymachine",
78+
Timestamp: "2025-10-11 22:14:15 +0000 UTC",
79+
Client: "127.0.0.1:5140",
80+
Facility: "4",
81+
},
82+
},
83+
},
84+
wantErr: false,
85+
},
86+
{
87+
name: "fail - wrong format",
88+
args: args{
89+
format: "rfc5424",
90+
input: []byte("Test message"),
91+
remote: "127.0.0.1:5140",
92+
},
93+
want: nil,
94+
wantErr: true,
95+
},
96+
}
97+
for _, tt := range tests {
98+
t.Run(tt.name, func(t *testing.T) {
99+
s := &Source{}
100+
101+
conn, err := anypb.New(&sourcespb.Syslog{
102+
Format: tt.args.format,
103+
})
104+
assert.NoError(t, err)
105+
106+
err = s.Init(context.Background(), "test", 0, 0, false, conn, 5)
107+
assert.NoError(t, err)
108+
109+
got, err := s.parseSyslogMetadata(tt.args.input, tt.args.remote)
110+
if (err != nil) != tt.wantErr {
111+
t.Errorf("Source.parseSyslogMetadata() error = %v, wantErr %v", err, tt.wantErr)
112+
return
113+
}
114+
115+
if !reflect.DeepEqual(got, tt.want) {
116+
t.Errorf("Source.parseSyslogMetadata() = %v, want %v", got, tt.want)
117+
}
118+
})
119+
}
120+
}

0 commit comments

Comments
 (0)