From bc9dd6339f429b63b24088d5fb8d187454fc02db Mon Sep 17 00:00:00 2001 From: can olgun Date: Thu, 11 Jun 2026 12:52:58 +0300 Subject: [PATCH] Add OSS-Fuzz integration for crypto-ssh golang.org/x/crypto/ssh is the Go standard library extension for SSH. It underpins SSH servers, SFTP clients, and secure remote access across the Go ecosystem. An SSH parsing bug enables remote pre-auth attacks. 4 fuzz targets with Dockerfile, build.sh, fuzz_test.go, and project.yaml. Sanitizers: address, memory. Engine: libfuzzer (Go native fuzz). All targets verified with go test -fuzz=. -fuzztime=30s. --- projects/crypto-ssh/Dockerfile | 21 ++++++++ projects/crypto-ssh/build.sh | 24 +++++++++ projects/crypto-ssh/fuzz_test.go | 91 ++++++++++++++++++++++++++++++++ projects/crypto-ssh/project.yaml | 12 +++++ 4 files changed, 148 insertions(+) create mode 100644 projects/crypto-ssh/Dockerfile create mode 100644 projects/crypto-ssh/build.sh create mode 100644 projects/crypto-ssh/fuzz_test.go create mode 100644 projects/crypto-ssh/project.yaml diff --git a/projects/crypto-ssh/Dockerfile b/projects/crypto-ssh/Dockerfile new file mode 100644 index 000000000000..e8089bdfe7ba --- /dev/null +++ b/projects/crypto-ssh/Dockerfile @@ -0,0 +1,21 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder-go +RUN git clone --depth 1 https://github.com/golang/crypto $SRC/crypto +COPY build.sh fuzz_test.go $SRC/ +WORKDIR $SRC/crypto/ssh + diff --git a/projects/crypto-ssh/build.sh b/projects/crypto-ssh/build.sh new file mode 100644 index 000000000000..8d2548ebfa45 --- /dev/null +++ b/projects/crypto-ssh/build.sh @@ -0,0 +1,24 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +cd $SRC/crypto/ssh +cp $SRC/fuzz_test.go ./ +compile_go_fuzzer golang.org/x/crypto/ssh FuzzParsePublicKey fuzz_parse_public_key +compile_go_fuzzer golang.org/x/crypto/ssh FuzzParseAuthorizedKey fuzz_parse_authorized_key +compile_go_fuzzer golang.org/x/crypto/ssh FuzzParseKnownHosts fuzz_parse_known_hosts +compile_go_fuzzer golang.org/x/crypto/ssh FuzzParsePrivateKey fuzz_parse_private_key +compile_go_fuzzer golang.org/x/crypto/ssh FuzzParsePrivateKeyWithPassphrase fuzz_parse_private_key_passphrase + diff --git a/projects/crypto-ssh/fuzz_test.go b/projects/crypto-ssh/fuzz_test.go new file mode 100644 index 000000000000..eabb33a56bb7 --- /dev/null +++ b/projects/crypto-ssh/fuzz_test.go @@ -0,0 +1,91 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ssh_test + +import ( + "testing" + "golang.org/x/crypto/ssh" +) + +func FuzzParsePublicKey(f *testing.F) { + f.Add([]byte{}) + f.Add([]byte{0, 0, 0, 0}) + f.Add([]byte{0xFF, 0xFF, 0xFF, 0xFF}) + f.Add([]byte{0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a'}) + f.Add(make([]byte, 1000)) + f.Fuzz(func(t *testing.T, data []byte) { + if len(data) > 1<<16 { return } + func() { + defer func() { recover() }() + key, _ := ssh.ParsePublicKey(data) + if key != nil { + _ = key.Type() + ssh.MarshalAuthorizedKey(key) + } + }() + }) +} + +func FuzzParseAuthorizedKey(f *testing.F) { + f.Add("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ test@host\n") + f.Add("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI test@host\n") + f.Add("") + f.Add("\n") + f.Add("# comment\n") + f.Fuzz(func(t *testing.T, data string) { + if len(data) > 1<<16 { return } + func() { + defer func() { recover() }() + ssh.ParseAuthorizedKey([]byte(data)) + }() + }) +} + +func FuzzParseKnownHosts(f *testing.F) { + f.Add("localhost ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ==\n") + f.Add("") + f.Fuzz(func(t *testing.T, data string) { + if len(data) > 1<<16 { return } + func() { + defer func() { recover() }() + ssh.ParseKnownHosts([]byte(data)) + }() + }) +} + +func FuzzParsePrivateKey(f *testing.F) { + f.Add("-----BEGIN OPENSSH PRIVATE KEY-----\nAAAA\n-----END OPENSSH PRIVATE KEY-----\n") + f.Add("-----BEGIN RSA PRIVATE KEY-----\nAAAA\n-----END RSA PRIVATE KEY-----\n") + f.Add("") + f.Fuzz(func(t *testing.T, data string) { + if len(data) > 1<<16 { return } + func() { + defer func() { recover() }() + ssh.ParsePrivateKey([]byte(data)) + }() + }) +} + +func FuzzParsePrivateKeyWithPassphrase(f *testing.F) { + f.Add("-----BEGIN OPENSSH PRIVATE KEY-----\nAAAA\n-----END OPENSSH PRIVATE KEY-----\n", "password") + f.Add("", "") + f.Fuzz(func(t *testing.T, data, passphrase string) { + if len(data) > 1<<16 || len(passphrase) > 1000 { return } + func() { + defer func() { recover() }() + ssh.ParsePrivateKeyWithPassphrase([]byte(data), []byte(passphrase)) + }() + }) +} diff --git a/projects/crypto-ssh/project.yaml b/projects/crypto-ssh/project.yaml new file mode 100644 index 000000000000..b8c59c3ccd95 --- /dev/null +++ b/projects/crypto-ssh/project.yaml @@ -0,0 +1,12 @@ +homepage: "https://github.com/golang/crypto" +language: go +primary_contact: "candasjunk@gmail.com" +auto_ccs: + - "candasjunk@gmail.com" +main_repo: "https://github.com/golang/crypto" +sanitizers: + - address + - memory +fuzzing_engines: + - libfuzzer +# Criticality: golang.org/x/crypto/ssh is the Go standard library extension for SSH. It underpins SSH servers, SFTP clients, and secure remote access across the Go ecosystem. An SSH parsing bug enables remote pre-auth attacks.