hibp

package module
v1.0.6 Latest Latest
Warning

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

Go to latest
Published: Feb 9, 2023 License: MIT Imports: 17 Imported by: 2

README

go-hibp - Simple Go binding to the "Have I Been Pwned" API

GoDoc Go Report Card Build Status codecov Mentioned in Awesome Go buy ma a coffee

This Go library provides simple bindings to the excellent "Have I Been Pwned" (HIBP) API by Troy Hunt. It implements all 3 APIs that are provided by HIBP (Breaches, Pastes, Passwords). API key support for the private API endpoints are supported as well. go-hibp follows idiomatic Go style and best practice. It's only dependency is the Go Standard Library.

Usage

The library is fully documented using the execellent GoDoc functionality. Check out the GoDocs Reference for details on how to implement access to any of the 3 APIs with this package. You will also find GoDoc code examples there for each of those APIs.

Documentation

Overview

Package hibp provides Go binding to all 3 APIs of the "Have I Been Pwned" by Troy Hunt

Index

Examples

Constants

View Source
const BaseURL = "https://haveibeenpwned.com/api/v3"

BaseURL is the base URL for the majority of API endpoints

View Source
const DefaultTimeout = time.Second * 5

DefaultTimeout is the default timeout value for the HTTP client

View Source
const DefaultUserAgent = `go-hibp/` + Version + ` (+https://github.com/wneessen/go-hibp)`

DefaultUserAgent defines the default UA string for the HTTP client Currently the URL in the UA string is comment out, as there is a bug in the HIBP API not allowing multiple slashes

View Source
const PasswdBaseURL = "https://api.pwnedpasswords.com"

PasswdBaseURL is the base URL for the pwned passwords API endpoints

View Source
const Version = "1.0.5"

Version represents the version of this package

Variables

View Source
var (
	// ErrNoAccountID is returned if no account ID is given to the corresponding API method
	ErrNoAccountID = errors.New("no account ID given")

	// ErrNoName is returned if no name is given to the corresponding API method
	ErrNoName = errors.New("no name given")

	// ErrNonPositiveResponse should be returned if a HTTP request failed with a non HTTP-200 status
	ErrNonPositiveResponse = errors.New("non HTTP-200 response for HTTP request")

	// ErrPrefixLengthMismatch should be used if a given prefix does not match the
	// expected length
	ErrPrefixLengthMismatch = errors.New("password hash prefix must be 5 characters long")

	// ErrSHA1LengthMismatch should be used if a given SHA1 checksum does not match the
	// expected length
	ErrSHA1LengthMismatch = errors.New("SHA1 hash size needs to be 160 bits")

	// ErrNTLMLengthMismatch should be used if a given NTLM hash does not match the
	// expected length
	ErrNTLMLengthMismatch = errors.New("NTLM hash size needs to be 128 bits")

	// ErrSHA1Invalid should be used if a given string does not represent a valid SHA1 hash
	ErrSHA1Invalid = errors.New("not a valid SHA1 hash")

	// ErrNTLMInvalid should be used if a given string does not represent a valid NTLM hash
	ErrNTLMInvalid = errors.New("not a valid NTLM hash")

	// ErrUnsupportedHashMode should be used if a given hash mode is not supported
	ErrUnsupportedHashMode = errors.New("hash mode not supported")
)

List of common errors

Functions

This section is empty.

Types

type APIDate added in v1.0.4

type APIDate time.Time

APIDate is a date string without time returned by the API represented as time.Time type

func (*APIDate) Time added in v1.0.4

func (d *APIDate) Time() time.Time

Time adds a Time() method to the APIDate converted time.Time type

func (*APIDate) UnmarshalJSON added in v1.0.4

func (d *APIDate) UnmarshalJSON(s []byte) error

UnmarshalJSON for the APIDate type converts a give date string into a time.Time type

type Breach added in v0.1.2

