model

package
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package model holds the types shared by the scanner, the detectors and the report writers.

Index

Constants

View Source
const (
	SampleSpread    = "spread"     // one row from each slice of the key range
	SampleFirstRows = "first_rows" // the table's or the key's first rows only
	SampleAllRows   = "all_rows"   // every row
	SampleThin      = "thin"       // gaps in the key left under half the slices with a row of their own
	SampleCut       = "cut"        // a statement failed part-way
)

How a production sample was taken.

View Source
const (
	LeakRead         = "read"           // read whole
	LeakStopped      = "stopped"        // a time limit or an error stopped it part-way
	LeakNotRead      = "not_read"       // the time limit came before it started
	LeakNotOnStaging = "not_on_staging" // the table or column doesn't exist there
	LeakUnreadable   = "unreadable"     // it can't be read there: a view, or now binary
)

The states of a column on staging.

View Source
const (
	RelDeclared   = "declared"
	RelConfirmed  = "confirmed"
	RelLikely     = "likely"
	RelWeak       = "weak"
	RelUnverified = "unverified"
)

Relationship statuses.

Variables

This section is empty.

Functions

func LeakExcept added in v0.12.0

func LeakExcept(except, location string) bool

LeakExcept reports whether a location given to --fail-except covers a location: the whole of it, its column or its table, in any letter case.

func LeakLocation added in v0.12.0

func LeakLocation(table, column, metaKey string) string

LeakLocation renders where a column is, as reports print it and --fail-except takes it: wp_users.user_email, or wp_usermeta.meta_value[billing_phone].

Types

type Category

type Category string

Category is the kind of sensitive data a finding is about.

const (
	CatEmail        Category = "email"
	CatPhone        Category = "phone"
	CatPersonName   Category = "person_name"
	CatUsername     Category = "username"
	CatAddress      Category = "address"
	CatPostcode     Category = "postcode"
	CatCity         Category = "city"
	CatRegion       Category = "region"
	CatCountry      Category = "country"
	CatDateOfBirth  Category = "date_of_birth"
	CatGender       Category = "gender"
	CatCompany      Category = "company"
	CatNationalID   Category = "national_id"
	CatBankAccount  Category = "bank_account"
	CatCardNumber   Category = "card_number"
	CatCardMeta     Category = "card_meta"
	CatPaymentToken Category = "payment_token"
	CatPasswordHash Category = "password_hash"
	CatSecret       Category = "secret"
	CatIPAddress    Category = "ip_address"
	CatUserAgent    Category = "user_agent"
	CatGeo          Category = "geo_location"
	CatWebsite      Category = "website"
	CatSessionData  Category = "session_data"
	CatFreeText     Category = "free_text"
	CatDeviceID     Category = "device_id"
)

func (Category) Info

func (c Category) Info() CategoryInfo

Info returns the description of a category.

func (Category) Label

func (c Category) Label() string

Label is the human-readable name of the category.

type CategoryInfo

type CategoryInfo struct {
	Label    string
	Severity Severity
	Mask     string
}

CategoryInfo describes a category: a label for people, the default severity and the masking strategy a starter config suggests.

type Column

type Column struct {
	Name       string
	Position   int
	DataType   string // lower case, e.g. varchar, bigint, longtext
	ColumnType string // full type, e.g. "bigint(20) unsigned"
	Nullable   bool
	// MaxLength is how many characters a string column holds, or bytes for a
	// binary one (CHARACTER_MAXIMUM_LENGTH). OctetLength is how many bytes
	// it holds (CHARACTER_OCTET_LENGTH). Both are 0 for numbers, dates and
	// other types that aren't strings; ENUM and SET columns have them.
	MaxLength   int64
	OctetLength int64
	// Charset and Collation are a string column's character set and
	// collation, such as utf8mb4 and utf8mb4_unicode_520_ci, ENUM and SET
	// columns included. They are empty for other types, binary strings
	// included.
	Charset   string
	Collation string
	Key       string // PRI, UNI, MUL
	Extra     string // auto_increment, VIRTUAL GENERATED, ...
	Comment   string
}

Column is one column of a table.

func (*Column) AutoIncrement

func (c *Column) AutoIncrement() bool

AutoIncrement reports whether the column is filled by the server.

type Confidence

type Confidence int

Confidence says how sure the scanner is that a finding is real.

const (
	ConfidenceLow Confidence = iota + 1
	ConfidenceMedium
	ConfidenceHigh
)

func (Confidence) MarshalText

func (c Confidence) MarshalText() ([]byte, error)

MarshalText encodes the confidence by name in JSON output.

func (Confidence) String

func (c Confidence) String() string

type Finding

type Finding struct {
	Table  string `json:"table"`
	Column string `json:"column"`
	// MetaKey is a key of a key/value table, or a pattern such as
	// um_cache_userdata_* where * stands for the part that varies between
	// keys. The varying part may itself be data, so it is never shown.
	MetaKey string `json:"meta_key,omitempty"`
	// KeyName marks a finding about the key names themselves: Column is
	// the key column, and the part of the names matched by * holds data.
	KeyName bool `json:"key_name,omitempty"`
	// Keys is how many keys a pattern stands for; KeysPartial says the
	// count is a lower bound because the keys were sampled, not listed.
	Keys        int    `json:"keys,omitempty"`
	KeysPartial bool   `json:"keys_partial,omitempty"`
	Path        string `json:"path,omitempty"`
	// Where, when set, limits the finding to the rows that match it, such
	// as the privacy requests among WordPress posts.
	Where      string     `json:"where,omitempty"`
	Category   Category   `json:"category"`
	Severity   Severity   `json:"severity"`
	Confidence Confidence `json:"confidence"`
	Sampled    int        `json:"sampled"`
	Matched    int        `json:"matched"`
	Reasons    []string   `json:"reasons"`
	Mask       string     `json:"suggested_mask"`
	RowMasks   []RowMask  `json:"suggested_row_masks,omitempty"`
	Source     string     `json:"source"`
	Note       string     `json:"note,omitempty"`
}

Finding is one column, meta key or JSON path that holds sensitive data.

func (Finding) KeyCount added in v0.3.0

func (f Finding) KeyCount() string

KeyCount renders how many keys a pattern stands for: "1,541 keys", or "at least 20 keys" when the keys were sampled rather than listed.

func (Finding) Location

func (f Finding) Location() string

Location renders where a finding is, e.g. wp_usermeta.meta_value[billing_phone].

type ForeignKey

type ForeignKey struct {
	Name       string
	Columns    []string
	RefSchema  string
	RefTable   string
	RefColumns []string
}

ForeignKey is one declared foreign key.

type Index

type Index struct {
	Name    string
	Unique  bool
	Type    string // BTREE, HASH, FULLTEXT or SPATIAL (information_schema INDEX_TYPE)
	Columns []string
	// SubParts holds, per column, the length of an indexed prefix, or 0
	// when the whole column is indexed (information_schema SUB_PART).
	SubParts []int
}

Index is one index of a table.

type IndexUse added in v0.3.0

type IndexUse struct {
	Found  bool // some index starts with the column
	Full   bool // one of them indexes the whole column, not a prefix of it
	Unique bool // a unique index covers exactly this column, in full
}

IndexUse says how a column can be looked up through the table's indexes.

type LeakAllowed added in v0.12.0

type LeakAllowed struct {
	Domains       []string `json:"domains"`
	Addresses     int      `json:"addresses"`
	ValuesSkipped int64    `json:"values_skipped"`
}

LeakAllowed says what --allow-email kept out of a check: domains by name, and exact addresses only as a count, since an address is a real person's.

type LeakColumn added in v0.12.0

type LeakColumn struct {
	Table    string   `json:"table"`
	Column   string   `json:"column"`
	MetaKey  string   `json:"meta_key,omitempty"`
	Kind     LeakKind `json:"kind"`
	Severity Severity `json:"severity"`
	State    string   `json:"state"`
	// StoppedBy says what stopped the column: "--max-time" or an error's
	// description, which never quotes the server's message.
	StoppedBy string `json:"stopped_by,omitempty"`
	Excepted  bool   `json:"excepted_from_fail_on,omitempty"`
	// Line is the report's line about this column.
	Line string `json:"line"`

	// From production.
	Sample          string `json:"sample"`
	Exact           bool   `json:"every_value_sampled,omitempty"`
	Sampled         int    `json:"sampled"`
	EstimatedValues int64  `json:"production_values_estimate"`

	// From staging.
	Found         int   `json:"found"`
	Rows          int64 `json:"rows_holding_them"`
	Values        int64 `json:"values_read"`
	ValuesSkipped int64 `json:"values_skipped_by_allow_email,omitempty"`
	RowsRead      int64 `json:"rows_read"`
	RowsEstimate  int64 `json:"rows_estimate"`

	// What the numbers say, each 0 where it doesn't apply.
	ShownAt95      float64 `json:"real_values_shown_at_95_percent,omitempty"`
	CatchIfAllReal float64 `json:"chance_of_catching_if_all_read_were_real,omitempty"`
	ChanceMatches  float64 `json:"matches_chance_could_explain,omitempty"`
	EstimateInAll  int64   `json:"estimated_real_values_in_all,omitempty"`
}

LeakColumn is what a check found for one kind of value in one column or key.

func (LeakColumn) Location added in v0.12.0

func (c LeakColumn) Location() string

Location renders where the column is.

type LeakHashesInfo added in v0.12.0

type LeakHashesInfo struct {
	Database    string    `json:"database"`
	CreatedAt   time.Time `json:"created_at"`
	ToolVersion string    `json:"tool_version"`
	SampleRows  int       `json:"sample_rows"`
}

LeakHashesInfo says where a check's sampled values came from.

type LeakKind added in v0.12.0

type LeakKind string

LeakKind is a kind of value the staging leak check counts: one that two people are very unlikely to share by chance.

const (
	LeakEmail        LeakKind = "email"
	LeakPhone        LeakKind = "phone"
	LeakIBAN         LeakKind = "iban"
	LeakNationalID   LeakKind = "national_id"
	LeakPaymentToken LeakKind = "payment_token"
	LeakPasswordHash LeakKind = "password_hash"
	LeakSecret       LeakKind = "secret"
)

The kinds the leak check counts.

func (LeakKind) Label added in v0.12.0

func (k LeakKind) Label() string

Label is the kind's name in reports.

func (LeakKind) Severity added in v0.12.0

func (k LeakKind) Severity() Severity

Severity is how bad a match of this kind is. A secret is critical: its exact production value is on staging, whatever its format says.

type LeakLeftOut added in v0.12.0

type LeakLeftOut struct {
	Location string `json:"location"`
	Why      string `json:"why"`
	NotRead  bool   `json:"not_read,omitempty"`
	Excepted bool   `json:"excepted_from_fail_on,omitempty"`
}

LeakLeftOut is a flagged column or key that isn't compared, and why. NotRead marks one a rerun might read, such as a table the sample couldn't read; it fails a gate, unless Excepted.

type LeakResult added in v0.12.0

type LeakResult struct {
	Tool        string         `json:"tool"`
	Version     string         `json:"version"`
	GeneratedAt time.Time      `json:"generated_at"`
	Server      ServerInfo     `json:"server"`
	Database    string         `json:"database"`
	Hashes      LeakHashesInfo `json:"hashes"`
	Allowed     LeakAllowed    `json:"allowed"`
	Summary     LeakSummary    `json:"summary"`
	Columns     []LeakColumn   `json:"columns"`
	LeftOut     []LeakLeftOut  `json:"left_out"`
	Warnings    []string       `json:"warnings"`
	Limits      []string       `json:"limits"`
}

LeakResult is the outcome of a staging leak check. It holds names and counts only, never a value, a primary key or a row number.

func (*LeakResult) NothingRead added in v0.12.0

func (r *LeakResult) NothingRead() bool

NothingRead reports whether a check read nothing at all, so it knows nothing.

type LeakSummary added in v0.12.0

type LeakSummary struct {
	Columns        int      `json:"columns"`
	ColumnsRead    int      `json:"columns_read"`
	ColumnsWithHit int      `json:"columns_with_hits"`
	Sampled        int64    `json:"sampled"`
	Found          int64    `json:"found"`
	SampledInPart  int64    `json:"sampled_in_columns_read_in_part"`
	FoundInPart    int64    `json:"found_in_columns_read_in_part"`
	RowsRead       int64    `json:"rows_read"`
	NothingRead    bool     `json:"nothing_read"`
	Highest        Severity `json:"highest_severity"`
	DurationMillis int64    `json:"duration_ms"`
}

LeakSummary holds a check's headline numbers. Sampled and Found cover the columns read whole; SampledInPart and FoundInPart cover stopped columns.

type Platform

type Platform struct {
	Name    string   `json:"name"`
	Label   string   `json:"label"`
	Version string   `json:"version,omitempty"`
	Prefix  string   `json:"table_prefix,omitempty"`
	Details []string `json:"details,omitempty"`
}

Platform is an application the scanner recognised, such as WordPress.

type Relationship

type Relationship struct {
	ChildTable    string   `json:"child_table"`
	ChildColumns  []string `json:"child_columns"`
	ParentTable   string   `json:"parent_table"`
	ParentColumns []string `json:"parent_columns"`
	Source        string   `json:"source"`
	Status        string   `json:"status"`
	Checked       int      `json:"checked,omitempty"`
	Found         int      `json:"found,omitempty"`
	TypeColumn    string   `json:"type_column,omitempty"`
	TypeValue     string   `json:"type_value,omitempty"`
	Note          string   `json:"note,omitempty"`
}

Relationship links a child column to a parent key. Declared relationships come from foreign keys; the others are inferred and checked against data.

func (Relationship) Key

func (r Relationship) Key() string

Key identifies a relationship regardless of where it came from.

type Result

type Result struct {
	Tool          string         `json:"tool"`
	Version       string         `json:"version"`
	GeneratedAt   time.Time      `json:"generated_at"`
	Server        ServerInfo     `json:"server"`
	Database      string         `json:"database"`
	Platforms     []Platform     `json:"platforms"`
	Options       ScanOptions    `json:"options"`
	Summary       Summary        `json:"summary"`
	Tables        []TableSummary `json:"tables"`
	Findings      []Finding      `json:"findings"`
	SideEffects   []SideEffect   `json:"side_effects"`
	Relationships []Relationship `json:"relationships"`
	Warnings      []string       `json:"warnings"`
}

Result is the full outcome of a scan.

type RowMask added in v0.2.0

type RowMask struct {
	Where string `json:"where"` // e.g. post_type IN ('shop_order', 'shop_order_refund')
	Mask  string `json:"mask"`
	Note  string `json:"note,omitempty"`
}

RowMask suggests a different mask for some rows of a column, such as the orders among WordPress posts. For the rows that match Where, it replaces the finding's own suggestion.

type ScanOptions

type ScanOptions struct {
	SampleRows     int     `json:"sample_rows"`
	MetaSampleRows int     `json:"meta_sample_rows"`
	KeySampleRows  int     `json:"key_sample_rows"`
	Samples        bool    `json:"samples"`
	Preset         string  `json:"preset"`
	TimeoutSeconds float64 `json:"statement_timeout_seconds"`
}

ScanOptions records the settings a scan ran with.

type Schema

type Schema struct {
	Database string
	Tables   []*Table
	// contains filtered or unexported fields
}

Schema is what the scanner knows about one database.

func (*Schema) Table

func (s *Schema) Table(name string) *Table

Table looks a table up by name.

type ServerInfo

type ServerInfo struct {
	Flavor  string `json:"flavor"`
	Version string `json:"version"`
	Address string `json:"address"`
	User    string `json:"user"`
}

ServerInfo describes the database server that was scanned.

type Severity

type Severity int

Severity ranks how much harm a finding could do in a non-production copy.

const (
	SeverityNone Severity = iota
	SeverityLow
	SeverityMedium
	SeverityHigh
	SeverityCritical
)

func ParseSeverity

func ParseSeverity(s string) (Severity, error)

ParseSeverity accepts none, low, medium, high or critical.

func (Severity) MarshalText

func (s Severity) MarshalText() ([]byte, error)

MarshalText encodes the severity by name in JSON output.

func (Severity) String

func (s Severity) String() string

type SideEffect

type SideEffect struct {
	Platform string   `json:"platform"`
	Kind     string   `json:"kind"`
	Table    string   `json:"table"`
	Item     string   `json:"item,omitempty"`
	Severity Severity `json:"severity"`
	Summary  string   `json:"summary"`
	Count    int64    `json:"count,omitempty"`
	Fix      string   `json:"fix"`
}

SideEffect is something a plain copy would let staging do to real people: send them email, charge their cards, call their webhooks.

type Summary

type Summary struct {
	Tables             int            `json:"tables"`
	TablesSampled      int            `json:"tables_sampled"`
	Views              int            `json:"views"`
	RowsSampled        int64          `json:"rows_sampled"`
	TablesWithFindings int            `json:"tables_with_findings"`
	Findings           int            `json:"findings"`
	BySeverity         map[string]int `json:"by_severity"`
	ByCategory         map[string]int `json:"by_category"`
	Highest            Severity       `json:"highest_severity"`
	SideEffects        int            `json:"side_effects"`
	Relationships      int            `json:"relationships"`
	InferredConfirmed  int            `json:"inferred_relationships_confirmed"`
	DurationMillis     int64          `json:"duration_ms"`
}

Summary holds the headline numbers of a scan.

type Table

type Table struct {
	Name         string
	Type         string // BASE TABLE, VIEW, SYSTEM VERSIONED, SEQUENCE
	Engine       string
	RowsEstimate int64
	DataBytes    int64
	Comment      string
	Columns      []*Column
	PrimaryKey   []string
	Indexes      []Index
	ForeignKeys  []ForeignKey
	// contains filtered or unexported fields
}

Table is one table or view.

func (*Table) Column

func (t *Table) Column(name string) *Column

Column looks a column up by name, ignoring case.

func (*Table) HasIndexOn

func (t *Table) HasIndexOn(column string) bool

HasIndexOn reports whether some index starts with the given column.

func (*Table) IsData

func (t *Table) IsData() bool

IsData reports whether the table holds rows the scanner can sample.

func (*Table) IsView

func (t *Table) IsView() bool

IsView reports whether the table is a view.

func (*Table) KeyIndex added in v0.3.0

func (t *Table) KeyIndex(column string) IndexUse

KeyIndex describes the indexes that start with a column.

func (*Table) SinglePK

func (t *Table) SinglePK() *Column

SinglePK returns the primary key column when the key has exactly one column.

type TableSummary

type TableSummary struct {
	Name         string   `json:"name"`
	Kind         string   `json:"kind"`
	RowsEstimate int64    `json:"rows_estimate"`
	RowsSampled  int      `json:"rows_sampled"`
	Findings     int      `json:"findings"`
	Highest      Severity `json:"highest_severity"`
	KeyColumn    string   `json:"key_column,omitempty"`
	ValueColumn  string   `json:"value_column,omitempty"`
	Keys         int      `json:"keys,omitempty"` // distinct keys read in a key/value table
	// HiddenKeys counts the keys with confident findings that reports show
	// as "(key hidden)": their names may hold data, so no rule names them.
	HiddenKeys   int    `json:"hidden_keys,omitempty"`
	Action       string `json:"suggested_action,omitempty"`
	ActionReason string `json:"action_reason,omitempty"`
	// PossibleAction is weaker than Action: a guess, such as emptying a
	// table that looks like a cache, which the user should confirm. Tools
	// that act on suggested_action never see it.
	PossibleAction       string `json:"possible_action,omitempty"`
	PossibleActionReason string `json:"possible_action_reason,omitempty"`
	Error                string `json:"error,omitempty"`
	// ReadFailed says a statement reading this key/value table's keys failed,
	// so some keys may have gone unjudged. The warnings say which statement.
	ReadFailed bool `json:"read_failed,omitempty"`
}

TableSummary is what the report says about one table.

Jump to

Keyboard shortcuts

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