Giter Site home page Giter Site logo

owasp / go-scp Goto Github PK

View Code? Open in Web Editor NEW
4.8K 129.0 364.0 16.12 MB

Golang Secure Coding Practices guide

Home Page: https://owasp.org/www-project-go-secure-coding-practices-guide/

License: Creative Commons Attribution Share Alike 4.0 International

Go 95.42% HTML 0.47% Dockerfile 4.10%
appsec golang

go-scp's Introduction

You can download this book in the following formats: PDF, Mobi and ePub.

Introduction

Go Language - Web Application Secure Coding Practices is a guide written for anyone who is using the Go Programming Language and aims to use it for web development.

It was originally created by Checkmarx Security Research Team and later donated to the OWASP Foundation: see the project page. The book follows the OWASP Secure Coding Practices - Quick Reference Guide v2 (stable) release.

The main goal of this book is to help developers avoid common mistakes while at the same time, learning a new programming language through a "hands-on approach". This book provides a good level of detail on "how to do it securely" showing what kind of security problems could arise during development.

The Audience for this Book

The primary audience of the Go Secure Coding Practices Guide is developers, particularly the ones with previous experience with other programming languages.

The book is also a great reference to those learning programming for the first time, who have already finish the Go tour.

What You Will Learn

This book covers the OWASP Secure Coding Practices Guide topic-by-topic, providing examples and recommendations using Go, to help developers avoid common mistakes and pitfalls.

After reading this book, you'll be more confident you're developing secure Go applications.

About OWASP Secure Coding Practices

This book was adapted for Go Language from The Secure Coding Practices Quick Reference Guide, an OWASP - Open Web Application Security Project. It is a "technology agnostic set of general software security coding practices, in a comprehensive checklist format, that can be integrated into the development lifecycle" (source).

OWASP itself is "an open community dedicated to enabling organizations to conceive, develop, acquire, operate, and maintain applications that can be trusted. All of the OWASP tools, documents, forums, and chapters are free and open to anyone interested in improving application security" (source).

How to Contribute

This book was created using a few open source tools. If you're curious about how we built it from scratch, read the How To contribute section.

License

This document is released under the Creative Commons Attribution-ShareAlike 4.0 International license (CC BY-SA 4.0). For any reuse or distribution, you must make clear to others the license terms of this work. https://creativecommons.org/licenses/by-sa/4.0/

go-scp's People

Contributors

bengadbois avatar bentcoder avatar budougumi0617 avatar cdrewuk avatar crsdrw avatar david-char avatar dreddsa5dies avatar edsrzf avatar erezyalon avatar filipnikolovski avatar gilliek avatar hoop33 avatar ich1gosan avatar ilyaglow avatar jabley avatar jparnaut avatar justinclift avatar leucos avatar lukasmalkmus avatar m-gregoire avatar michaeljsaenz avatar nicobouliane avatar pauloasilva avatar powerman avatar shawnkoon avatar spoint42 avatar tebeka avatar techjanitor avatar tusharxoxoxo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-scp's Issues

Spelling mistakes

Communication security and logging markdown contain spelling mistakes for "successfull" and "unsecure"

suggestion: do not demonstrate storing a password in plain text

Examples should often take extra steps to be correct. When demonstrating how to display an error message to the user:
https://github.com/Checkmarx/Go-SCP/blob/c3471ef24a7c2ca6a769457783f43c60712f087a/authentication-password-management/communicating-authentication-data.md

The password check is apparently stored in plain text. I would recommend returning fields called PasswordHash and Salt then doing some fake calls to verify that against the given password in the example.

Somehow avoid passing nonce to decryption method

Hi,

Thanks for this piece of work. The enc/dec example here requires the nonce to be known by both methods. Is there a way to avoid passing to dec method? Similar to this. See example below - same one from the doc but split into enc and dec methods.

Thanks

package main

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/hex"
	"fmt"
)

func main() {
	msg := []byte("Hello World!")
	key := []byte("a6df723a921fccda52bdc4ca50851559")

	nonce := make([]byte, 12)
	if _, err := rand.Read(nonce); err != nil {
		panic(err.Error())
	}
	fmt.Println("NONCE:", hex.EncodeToString(nonce))

	enc := enc(msg, key, nonce)
	fmt.Println("ENC:", hex.EncodeToString(enc))

	dec := dec(enc, key, nonce)
	fmt.Println("DEC:", string(dec))
}

func enc(data, key, nonce []byte) []byte {
	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err.Error())
	}

	aesgcm, err := cipher.NewGCM(block)
	if err != nil {
		panic(err.Error())
	}

	return aesgcm.Seal(nil, nonce, data, nil)
}

// Somehow this method should avoid requiring `nonce`.
func dec(enc, key, nonce []byte) []byte  {
	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err.Error())
	}

	aesgcm, err := cipher.NewGCM(block)
	if err != nil {
		panic(err.Error())
	}

	decrypted_data, err := aesgcm.Open(nil, nonce, enc, nil)
	if err != nil {
		panic(err.Error())
	}

	return decrypted_data
}

Traditional Chinese Version

Hi, this book is useful for gopher to follow the best practice of secure programming. Would you mind I translate this book to Traditional Chinese? I will link to origin repository and follows the license.

thanks

Validation of integers needs a review

I'm just picking on integers right now, because that's top of mind, but:

Add automation

It would be good to add some automation to this project, nothing fancy - probably a link checker to start with. This could be run on pull-request or merge to main, and for example could check for broken links

We do something similar in Secure Coding Practices

Link not updated to the migrated platform!

// OWASP Secure Coding Practices - Quick Reference Guide v2 (stable)
The link redirects to the old platform.

Please assign me this issue with the new platfrom t
Screenshot 2021-12-09 at 11 41 30 PM
o be added.

The sample code in this article doesn't seem to meet expectations

I note that in the XSS chapter, a simple example code is given.

package main

import "net/http"
import "io"

func handler (w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, r.URL.Query().Get("param1"))
}

func main () {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

I ran this code, but when I make param1 equal to <script>alert(1)</script>,XSS vulnerability is not triggered, <script> tag is filtered.
I ran this code in go 1.13.3. And I didn't succeed in the lower version (go1.5.4). Why is that? Did golang make any updates? If so, should the article also mention it?

Session management example doesn't compile due to syntax errors

The session-management example source code doesn't compile due to syntax errors:

$ go build session.go
# command-line-arguments
.\session.go:48:21: syntax error: unexpected newline, expecting comma or }
.\session.go:72:14: syntax error: unexpected newline, expecting comma or )
.\session.go:86:9: syntax error: unexpected else, expecting }
.\session.go:87:9: syntax error: unexpected {, expecting comma or )
.\session.go:93:5: syntax error: non-declaration statement outside function body
.\session.go:117:28: syntax error: unexpected newline, expecting comma or }

Validation section fix

From the Validation section, is this part backwards?

Anytime data is passed from a trusted source to a less-trusted source,...

Question about logging chapter

Hi, I am a little bit don't understand the following paragraph on the logging chapter:

... Another issue with the native logger is that there is no way to turn logging on or off on a per-package basis.

What do you mean about no way to turn logging on or off on a per-package basis. ?

As I know, you can use log.SetOutput(ioutil.Discard) to disable logging output. The example code is following:

package main

import (
	"fmt"
	"io/ioutil"
	"log"
)

func main() {
	fmt.Println("Hello, World.")
	log.SetOutput(ioutil.Discard)
	log.Print("Hello from log")
}

Or you mean this functionality does not contain inside the log package, which means you have to import io/ioutil package to achieve it ?

Thanks.

License

Hi there,

This looks like a great book, but you seem to have selected the GPL license for it. I'm not sure I understand how the GPL (which is a software license) would apply to a book. Perhaps you might like to consider one of the Creative Commons licenses instead?

Don't ignore error when password checking

In the "Communicating authentication data" section, there's this example:

var ctx context.Context
var value string

ctx := context.Background()
err := db.QueryContext(ctx, "SELECT passwordHash FROM accounts WHERE username = ?", username).Scan(&value)

// we don't really care about `err` as a measure to prevent timing attacks:
// as we always do a Constant Time Compare
if subtle.ConstantTimeCompare([]byte(value), []byte(attemptPasswordHash)) != 1 {
    // passwords do not match
}

I think it's bad practice to ignore the error, both in terms of practicality and security.

The argument in the comment amounts to "we don't want the client to be able to tell when our database returns an error." But I'd argue that they'll be able to tell anyway, for these reasons:

  • It will probably take a different amount of time for the database to return an error vs. not return an error.
  • When an error is returned, value will be the empty string (""). This means:
    • The []byte(value) conversion will take less time than in the no-error case.
    • subtle.ConstantTimeCompare will short circuit and return early because its two parameters have different length. (See its implementation)

Further, it doesn't matter whether the client can tell whether there's an error. If they're able to cause an error at will (for example, through SQL injection), then that's a separate security problem in itself. If they can't cause the error (for example, because the database is down), then it's independent of their input and it doesn't help them figure anything out.

Addition of Glossary for certain terms

Hi all,

I'd like to propose the addition of a glossary for certain terms that may be misinterpreted or need additional explanations to be unambiguously interpreted by readers.
This would also require a review of the complete document to ensure the uses of such words are correct according to their glossary definition.
This is particularly important in some specific cases like crypto, where terms are sometimes misused and there can be confusion as to their meaning and the instances of their use across the document could be linked to the definition in the glossary for fast reference.

Here's an example of what glossary entries could look like:

encoding - function which transforms input into a different representation without the use of a key. These are reversible and do not provide real security because if the algorithm is known, their output can be reversed.

hash - may be a reference to a hashing function or its output.

hashing/hash function - cryptographically-secure function which transforms input into fixed-length output, also known as trapdoor or one-way function. Their output cannot be "reversed", in the sense of retrieving back the input information from the output, because its fixed-length property does not retain the original information, but it can be "guessed" by attempting all possible inputs until we get the same output.

encryption - process by which input data (plaintext) is transformed into encrypted data (ciphertext) via the application of a secret key. The output of an encryption process may be reversed (decrypted) using a key.

KDF (or Key Derivation Function) - In this document, when referring to a KDF, we mean a function which takes a user password as input and derives a key which can be used for storage and authentication or a high entropy key for use with symmetric encryption algorithms. This is not a hash function, but a construction around a hash function to make it more resistant to attacks such as brute-force, rainbow-tables, etc. A simple example to understand what is meant by construction is PBKDF2 which uses salting and iterations to increase the cost of breaking the hash to the attacker.

The crypto section would then be revised to use these terms appropriately.

ServeMux doesn't always sanitize URL request path

Hey there,

It is stated that

In the net/http package there is an HTTP request multiplexer type called ServeMux. It is used to match the incoming request to the registered patterns, and calls the handler that most closely matches the requested URL. In addition to it's main purpose, it also takes care of sanitizing the URL request path, redirecting any request containing . or .. elements or repeated slashes to an equivalent, cleaner URL.

But actually you can see in the docs that "The path and host are used unchanged for CONNECT requests.".

You can check out an exploitation scenario here: https://ilyaglotov.com/blog/servemux-and-path-traversal

Suggestion: timing attacks.

On https://github.com/Checkmarx/Go-SCP/blob/master/src/authentication-password-management/communicating-authentication-data.md in the code example:

record, err = db.Query("SELECT password FROM accounts WHERE username = ?", username)
if err != nil {
  // user does not exist
}

if subtle.ConstantTimeCompare([]byte(record[0]), []byte(password)) != 1 {   
  // passwords do not match
}

the attacker can guess if the username exists or not in the database, if you choose to return early when the user does not exist.

suggestion: use database context methods in examples

All database operations are network operations (unless you are using an embedded database like sqlite or ql). As such they should be guarded with a context using db.QueryContext(ctx, "", arg1) to prevent hanging connections.

suggestion: incorrect handling of database connections

On page:

https://github.com/Checkmarx/Go-SCP/blob/c3471ef24a7c2ca6a769457783f43c60712f087a/database-security/connections.md

sql.Open returns a database pool (not a connection). This can be closed just before the application exists, but databases will determine that the connections are closed when the OS terminates the network connections when the executable closes.

Your example code (while won't compile as is), shows db.QueryRow. QueryRow does not need to be manually closed; it will be closed after a Scan. Furthermore throughout I highly recommend you use the Context variants, especially with a web application. When the context is canceled, a Tx will be rolled back if not committed, a Rows (from QueryContext) will be closed, and any resources will be returned. It is important to commit/rollback a Transaction or Close a Rows either explicitly or by canceling the context. However, the example Go code does not demonstrate this.

"init(i int)" is invalid

In "Error Handling" there's the following example:

func init(i int) {
        ...
	//This is just to deliberately crash the function.
	if i < 2 {
		fmt.Printf("Var %d - initialized\n", i)
	} else {
		//This was never supposed to happen, so we'll terminate our program.
		log.Fatal("Init failure - Terminating.")
	}
}

This code won't compile, the error is:
func init must have no arguments and no return values

Rename it to initialize?

Vague code description in system configuration section

In the system configuration section, the sample code demonstrate disable directory listing as follows:

type justFilesFilesystem struct {
    fs http.FileSystem
}

func (fs justFilesFilesystem) Open(name string) (http.File, error) {
    f, err := fs.fs.Open(name)
    if err != nil {
        return nil, err
    }
    return neuteredReaddirFile{f}, nil
}

However, it does not provide neuteredReaddirFile type here, which only show in the files directory.

How about describe neuteredReaddirFile type here that reader can easily copy&paste the sample code when reading the content here?

If you feel ok, I can open a pull request to add it to the sample code.

Thank you.

Source code examples give linter issues

The source code examples give various linter warnings using the golangci-lint tool:

$ golangci-lint run --no-config --deadline=1000s -E=golint -E=gocyclo -E=maligned -E=prealloc -E=unconvert -E=gosec -E=whitespace -E=misspell
system-configuration\files\directoryListSafe.go:30:21: Error return value of `http.ListenAndServe` is not checked (errcheck)
        http.ListenAndServe(":8080", http.StripPrefix("/tmp/static", http.FileServer(fs)))
                           ^
access-control\URL.go:29: unnecessary trailing newline (whitespace)

}
access-control\URL.go:62: unnecessary leading newline (whitespace)
        return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {

access-control\URL.go:117: unnecessary trailing newline (whitespace)

}
file-management\filetype\filetype.go:43: unnecessary trailing newline (whitespace)

}
access-control\URL.go:124:2: S1023: redundant `return` statement (gosimple)
        return
        ^

Wrong reference links for hashing algorithms in validation-and-storage.md

In " Go-SCP/src/authentication-password-management/validation-and-storage.md " LINK the reference links for hashing functions are wrong.

It should be something similar to:

In the case of password storage, the hashing algorithms recommended by
[OWASP][2] are [`bcrypt`][3], [`PDKDF2`][4], [`Argon2`][5] and [`scrypt`][6].

[1]: ../cryptographic-practices/pseudo-random-generators.md
[2]: https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet
[3]: https://godoc.org/golang.org/x/crypto/bcrypt
[4]: https://godoc.org/golang.org/x/crypto/pbkdf2
[5]: https://github.com/p-h-c/phc-winner-argon2
[6]: https://pkg.go.dev/golang.org/x/crypto/scrypt
[7]: https://github.com/ermites-io/passwd

Incorrect Cryptography recommendations

In the Cryptography Practices section we say the following:

MD5 is the most popular hashing algorithm, but securitywise BLAKE2 is considered the strongest and most flexible.

and

To fight back, the hashing function should be inherently slow, using at least 10,000 iterations.

MD5 is deprecated and insecure; we should never list it as a compliant sample. Additionally, iterated hashing is incorrect, and. we should recommend key stretching or some other mechanism for handling these scenarios. Lastly, there are no mentions of HMACs, which are the correct solution to authentication issues.

I can help massage these sections with some input from our cryptographers.

Additionally, we say:

Please not that slowness is something desired on a cryptographic hashing algorithm.

Which should be "Please note..."

Clarify how internal redirects work

From https://github.com/Checkmarx/Go-SCP/blob/c3471ef24a7c2ca6a769457783f43c60712f087a/input-validation/validation.md:

Go handles redirections internally which means that unless specified in the server side, in case of a redirect, Go serves the target page of the redirect directly. This can lead to security issues if a bad agent submits malicious data directly to the target of the redirection, effectively bypassing the data validation procedures in the server.

Please clarify how this works, with code examples using the standard library.

I'm not sure what it's trying to say. If I use https://golang.org/pkg/net/http/#Redirect, it doesn't appear to handle the redirection internally. It will send a 3xx response to the client, and wait for another request to arrive.

Gorilla Toolkit - vulnerable or not?

The portion about Input Validation, and specifically sanitation of the URL request path mentions a third party package called Gorilla Toolkit, but it does not specify whether this package is also vulnerable to path traversal attacks or whether it's preferred to use because perhaps it doesn't have this vulnerability.

Can someone please advise on whether this package is also vulnerable so we can update this section to indicate that?

Section "Sanitization" should be under "Output Encoding", not "Input Validation"

The section "Sanitization" talks about what needs to be done to safely display user submitted content, which doesn't actually have anything to do with "Input Validation", despite being a part of that chapter.

Having this section in the wrong place can mislead developers and give them a false sense of security ("I don't need to worry about XSS, because I've removed the HTML stuff").

I suggest moving the "Sanitization" section to the "Output Encoding" chapter, probably renaming it to something like "HTML".

Missing develop branch

Hi,

I'd like to submit a pull request but, according to your "How to contribute" guide, I should submit it to the develop branch:

Once you're ready to merge your work with others, you should go to main repository and open a Pull Request to the develop branch.

However, there is no such a branch in your repository. Could you create it or can I submit the pull request to the master branch?

Thanks,

Kevin

SQLi and templates

Most of the non-compliant Go SQL code I see is actually abuse of templates, rather than string joins. We should show non-compliance via templating as well, so that developers do not think that templating can necessarily save them here.

Needs more information on CSRF

It feels like CSRF deserves more mention in this book. There's a brief note about it in the section on websockets and the sample HTML form in "Communicating authentication data" contains a CSRF token form field, but that's it.

There's never a definition of CSRF, let alone strategies for managing or validating CSRF tokens.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.