type Breach struct {
	// Name is a pascal-cased name representing the breach which is unique across all other breaches.
	// This value never changes and may be used to name dependent assets (such as images) but should not
	// be shown directly to end users (see the "Title" attribute instead)
	Name string `json:"Name"`

	// Title is a descriptive title for the breach suitable for displaying to end users. It's unique across
	// all breaches but individual values may change in the future (i.e. if another breach occurs against
	// an organisation already in the system). If a stable value is required to reference the breach,
	// refer to the "Name" attribute instead
	Title string `json:"Title"`

	// Domain of the primary website the breach occurred on. This may be used for identifying other
	// assets external systems may have for the site
	Domain string `json:"Domain"`

	// BreachDate is the date (with no time) the breach originally occurred on in ISO 8601 format. This is not
	// always accurate — frequently breaches are discovered and reported long after the original incident. Use
	// this attribute as a guide only
	BreachDate *APIDate `json:"BreachDate,omitempty"`

	// AddedDate represents the date and time (precision to the minute) the breach was added to the system
	// in ISO 8601 format
	AddedDate time.Time `json:"AddedDate"`

	// ModifiedDate is the date and time (precision to the minute) the breach was modified in ISO 8601 format.
	// This will only differ from the AddedDate attribute if other attributes represented here are changed or
	// data in the breach itself is changed (i.e. additional data is identified and loaded). It is always
	// either equal to or greater then the AddedDate attribute, never less than
	ModifiedDate time.Time `json:"ModifiedDate"`

	// PwnCount is the total number of accounts loaded into the system. This is usually less than the total
	// number reported by the media due to duplication or other data integrity issues in the source data
	PwnCount int `json:"PwnCount"`

	// Description contains an overview of the breach represented in HTML markup. The description may include
	// markup such as emphasis and strong tags as well as hyperlinks
	Description string `json:"Description"`

	// DataClasses describes the nature of the data compromised in the breach and contains an alphabetically ordered
	// string array of impacted data classes
	DataClasses []string `json:"DataClasses"`

	// IsVerified indicates that the breach is considered unverified. An unverified breach may not have
	// been hacked from the indicated website. An unverified breach is still loaded into HIBP when there's
	// sufficient confidence that a significant portion of the data is legitimate
	IsVerified bool `json:"IsVerified"`

	// IsFabricated indicates that the breach is considered fabricated. A fabricated breach is unlikely
	// to have been hacked from the indicated website and usually contains a large amount of manufactured
	// data. However, it still contains legitimate email addresses and asserts that the account owners
	// were compromised in the alleged breach
	IsFabricated bool `json:"IsFabricated"`

	// IsSensitive indicates if the breach is considered sensitive. The public API will not return any
	// accounts for a breach flagged as sensitive
	IsSensitive bool `json:"IsSensitive"`

	// IsRetired indicates if the breach has been retired. This data has been permanently removed and
	// will not be returned by the API
	IsRetired bool `json:"IsRetired"`

	// IsSpamList indicates
	IsSpamList bool `json:"IsSpamList"`

	// LogoPath represents a URI that specifies where a logo for the breached service can be found.
	// Logos are always in PNG format
	LogoPath string `json:"LogoPath"`
}

Breach represents a JSON response structure of the breaches API

type BreachAPI added in v1.0.4

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

BreachAPI is a HIBP breaches API client

func (*BreachAPI) BreachByName added in v1.0.4

func (b *BreachAPI) BreachByName(n string, options ...BreachOption) (*Breach, *http.Response, error)

BreachByName returns a single breached site based on its name

Example

ExampleBreachAPI_BreachByName is a code example to show how to fetch a specific breach from the HIBP breaches API using the BreachByName method

hc := New()
bd, _, err := hc.BreachAPI.BreachByName("Adobe")
if err != nil {
	panic(err)
}
if bd != nil {
	fmt.Println("Details of the 'Adobe' breach:")
	fmt.Printf("\tDomain: %s\n", bd.Domain)
	fmt.Printf("\tBreach date: %s\n", bd.BreachDate.Time().Format("2006-01-02"))
	fmt.Printf("\tAdded to HIBP: %s\n", bd.AddedDate.String())
}
Output:

func (*BreachAPI) BreachedAccount added in v1.0.4

func (b *BreachAPI) BreachedAccount(a string, options ...BreachOption) ([]*Breach, *http.Response, error)

BreachedAccount returns a single breached site based on its name

Example

ExampleBreachAPI_BreachedAccount is a code example to show how to fetch a list of breaches for a specific site/account from the HIBP breaches API using the BreachedAccount method

apiKey := os.Getenv("HIBP_API_KEY")
if apiKey == "" {
	panic("A API key is required for this API")
}
hc := New(WithAPIKey(apiKey))
bd, _, err := hc.BreachAPI.BreachedAccount("multiple-breaches@hibp-integration-tests.com")
if err != nil {
	panic(err)
}
for _, b := range bd {
	fmt.Printf("Your account was part of the %q breach\n", b.Name)
}
Output:

func (*BreachAPI) Breaches added in v1.0.4

func (b *BreachAPI) Breaches(options ...BreachOption) ([]*Breach, *http.Response, error)

Breaches returns a list of all breaches in the HIBP system

Example (GetAllBreaches)

ExampleBreachAPI_Breaches_getAllBreaches is a code example to show how to fetch all breaches from the HIBP breaches API

hc := New()
bl, _, err := hc.BreachAPI.Breaches()
if err != nil {
	panic(err)
}
if len(bl) != 0 {
	for _, b := range bl {
		fmt.Printf("Found breach:\n\tName: %s\n\tDomain: %s\n\tBreach date: %s\n\n",
			b.Name, b.Domain, b.BreachDate.Time().Format("Mon, 2. January 2006"))
	}
}
Output:

Example (GetAllBreachesNoUnverified)

ExampleBreachAPI_Breaches_getAllBreachesNoUnverified is a code example to show how to fetch all breaches from the HIBP breaches API but ignoring unverified breaches

hc := New()
bl, _, err := hc.BreachAPI.Breaches()
if err != nil {
	panic(err)
}
if len(bl) != 0 {
	fmt.Printf("Found %d breaches total.\n", len(bl))
}

bl, _, err = hc.BreachAPI.Breaches(WithoutUnverified())
if err != nil {
	panic(err)
}
if len(bl) != 0 {
	fmt.Printf("Found %d verified breaches total.\n", len(bl))
}
Output:

func (*BreachAPI) DataClasses added in v1.0.4

func (b *BreachAPI) DataClasses() ([]string, *http.Response, error)

DataClasses are attribute of a record compromised in a breach. This method returns a list of strings with all registered data classes known to HIBP

type BreachOption added in v0.1.2

type BreachOption func(*BreachAPI)

BreachOption is an additional option the can be set for the BreachApiClient

func WithDomain added in v0.1.2

func WithDomain(d string) BreachOption

WithDomain sets the domain filter for the breaches API

func WithoutTruncate added in v0.1.2

func WithoutTruncate() BreachOption

WithoutTruncate disables the truncateResponse parameter in the breaches API This option only influences the BreachedAccount method

func WithoutUnverified added in v0.1.3

func WithoutUnverified() BreachOption

WithoutUnverified suppress unverified breaches from the query

type Client added in v0.1.1

type Client struct {
	PwnedPassAPI     *PwnedPassAPI         // Reference to the PwnedPassAPI API
	PwnedPassAPIOpts *PwnedPasswordOptions // Additional options for the PwnedPassAPI API

	BreachAPI *BreachAPI // Reference to the BreachAPI
	PasteAPI  *PasteAPI  // Reference to the PasteAPI
	// contains filtered or unexported fields
}

Client is the HIBP client object

func New added in v0.1.1

func New(options ...Option) Client

New creates and returns a new HIBP client object

func (*Client) HTTPReq added in v1.0.4

func (c *Client) HTTPReq(m, p string, q map[string]string) (*http.Request, error)

HTTPReq performs an HTTP request to the corresponding API

func (*Client) HTTPResBody added in v1.0.4

func (c *Client) HTTPResBody(m string, p string, q map[string]string) ([]byte, *http.Response, error)

HTTPResBody performs the API call to the given path and returns the response body as byte array

type HashMode added in v1.0.6

type HashMode int
const (
	// HashModeSHA1 is the default hash mode expecting SHA-1 hashes
	HashModeSHA1 HashMode = iota
	// HashModeNTLM represents the mode that expects and returns NTLM hashes
	HashModeNTLM
)

type Match added in v0.1.1

type Match struct {
	Hash  string // SHA1 hash of the matching password
	Count int64  // Represents the number of leaked accounts that hold/held this password
}

Match represents a match in the Pwned Passwords API

type Option added in v0.1.1

type Option func(*Client)

Option is a function that is used for grouping of Client options.

func WithAPIKey added in v1.0.4

func WithAPIKey(k string) Option

WithAPIKey set the optional API key to the Client object

func WithHTTPTimeout added in v1.0.4

func WithHTTPTimeout(t time.Duration) Option

WithHTTPTimeout overrides the default http client timeout

func WithPwnedNTLMHash added in v1.0.6

func WithPwnedNTLMHash() Option

WithPwnedNTLMHash sets the hash mode for the PwnedPasswords API to NTLM hashes

Note: This option only affects the generic methods like PwnedPassAPI.CheckPassword or PwnedPassAPI.ListHashesPassword. For any specifc method with the hash type in the method name, this option is ignored and the hash type of the function is forced

func WithPwnedPadding added in v0.1.2

func WithPwnedPadding() Option

WithPwnedPadding enables padding-mode for the PwnedPasswords API client

func WithRateLimitSleep added in v1.0.0

func WithRateLimitSleep() Option

WithRateLimitSleep let's the HTTP client sleep in case the API rate limiting hits (Defaults to fail)

func WithUserAgent added in v0.1.4

func WithUserAgent(a string) Option

WithUserAgent sets a custom user agent string for the HTTP client

type Paste added in v1.0.0

type Paste struct {
	// Source is the paste service the record was retrieved from. Current values are: Pastebin,
	// Pastie, Slexy, Ghostbin, QuickLeak, JustPaste, AdHocUrl, PermanentOptOut, OptOut
	Source string `json:"Source"`

	// ID of the paste as it was given at the source service. Combined with the "Source" attribute, this
	// can be used to resolve the URL of the paste
	ID string `json:"ID"`

	// Title of the paste as observed on the source site. This may be null and if so will be omitted from
	// the response
	Title string `json:"Title"`

	// Date is the date and time (precision to the second) that the paste was posted. This is taken directly
	// from the paste site when this information is available but may be null if no date is published
	Date time.Time `json:"Date"`

	// EmailCount is number of emails that were found when processing the paste. Emails are extracted by
	// using the regular expression \b[a-zA-Z0-9\.\-_\+]+@[a-zA-Z0-9\.\-_]+\.[a-zA-Z]+\b
	EmailCount int `json:"EmailCount"`
}

Paste represents a JSON response structure of the pastes API

type PasteAPI added in v1.0.4

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

PasteAPI is a HIBP pastes API client

Example (PastedAccount)

ExamplePasteAPI_pastedAccount is a code example to show how to fetch a specific paste based on its name from the HIBP pastes API using the PastedAccount() method

apiKey := os.Getenv("HIBP_API_KEY")
if apiKey == "" {
	panic("A API key is required for this API")
}
hc := New(WithAPIKey(apiKey))
pd, _, err := hc.PasteAPI.PastedAccount("account-exists@hibp-integration-tests.com")
if err != nil {
	panic(err)
}
for _, p := range pd {
	fmt.Printf("Your account was part of the %q paste\n", p.Title)
}
Output:

func (*PasteAPI) PastedAccount added in v1.0.4

func (p *PasteAPI) PastedAccount(a string) ([]*Paste, *http.Response, error)

PastedAccount returns a single breached site based on its name

type PwnedPassAPI added in v1.0.4

type PwnedPassAPI struct {

	// Query parameter map for additional query parameters passed to request
	ParamMap map[string]string
	// contains filtered or unexported fields
}

PwnedPassAPI is a HIBP Pwned Passwords API client

Example (CheckNTLM)

ExamplePwnedPassAPI_checkNTLM is a code example to show how to check a given password NTLM hash against the HIBP passwords API using the CheckNTLM() method

