httperroryzer

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2020 License: Apache-2.0 Imports: 7 Imported by: 0

README

httperroryzer

Static analyzer to catch invalid uses of http.Error without a return statement which can cause expected bugs

Example

An insidious bug could be the following in an HTTP handler

type credentials struct {
	Secret string `json:"secret"`
}

func authenticate(rw http.ResponseWriter, req *http.Request) {
	dec := json.NewDecoder(req.Body)
	defer req.Body.Close()
	creds := new(credentials)
	if err := dec.Decode(creds); err != nil {
		http.Error(rw, "could not parse out the response", http.StatusBadRequest)
	}
	if creds.Secret != "open-sesame" {
		http.Error(rw, "unauthorized", http.StatusUnauthorized)
	}
	rw.Write([]byte(`{"secret_location":"23.4162° N, 25.6628° E"}`))
}

In here, the caller forgot to invoke return after every error and in the end exposed what was supposed to be privileged information only available to those with the right credentials, for example when ran as per https://play.golang.org/p/I7Swd6GBfYe, it'll print out with malformed/malicious input such as { or {"secret":""}

http: superfluous response.WriteHeader call from main.authenticate (secrets.go:45)
could not parse out the response
unauthorized
{"secret_location":"23.4162° N, 25.6628° E"}
Remedy

Let's what would happen if we ran httperroryzer on it

go get github.com/orijtech/httperroryzer/cmd/httperroryzer && httperroryzer secrets.go

/go/src/github.com/orijtech/httperroryzer/sample/secrets.go:42:3: call to http.Error without a terminating statement below it
/go/src/github.com/orijtech/httperroryzer/sample/secrets.go:45:3: call to http.Error without a terminating statement below it

and when corrected

func authenticate(rw http.ResponseWriter, req *http.Request) {
	dec := json.NewDecoder(req.Body)
	defer req.Body.Close()
	creds := new(credentials)
	if err := dec.Decode(creds); err != nil {
		http.Error(rw, "could not parse out the response", http.StatusBadRequest)
		return
	}
	if creds.Secret != "open-sesame" {
		http.Error(rw, "unauthorized", http.StatusUnauthorized)
		return
	}
	rw.Write([]byte(`{"secret_location":"23.4162° N, 25.6628° E"}`))
}

Documentation

Overview

Copyright 2020 Orijtech, Inc. All Rights Reserved.

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 httperroryzer defines an Analyzer that checks for missing terminating statements after invoking http.Error.

Index

Constants

View Source
const Doc = `` /* 456-byte string literal not displayed */

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name: "httperroryzer",
	Doc:  Doc,
	Run:  run,
	Requires: []*analysis.Analyzer{
		inspect.Analyzer,
		ctrlflow.Analyzer,
	},
}

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL