sensitive

package module
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2021 License: MIT Imports: 8 Imported by: 5

README

Package sensitive

Project status Build Status GoDoc License

Package sensitive provides base types who's values should never be seen by the human eye, but still used for configuration.

What? Explain

Sometimes you have a variable, such as a password, passed into your program via arguments or ENV variables. Some of these variables are very sensitive! and should not in any circumstance be loggged or sent via JSON, despite JSON's "-", which people may forget. These variables, which are just typed primitive types, have their overridden fmt.Formatter, encoding.MarshalText & json.Marshal implementations.

As an added bonus using them as their base type eg. String => string, you have to explicitly cast the eg. string(s) This makes you think about what you're doing and why you casting it providing additional safelty.

Variables:

  • String - The most useful
  • Bytes
  • Bool
  • Float32
  • Float64
  • Int
  • Int8
  • Int16
  • Int32
  • Int64
  • Uint
  • Uint8
  • Uint16
  • Uint32
  • Uint64

Example

// go run _examples/basic/main.go mypassword
package main

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/powerman/sensitive"
)

func main() {
	password := sensitive.String(os.Args[1])

	fmt.Printf("%s\n", password)
	fmt.Printf("%v\n", password)

	b, _ := json.Marshal(password)
	fmt.Println(string(b))

	var empty *sensitive.String
	b, _ = json.Marshal(empty)
	fmt.Println(string(b))

	// output:
	//
	//
	// ""
	// null
}

Custom Formatting

package main

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/powerman/sensitive"
)

func init() {
	// override default Formatter
	sensitive.FormatStringFn = func(s sensitive.String, f fmt.State, c rune) {
		switch c {
		default:
		        sensitive.Format(f, c, "redacted")
		case 'v':
		        sensitive.Format(f, c, string(s)[:4]+"*******")
		}
	}
}

func main() {
	password := sensitive.String(os.Args[1])

	fmt.Printf("%s\n", password)
	fmt.Printf("%v\n", password)

	b, _ := json.Marshal(password)
	fmt.Println(string(b))

	var empty *sensitive.String
	b, _ = json.Marshal(empty)
	fmt.Println(string(b))

	// output:
	// redacted
	// mypa*******
	// "redacted"
	// null
}

License

Distributed under MIT License, please see license file in code for more details.

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	FormatBoolFn = func(s Bool, f fmt.State, c rune) {}
)
View Source
var (
	FormatBytesFn = func(s Bytes, f fmt.State, c rune) {}
)
View Source
var (
	FormatDecimalFn = func(s Decimal, f fmt.State, c rune) {}
)
View Source
var (
	FormatFloat32Fn = func(s Float32, f fmt.State, c rune) {}
)
View Source
var (
	FormatFloat64Fn = func(s Float64, f fmt.State, c rune) {}
)
View Source
var (
	FormatInt16Fn = func(s Int16, f fmt.State, c rune) {}
)
View Source
var (
	FormatInt32Fn = func(s Int32, f fmt.State, c rune) {}
)
View Source
var (
	FormatInt64Fn = func(s Int64, f fmt.State, c rune) {}
)
View Source
var (
	FormatInt8Fn = func(s Int8, f fmt.State, c rune) {}
)
View Source
var (
	FormatIntFn = func(s Int, f fmt.State, c rune) {}
)
View Source
var (
	FormatStringFn = func(s String, f fmt.State, c rune) {}
)
View Source
var (
	FormatUint16Fn = func(s Uint16, f fmt.State, c rune) {}
)
View Source
var (
	FormatUint32Fn = func(s Uint32, f fmt.State, c rune) {}
)
View Source
var (
	FormatUint64Fn = func(s Uint64, f fmt.State, c rune) {}
)
View Source
var (
	FormatUint8Fn = func(s Uint8, f fmt.State, c rune) {}
)
View Source
var (
	FormatUintFn = func(s Uint, f fmt.State, c rune) {}
)

Functions

func Disable added in v0.0.6

func Disable()

Disable protection of sensitive values.

This is designed to be used only in tests to make it easier to compare got/want values. To make Disable actually works it's not enough to just call it, there are a couple of extra requirements to minimize a chance to get disabled sensitive in production:

  • Current binary name should have ".test" suffix.
  • Environment variable GO_TEST_DISABLE_SENSITIVE should not be empty.

It is recommended to call it from TestMain or non-Parallel tests because it is not safe to call from simultaneous goroutines.

Calling Redact after Disable will re-enable protection of sensitive values.

As an extra protection it's recommended to add this into your main():

os.Unsetenv("GO_TEST_DISABLE_SENSITIVE")

func Format

func Format(f fmt.State, c rune, value interface{})

Format outputs value accordingly to formatting options.

It is useful in case you'll redefine some Format<type>Fn to output redacted value using formatting applied to original value.

sensitive.FormatStringFn = func(s sensitive.String, f fmt.State, c rune) {
    sensitive.Format(f, c, "REDACTED")
}
sensitive.FormatBytesFn = func(s sensitive.Bytes, f fmt.State, c rune) {
    sensitive.Format(f, c, []byte{0xDE, 0xFA, 0xCE})
}

func Redact added in v0.0.4

func Redact()

Redact sets all Format<type>Fn to output visible, non-zero values:

Bool:    FALSE (in upper case, unlike usual bool)
Float*:  NaN
Int*:    math.MinInt* (MinInt32 for Int)
Uint*:   math.MaxUint* (MaxUint32 for Uint)
String:  "REDACTED"
Bytes:   0xDEFACE
Decimal: NaN
Example
var (
	vBool    Bool    = true
	vFloat32 Float32 = 4.2
	vFloat64 Float64 = 42.42
	vInt8    Int8    = -42
	vInt16   Int16   = -4242
	vInt32   Int32   = -424242
	vInt64   Int64   = -42424242
	vInt     Int     = -42424242
	vUint8   Uint8   = 42
	vUint16  Uint16  = 4242
	vUint32  Uint32  = 424242
	vUint64  Uint64  = 42424242
	vUint    Uint    = 42424242
	vString  String  = "secret"
	vBytes   Bytes   = []byte("secret")
	vDecimal Decimal = Decimal(decimal.NewFromFloat(42.42))
	vs               = []interface{}{
		vBool, vFloat32, vFloat64,
		vInt8, vInt16, vInt32, vInt64, vInt,
		vUint8, vUint16, vUint32, vUint64, vUint,
		vString, vBytes, vDecimal,
	}
	imap = map[interface{}]interface{}{
		vBool:    vBool,
		vFloat32: vFloat32,
		vFloat64: vFloat64,
		vInt8:    vInt8,
		vInt16:   vInt16,
		vInt32:   vInt32,
		vInt64:   vInt64,
		vInt:     vInt,
		vUint8:   vUint8,
		vUint16:  vUint16,
		vUint32:  vUint32,
		vUint64:  vUint64,
		vUint:    vUint,
		vString:  vString,
		// vBytes:   vBytes,
		vDecimal: vDecimal,
	}
	vmap = map[string]interface{}{
		"Bool":    vBool,
		"Float32": vFloat32,
		"Float64": vFloat64,
		"Int8":    vInt8,
		"Int16":   vInt16,
		"Int32":   vInt32,
		"Int64":   vInt64,
		"Int":     vInt,
		"Uint8":   vUint8,
		"Uint16":  vUint16,
		"Uint32":  vUint32,
		"Uint64":  vUint64,
		"Uint":    vUint,
		"String":  vString,
		"Bytes":   vBytes,
		"Decimal": vDecimal,
	}
	exported = struct {
		VBool    Bool
		VFloat32 Float32
		VFloat64 Float64
		VInt8    Int8
		VInt16   Int16
		VInt32   Int32
		VInt64   Int64
		VInt     Int
		VUint8   Uint8
		VUint16  Uint16
		VUint32  Uint32
		VUint64  Uint64
		VUint    Uint
		VString  String
		VBytes   Bytes
		VDecimal Decimal
	}{
		VBool:    vBool,
		VFloat32: vFloat32,
		VFloat64: vFloat64,
		VInt8:    vInt8,
		VInt16:   vInt16,
		VInt32:   vInt32,
		VInt64:   vInt64,
		VInt:     vInt,
		VUint8:   vUint8,
		VUint16:  vUint16,
		VUint32:  vUint32,
		VUint64:  vUint64,
		VUint:    vUint,
		VString:  vString,
		VBytes:   vBytes,
		VDecimal: vDecimal,
	}
	unexported = struct {
		vBool    Bool
		vFloat32 Float32
		vFloat64 Float64
		vInt8    Int8
		vInt16   Int16
		vInt32   Int32
		vInt64   Int64
		vInt     Int
		vUint8   Uint8
		vUint16  Uint16
		vUint32  Uint32
		vUint64  Uint64
		vUint    Uint
		vString  String
		vBytes   Bytes
		// vDecimal Decimal
	}{
		vBool:    vBool,
		vFloat32: vFloat32,
		vFloat64: vFloat64,
		vInt8:    vInt8,
		vInt16:   vInt16,
		vInt32:   vInt32,
		vInt64:   vInt64,
		vInt:     vInt,
		vUint8:   vUint8,
		vUint16:  vUint16,
		vUint32:  vUint32,
		vUint64:  vUint64,
		vUint:    vUint,
		vString:  vString,
		vBytes:   vBytes,
		// vDecimal: vDecimal,
	}
)

// Outputs to stderr, not intercepted by testing package:
// println: true +4.200000e+000 +4.242000e+001 -42 -4242 -424242 -42424242 -42424242 42 4242 424242 42424242 42424242 secret [6/6]0xc000216158
println("println:",
	vBool, vFloat32, vFloat64,
	vInt8, vInt16, vInt32, vInt64, vInt,
	vUint8, vUint16, vUint32, vUint64, vUint,
	vString, vBytes,
	// vDecimal,
)

output := func() {
	fmt.Println(append(append([]interface{}{"fmt.Println(...):"}, vs...), "EOL")...)
	fmt.Printf("fmt.Printf: %t %e %E %c %b %o %x %d %c %b %O %X %U %q %X %v EOL\n", vs...)
	fmt.Printf("fmt.Printf(vs): %v\n", vs)
	fmt.Printf("fmt.Printf(imap): %v\n", imap)
	fmt.Printf("fmt.Printf(vmap): %v\n", vmap)
	fmt.Printf("fmt.Printf(exported): %v\n", exported)
	fmt.Printf("fmt.Printf(unexported): %v\n", unexported)
	json.NewEncoder(os.Stdout).Encode(vs)
	json.NewEncoder(os.Stdout).Encode(vmap)
	json.NewEncoder(os.Stdout).Encode(exported)
	json.NewEncoder(os.Stdout).Encode(unexported)
	xml.NewEncoder(os.Stdout).Encode(vs)
	fmt.Println()
}
output()
Redact()
os.Unsetenv("GO_TEST_DISABLE_SENSITIVE")
Disable()
output()
os.Setenv("GO_TEST_DISABLE_SENSITIVE", "1")
Disable()
output()
Output:

fmt.Println(...):                 EOL
fmt.Printf:                 EOL
fmt.Printf(vs): [               ]
fmt.Printf(imap): map[: : : : : : : : : : : : : : :]
fmt.Printf(vmap): map[Bool: Bytes: Decimal: Float32: Float64: Int: Int16: Int32: Int64: Int8: String: Uint: Uint16: Uint32: Uint64: Uint8:]
fmt.Printf(exported): {               }
fmt.Printf(unexported): {true 4.2 42.42 -42 -4242 -424242 -42424242 -42424242 42 4242 424242 42424242 42424242 secret [115 101 99 114 101 116]}
[null,null,null,null,null,null,null,null,null,null,null,null,null,"",null,null]
{"Bool":null,"Bytes":null,"Decimal":null,"Float32":null,"Float64":null,"Int":null,"Int16":null,"Int32":null,"Int64":null,"Int8":null,"String":"","Uint":null,"Uint16":null,"Uint32":null,"Uint64":null,"Uint8":null}
{"VBool":null,"VFloat32":null,"VFloat64":null,"VInt8":null,"VInt16":null,"VInt32":null,"VInt64":null,"VInt":null,"VUint8":null,"VUint16":null,"VUint32":null,"VUint64":null,"VUint":null,"VString":"","VBytes":null,"VDecimal":null}
{}
<Bool></Bool><Float32></Float32><Float64></Float64><Int8></Int8><Int16></Int16><Int32></Int32><Int64></Int64><Int></Int><Uint8></Uint8><Uint16></Uint16><Uint32></Uint32><Uint64></Uint64><Uint></Uint><String></String><Bytes></Bytes><Decimal></Decimal>
fmt.Println(...): FALSE NaN NaN -128 -32768 -2147483648 -9223372036854775808 -2147483648 255 65535 4294967295 18446744073709551615 4294967295 REDACTED [222 250 206] NaN EOL
fmt.Printf: FALSE NaN NaN � -1000000000000000 -20000000000 -8000000000000000 -2147483648 ÿ 1111111111111111 0o37777777777 FFFFFFFFFFFFFFFF U+FFFFFFFF "REDACTED" DEFACE NaN EOL
fmt.Printf(vs): [FALSE NaN NaN -128 -32768 -2147483648 -9223372036854775808 -2147483648 255 65535 4294967295 18446744073709551615 4294967295 REDACTED [222 250 206] NaN]
fmt.Printf(imap): map[FALSE:FALSE NaN:NaN NaN:NaN -2147483648:-2147483648 -32768:-32768 -2147483648:-2147483648 -9223372036854775808:-9223372036854775808 -128:-128 REDACTED:REDACTED 4294967295:4294967295 65535:65535 4294967295:4294967295 18446744073709551615:18446744073709551615 255:255 NaN:NaN]
fmt.Printf(vmap): map[Bool:FALSE Bytes:[222 250 206] Decimal:NaN Float32:NaN Float64:NaN Int:-2147483648 Int16:-32768 Int32:-2147483648 Int64:-9223372036854775808 Int8:-128 String:REDACTED Uint:4294967295 Uint16:65535 Uint32:4294967295 Uint64:18446744073709551615 Uint8:255]
fmt.Printf(exported): {FALSE NaN NaN -128 -32768 -2147483648 -9223372036854775808 -2147483648 255 65535 4294967295 18446744073709551615 4294967295 REDACTED [222 250 206] NaN}
fmt.Printf(unexported): {true 4.2 42.42 -42 -4242 -424242 -42424242 -42424242 42 4242 424242 42424242 42424242 secret [115 101 99 114 101 116]}
{}
<Bool>FALSE</Bool><Float32>NaN</Float32><Float64>NaN</Float64><Int8>-128</Int8><Int16>-32768</Int16><Int32>-2147483648</Int32><Int64>-9223372036854775808</Int64><Int>-2147483648</Int><Uint8>255</Uint8><Uint16>65535</Uint16><Uint32>4294967295</Uint32><Uint64>18446744073709551615</Uint64><Uint>4294967295</Uint><String>REDACTED</String><Bytes>DEFACE</Bytes><Decimal>NaN</Decimal>
fmt.Println(...): true 4.2 42.42 -42 -4242 -424242 -42424242 -42424242 42 4242 424242 42424242 42424242 secret [115 101 99 114 101 116] 42.42 EOL
fmt.Printf: true 4.200000e+00 4.242000E+01 � -1000010010010 -1474462 -28757b2 -42424242 * 1000010010010 0o1474462 28757B2 U+28757B2 "secret" 736563726574 42.42 EOL
fmt.Printf(vs): [true 4.2 42.42 -42 -4242 -424242 -42424242 -42424242 42 4242 424242 42424242 42424242 secret [115 101 99 114 101 116] 42.42]
fmt.Printf(imap): map[true:true 4.2:4.2 42.42:42.42 -42424242:-42424242 -4242:-4242 -424242:-424242 -42424242:-42424242 -42:-42 secret:secret 42424242:42424242 4242:4242 424242:424242 42424242:42424242 42:42 42.42:42.42]
fmt.Printf(vmap): map[Bool:true Bytes:[115 101 99 114 101 116] Decimal:42.42 Float32:4.2 Float64:42.42 Int:-42424242 Int16:-4242 Int32:-424242 Int64:-42424242 Int8:-42 String:secret Uint:42424242 Uint16:4242 Uint32:424242 Uint64:42424242 Uint8:42]
fmt.Printf(exported): {true 4.2 42.42 -42 -4242 -424242 -42424242 -42424242 42 4242 424242 42424242 42424242 secret [115 101 99 114 101 116] 42.42}
fmt.Printf(unexported): {true 4.2 42.42 -42 -4242 -424242 -42424242 -42424242 42 4242 424242 42424242 42424242 secret [115 101 99 114 101 116]}
[true,4.2,42.42,-42,-4242,-424242,-42424242,-42424242,42,4242,424242,42424242,42424242,"secret","c2VjcmV0",42.42]
{"Bool":true,"Bytes":"c2VjcmV0","Decimal":42.42,"Float32":4.2,"Float64":42.42,"Int":-42424242,"Int16":-4242,"Int32":-424242,"Int64":-42424242,"Int8":-42,"String":"secret","Uint":42424242,"Uint16":4242,"Uint32":424242,"Uint64":42424242,"Uint8":42}
{"VBool":true,"VFloat32":4.2,"VFloat64":42.42,"VInt8":-42,"VInt16":-4242,"VInt32":-424242,"VInt64":-42424242,"VInt":-42424242,"VUint8":42,"VUint16":4242,"VUint32":424242,"VUint64":42424242,"VUint":42424242,"VString":"secret","VBytes":"c2VjcmV0","VDecimal":42.42}
{}
<Bool>true</Bool><Float32>4.2</Float32><Float64>42.42</Float64><Int8>-42</Int8><Int16>-4242</Int16><Int32>-424242</Int32><Int64>-42424242</Int64><Int>-42424242</Int><Uint8>42</Uint8><Uint16>4242</Uint16><Uint32>424242</Uint32><Uint64>42424242</Uint64><Uint>42424242</Uint><String>secret</String><Bytes>736563726574</Bytes><Decimal>42.42</Decimal>

Types

type Bool

type Bool bool

func (Bool) Format

func (s Bool) Format(f fmt.State, c rune)

func (Bool) MarshalJSON

func (s Bool) MarshalJSON() ([]byte, error)

func (Bool) MarshalText

func (s Bool) MarshalText() (text []byte, err error)

type Bytes

type Bytes []byte

func (Bytes) Format

func (s Bytes) Format(f fmt.State, c rune)

func (Bytes) MarshalJSON

func (s Bytes) MarshalJSON() ([]byte, error)

func (Bytes) MarshalText

func (s Bytes) MarshalText() (text []byte, err error)

type Decimal added in v0.0.5

type Decimal decimal.Decimal

func (Decimal) Format added in v0.0.5

func (s Decimal) Format(f fmt.State, c rune)

func (Decimal) MarshalJSON added in v0.0.5

func (s Decimal) MarshalJSON() ([]byte, error)

func (Decimal) MarshalText added in v0.0.5

func (s Decimal) MarshalText() (text []byte, err error)

type Float32

type Float32 float32

func (Float32) Format

func (s Float32) Format(f fmt.State, c rune)

func (Float32) MarshalJSON

func (s Float32) MarshalJSON() ([]byte, error)

func (Float32) MarshalText

func (s Float32) MarshalText() (text []byte, err error)

type Float64

type Float64 float64

func (Float64) Format

func (s Float64) Format(f fmt.State, c rune)

func (Float64) MarshalJSON

func (s Float64) MarshalJSON() ([]byte, error)

func (Float64) MarshalText

func (s Float64) MarshalText() (text []byte, err error)

type Int

type Int int

func (Int) Format

func (s Int) Format(f fmt.State, c rune)

func (Int) MarshalJSON

func (s Int) MarshalJSON() ([]byte, error)

func (Int) MarshalText

func (s Int) MarshalText() (text []byte, err error)

type Int8

type Int8 int8

func (Int8) Format

func (s Int8) Format(f fmt.State, c rune)

func (Int8) MarshalJSON

func (s Int8) MarshalJSON() ([]byte, error)

func (Int8) MarshalText

func (s Int8) MarshalText() (text []byte, err error)

type Int16

type Int16 int16

func (Int16) Format

func (s Int16) Format(f fmt.State, c rune)

func (Int16) MarshalJSON

func (s Int16) MarshalJSON() ([]byte, error)

func (Int16) MarshalText

func (s Int16) MarshalText() (text []byte, err error)

type Int32

type Int32 int32

func (Int32) Format

func (s Int32) Format(f fmt.State, c rune)

func (Int32) MarshalJSON

func (s Int32) MarshalJSON() ([]byte, error)

func (Int32) MarshalText

func (s Int32) MarshalText() (text []byte, err error)

type Int64

type Int64 int64

func (Int64) Format

func (s Int64) Format(f fmt.State, c rune)

func (Int64) MarshalJSON

func (s Int64) MarshalJSON() ([]byte, error)

func (Int64) MarshalText

func (s Int64) MarshalText() (text []byte, err error)

type State

type State struct {
	// contains filtered or unexported fields
}

func (State) Flag

func (s State) Flag(c int) bool

func (State) Precision

func (s State) Precision() (prec int, ok bool)

func (State) Width

func (s State) Width() (wid int, ok bool)

func (*State) Write

func (s *State) Write(b []byte) (n int, err error)

type String

type String string

func (String) Format

func (s String) Format(f fmt.State, c rune)

func (String) MarshalJSON

func (s String) MarshalJSON() ([]byte, error)

func (String) MarshalText

func (s String) MarshalText() (text []byte, err error)

type Uint

type Uint uint

func (Uint) Format

func (s Uint) Format(f fmt.State, c rune)

func (Uint) MarshalJSON

func (s Uint) MarshalJSON() ([]byte, error)

func (Uint) MarshalText

func (s Uint) MarshalText() (text []byte, err error)

type Uint8

type Uint8 uint8

func (Uint8) Format

func (s Uint8) Format(f fmt.State, c rune)

func (Uint8) MarshalJSON

func (s Uint8) MarshalJSON() ([]byte, error)

func (Uint8) MarshalText

func (s Uint8) MarshalText() (text []byte, err error)

type Uint16

type Uint16 uint16

func (Uint16) Format

func (s Uint16) Format(f fmt.State, c rune)

func (Uint16) MarshalJSON

func (s Uint16) MarshalJSON() ([]byte, error)

func (Uint16) MarshalText

func (s Uint16) MarshalText() (text []byte, err error)

type Uint32

type Uint32 uint32

func (Uint32) Format

func (s Uint32) Format(f fmt.State, c rune)

func (Uint32) MarshalJSON

func (s Uint32) MarshalJSON() ([]byte, error)

func (Uint32) MarshalText

func (s Uint32) MarshalText() (text []byte, err error)

type Uint64

type Uint64 uint64

func (Uint64) Format

func (s Uint64) Format(f fmt.State, c rune)

func (Uint64) MarshalJSON

func (s Uint64) MarshalJSON() ([]byte, error)

func (Uint64) MarshalText

func (s Uint64) MarshalText() (text []byte, err error)

Directories

Path Synopsis
_examples
basic command
custom command

Jump to

Keyboard shortcuts

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