hc := New()
pwHash := "0cb6948805f797bf2a82807973b89537" // represents the PW: "test"
m, _, err := hc.PwnedPassAPI.CheckNTLM(pwHash)
if err != nil {
	panic(err)
}
if m != nil && m.Count != 0 {
	fmt.Printf("Your password with the hash %q was found %d times in the pwned passwords DB\n",
		m.Hash, m.Count)
	
Output:

Your password with the hash "0cb6948805f797bf2a82807973b89537" was found 86495 times in the pwned passwords DB
Example (CheckSHA1)

ExamplePwnedPassAPI_checkSHA1 is a code example to show how to check a given password SHA1 hash against the HIBP passwords API using the CheckSHA1() method

hc := New()
pwHash := "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" // represents the PW: "test"
m, _, err := hc.PwnedPassAPI.CheckSHA1(pwHash)
if err != nil {
	panic(err)
}
if m != nil && m.Count != 0 {
	fmt.Printf("Your password with the hash %q was found %d times in the pwned passwords DB\n",
		m.Hash, m.Count)
	
Output:

Your password with the hash "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" was found 86495 times in the pwned passwords DB

func (*PwnedPassAPI) CheckNTLM added in v1.0.6

func (p *PwnedPassAPI) CheckNTLM(h string) (*Match, *http.Response, error)

CheckNTLM checks the Pwned Passwords database against a given NTLM hash of a password string

func (*PwnedPassAPI) CheckPassword added in v1.0.4

func (p *PwnedPassAPI) CheckPassword(pw string) (*Match, *http.Response, error)

CheckPassword checks the Pwned Passwords database against a given password string

This method will automatically decide whether the hash is in SHA-1 or NTLM format based on the Option when the Client was initialized

Example

ExamplePwnedPassAPI_CheckPassword is a code example to show how to check a given password against the HIBP passwords API

hc := New()
m, _, err := hc.PwnedPassAPI.CheckPassword("test")
if err != nil {
	panic(err)
}
if m != nil && m.Count != 0 {
	fmt.Printf("Your password with the hash %q was found %d times in the pwned passwords DB\n",
		m.Hash, m.Count)
	
Output:

Your password with the hash "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" was found 86495 times in the pwned passwords DB
Example (WithPadding)

ExamplePwnedPassAPI_CheckPassword_withPadding is a code example to show how to check a given password against the HIBP passwords API with the WithPadding() option set

hc := New(WithPwnedPadding())
m, _, err := hc.PwnedPassAPI.CheckPassword("test")
if err != nil {
	panic(err)
}
if m != nil && m.Count != 0 {
	fmt.Printf("Your password with the hash %q was found %d times in the pwned passwords DB\n",
		m.Hash, m.Count)
	
Output:

Your password with the hash "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3" was found 86495 times in the pwned passwords DB

func (*PwnedPassAPI) CheckSHA1 added in v1.0.4

func (p *PwnedPassAPI) CheckSHA1(h string) (*Match, *http.Response, error)

CheckSHA1 checks the Pwned Passwords database against a given SHA1 checksum of a password string

func (*PwnedPassAPI) ListHashesNTLM added in v1.0.6

func (p *PwnedPassAPI) ListHashesNTLM(h string) ([]Match, *http.Response, error)

ListHashesNTLM checks the Pwned Password API endpoint for all hashes based on a given NTLM hash and returns the a slice of Match as well as the http.Response

NOTE: If the `WithPwnedPadding` option is set to true, the returned list will be padded and might contain junk data

func (*PwnedPassAPI) ListHashesPassword added in v1.0.4

func (p *PwnedPassAPI) ListHashesPassword(pw string) ([]Match, *http.Response, error)

ListHashesPassword checks the Pwned Password API endpoint for all hashes based on a given password string and returns the a slice of Match as well as the http.Response

This method will automatically decide whether the hash is in SHA-1 or NTLM format based on the Option when the Client was initialized

NOTE: If the `WithPwnedPadding` option is set to true, the returned list will be padded and might contain junk data

func (*PwnedPassAPI) ListHashesPrefix added in v1.0.4

func (p *PwnedPassAPI) ListHashesPrefix(pf string) ([]Match, *http.Response, error)

ListHashesPrefix checks the Pwned Password API endpoint for all hashes based on a given SHA-1 or NTLM hash prefix and returns the a slice of Match as well as the http.Response

To decide which HashType is queried for, make sure to set the appropriate HashMode in the PwnedPassAPI struct

NOTE: If the `WithPwnedPadding` option is set to true, the returned list will be padded and might contain junk data

func (*PwnedPassAPI) ListHashesSHA1 added in v1.0.4

func (p *PwnedPassAPI) ListHashesSHA1(h string) ([]Match, *http.Response, error)

ListHashesSHA1 checks the Pwned Password API endpoint for all hashes based on a given SHA1 checksum and returns the a slice of Match as well as the http.Response

NOTE: If the `WithPwnedPadding` option is set to true, the returned list will be padded and might contain junk data

type PwnedPasswordOptions added in v0.1.2

type PwnedPasswordOptions struct {
	// HashMode controls whether the provided hash is in SHA-1 or NTLM format
	// HashMode defaults to SHA-1 and can be overridden using the WithNTLMHash() Option
	// See: https://haveibeenpwned.com/API/v3#PwnedPasswordsNTLM
	HashMode HashMode

	// WithPadding controls if the PwnedPassword API returns with padding or not
	// See: https://haveibeenpwned.com/API/v3#PwnedPasswordsPadding
	WithPadding bool
}

PwnedPasswordOptions is a struct of additional options for the PP API

Directories

Path Synopsis
Package md4 implements the MD4 hash algorithm as defined in RFC 1320.
Package md4 implements the MD4 hash algorithm as defined in RFC 1320.

Jump to

Keyboard shortcuts

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