Skip to content

Commit 09284bc

Browse files
Working enough where it is usable. Still need improvements or completely replaced.
1 parent f59a216 commit 09284bc

File tree

3 files changed

+51
-39
lines changed

3 files changed

+51
-39
lines changed

topics/fuzzing/README.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,35 @@ Review the code we want to find problems with and the existing test:
3232

3333
Create a corpus file with the initial input data to use and that will be mutated.
3434

35-
[Fuzzing Data](workdir/corpus/data.txt) ([Go Playground](http://play.golang.org/p/_bfeKC1A4z))
35+
[Fuzzing Data](workdir/corpus/data.api) ([Go Playground](http://play.golang.org/p/RkYDgyQsF8))
3636

3737
Create a fuzzing function that takes mutated input and executes the code we care about using it.
3838

39-
[Fuzzing Function](example1/fuzzer.go) ([Go Playground](http://play.golang.org/p/CaGCilf6Yr))
39+
[Fuzzing Function](example1/fuzzer.go) ([Go Playground](http://play.golang.org/p/eq8Xnba6as)
4040

41-
Run the `go-fuzz-build` tool against the package to generate the fuzz zip file. The zip file contains all the instrumented binaries go-fuzz is going to use while fuzzing.
41+
Run the `go-fuzz-build` tool against the package to generate the fuzz zip file. The zip file contains all the instrumented binaries go-fuzz is going to use while fuzzing. Any time the source code changes this needs to be re-run.
4242

4343
go-fuzz-build github.com/ardanlabs/gotraining/topics/fuzzing/example1
4444

45-
Perform the actual fuzzing by running the `go-fuzz` tool and find data inputs that cause panics. Run this for a few seconds.
45+
Perform the actual fuzzing by running the `go-fuzz` tool and find data inputs that cause panics. Run this until you see an initial crash.
4646

47-
go-fuzz -bin=./api-fuzz.zip -dup -workdir=workdir/corpus -v 9
47+
go-fuzz -bin=./api-fuzz.zip -dup -workdir=workdir/corpus
4848

49-
Review the `crashers` folder under the `workdir/corpus` folders. This contains panic information.
49+
Run the build and start fuzzing.
5050

51-
[Output Stack Trace](example1/workdir/corpus/crashers/da39a3ee5e6b4b0d3255bfef95601890afd80709.output) ([Go Playground](http://play.golang.org/p/YajfpYyttx)
51+
Review the `crashers` folder under the `workdir/corpus` folders. This contains panic information. You will see an issue when the data passed into the web call is empty. Fix the `Process` function and add the table data to the test.
5252

53-
_**NOTE: These files are empty because an empty string is causing our problems.**_
53+
{"/process", http.StatusBadRequest, []byte(""), `{"Error":"The Message"}`},
5454

55-
[Crash Data Raw](example1/workdir/corpus/crashers/da39a3ee5e6b4b0d3255bfef95601890afd80709)
56-
[Crash Data Quoted](example1/workdir/corpus/crashers/da39a3ee5e6b4b0d3255bfef95601890afd80709.quoted)
55+
Run the build and start fuzzing.
5756

58-
Add new table data to our test for this input case and run the test. It will panic.
57+
Review the `crashers` folder under the `workdir/corpus` folders. This contains panic information. You will see an issue when value of "0" is used. Fix the `Process` function and add the table data to the test.
58+
59+
{"/process", http.StatusBadRequest, []byte("0"), `{"Error":"The Message"}`},
5960

60-
{"/process", http.StatusBadRequest, []byte(""), `{"Error":"Invalid user format"}`},
61+
## Exercises
62+
63+
### Exercise 1
6164

62-
Fix the `Process` function so this test no longer crashes. Run the tests again.
6365
___
6466
All material is licensed under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0).

topics/fuzzing/example1/example1.go

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@ package api
66

77
import (
88
"encoding/json"
9-
"errors"
109
"io/ioutil"
1110
"net/http"
1211
"strconv"
1312
"strings"
1413
)
1514

15+
// Need a named type for our user.
16+
type user struct {
17+
Type string
18+
Name string
19+
Age int
20+
}
21+
1622
// Routes initializes the routes.
1723
func Routes() {
1824
http.HandleFunc("/process", Process)
@@ -35,47 +41,47 @@ func Process(w http.ResponseWriter, r *http.Request) {
3541
return
3642
}
3743

38-
// If we received no data return an error.
39-
if len(data) == 0 {
40-
SendError(w, errors.New("Empty data value"))
41-
return
42-
}
43-
4444
// Split the data by comma.
4545
parts := strings.Split(string(data), ",")
4646

47-
// Need a named type for our user.
48-
type user struct {
49-
Type string
50-
Name string
51-
Age int
52-
}
53-
5447
// Create a slice of users.
5548
var users []user
5649

5750
// Iterate over the set of users we received.
5851
for _, part := range parts {
5952

60-
// Capture the type of user.
61-
typ := part[:3]
62-
63-
// Capture the age and convert to integer.
64-
age, err := strconv.Atoi(part[3:5])
53+
// Extract the user.
54+
u, err := extractUser(part)
6555
if err != nil {
6656
SendError(w, err)
6757
return
6858
}
6959

70-
// Capture the users name.
71-
name := part[5:]
72-
7360
// Add a user to the slice.
74-
users = append(users, user{typ, name, age})
61+
users = append(users, u)
7562
}
7663

7764
// Respond with the processed data.
7865
w.Header().Set("Content-Type", "application/json")
7966
w.WriteHeader(http.StatusOK)
8067
json.NewEncoder(w).Encode(users)
8168
}
69+
70+
// extractUser knows how to extract a user from the string.
71+
func extractUser(data string) (user, error) {
72+
73+
// Capture the age and convert to integer.
74+
age, err := strconv.Atoi(data[3:5])
75+
if err != nil {
76+
return user{}, err
77+
}
78+
79+
// Create the user value.
80+
u := user{
81+
Type: data[:3],
82+
Name: data[5:],
83+
Age: age,
84+
}
85+
86+
return u, nil
87+
}

topics/fuzzing/example1/fuzzer.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@ func Fuzz(data []byte) int {
1818
w := httptest.NewRecorder()
1919
http.DefaultServeMux.ServeHTTP(w, r)
2020

21+
// Data which has been corrupted but "looks valid" is more likely to be
22+
// able to get into other valid parts of your program without being
23+
// discarded as junk.
24+
2125
if w.Code != 200 {
2226

23-
// This was not successful. It we panic it will be recorded.
24-
panic(w.Body.String())
27+
// Report the data that produced this error as not interesting.
28+
return 0
2529
}
2630

27-
// The data caused no issues and is not interesting.
31+
// Report the data that did not cause an error as interesting.
2832
return 1
2933
}

0 commit comments

Comments
 (0)