Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more tests #11

Merged
merged 5 commits into from
Nov 21, 2023
Merged

Add more tests #11

merged 5 commits into from
Nov 21, 2023

Conversation

picatz
Copy link
Owner

@picatz picatz commented Sep 16, 2023

This PR adds more tests.

@picatz
Copy link
Owner Author

picatz commented Sep 16, 2023

e1653cb added a test that essentially checks if the echo function used in the handler function can be exploited to inject malicious code into the response (reflected cross-site scripting):

func echo(w io.Writer, r any) error {
ior, ok := r.(io.Reader)
if !ok {
return fmt.Errorf("failed to cast to io.Reader")
}
b, err := io.ReadAll(ior)
if err != nil {
return fmt.Errorf("failed to read all bytes from io.Reader: %w", err)
}
w.Write(b)
return nil
}
func handler(w http.ResponseWriter, r *http.Request) {
err := echo(w, r) // want "potential XSS"
if err != nil {
panic(err)
}
}

Callgraph

n0:e.main
	→ n5:net/http.HandleFunc
	→ n7:net/http.ListenAndServe

n1:e.echo
	→ n3:(io.Writer).Write
	→ n6:io.ReadAll
	→ n8:fmt.Errorf
	→ n9:(io.Writer).Write

n3:(io.Writer).Write
	→ n4:(net/http.ResponseWriter).Write

n4:(net/http.ResponseWriter).Write

n7:net/http.ListenAndServe

n2:e.handler
	→ n1:e.echo

n5:net/http.HandleFunc
	→ n2:e.handler

n6:io.ReadAll

n8:fmt.Errorf

n9:(io.Writer).Write

Tainted Path

n5:net/http.HandleFuncn2:e.handlern1:e.echon3:(io.Writer).Writen4:(net/http.ResponseWriter).Write

Importantly, echo function's signature obscures the test because it takes an io.Writer and empty interface r as parameters, effectively masking the type information for r.

@picatz
Copy link
Owner Author

picatz commented Sep 17, 2023

🤔 Continuing to add more test cases, if we add an "f" test based e1653cb, the analysis gets confused:

e f
func echo(w io.Writer, r any) {
	ior := r.(io.Reader)

	b, err := io.ReadAll(ior)
	if err != nil {
		panic(err)
	}

	w.Write(b)
}

func handler(w http.ResponseWriter, r *http.Request) {
	echo(w, r) // want "potential XSS"
}
func echo(w io.Writer, r any) {
	ior := r.(io.Reader)

	b, err := io.ReadAll(ior)
	if err != nil {
		panic(err)
	}

	w.Write(b)
}

func handler(w http.ResponseWriter, r *http.Request) {
	b := bufio.NewWriterSize(w, 4096)
	defer b.Flush()

	echo(b, r) // want "potential XSS"
}

Simplified version of e1653cb with less error handling. Current analysis logic can easily catch this.

Includes bufio.NewWriterSize, an additional call in the call graph. Current analysis logic is confused by this.

Sink Path for E

n5:net/http.HandleFuncn2:e.handlern1:e.echon3:(io.Writer).Writen4:(net/http.ResponseWriter).Write

e

Sink Path for F

n7:net/http.HandleFuncn2:f.handlern3:bufio.NewWriterSizen4:(io.Writer).Writen5:(net/http.ResponseWriter).Write

f

This confusion likely partially stems from the "virtual" function calls now tracked for interfaces (like io.Writer) added in #9 (comment).

@github-advanced-security
Copy link

This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.

@picatz picatz marked this pull request as ready for review November 21, 2023 01:01
@picatz picatz merged commit 6b31d14 into main Nov 21, 2023
1 check passed
@picatz picatz deleted the add-more-tests branch November 21, 2023 01:03
@picatz
Copy link
Owner Author

picatz commented Nov 21, 2023

This was a very imperfect, but fun PR to work on. Learned a lot, and I hope to follow this up in the near future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant