Skip to content

Commit

Permalink
Add PCI card information check
Browse files Browse the repository at this point in the history
  • Loading branch information
otterobert committed Sep 19, 2024
1 parent 7e313d0 commit 1585fbd
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 36 deletions.
7 changes: 6 additions & 1 deletion src/node-agent/pkg/ebpf/eventreader.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ func (e *EventReader) Start() {

// Process the event
cInfo := e.containerMap[pidNamespaceInode]

Check failure on line 76 in src/node-agent/pkg/ebpf/eventreader.go

View workflow job for this annotation

GitHub Actions / golangci-lint

printf: github.com/sirupsen/logrus.Printf does not support error-wrapping directive %w (govet)
eventContext := types.EventContext{Event: event, Data: data, Container: cInfo}
eventContext := types.EventContext{
Event: event,
Data: data,
Container: cInfo,
Metadata: &types.EventMetadata{},
}
err = eventparser.ProcessEvent(eventContext)
if err != nil {
logrus.Printf("error processing event: %s", err)
Expand Down
14 changes: 14 additions & 0 deletions src/node-agent/pkg/ebpf/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ const (
BpfEventTypeURetProbe BpfEventType = "URetProbe"
)

type EventTag string

const (
EventTagPCI EventTag = "PCI"
EventTagPII EventTag = "PII"
)

type BpfProgram struct {
Type BpfEventType
Symbol string
Expand All @@ -29,8 +36,15 @@ type BpfProgram struct {
Address uint64
}

// EventContext contains the data and metadata for a BPF event - used for parsing and handling of events
type EventContext struct {
Data []byte
Event otrzebpf.BpfSslEventT
Container container.ContainerInfo
Metadata *EventMetadata // Metadata for the event - this is editable by parsers
}

// EventMetadata contains the parsed metadata for a BPF event
type EventMetadata struct {
Tags map[EventTag]bool
}
6 changes: 6 additions & 0 deletions src/node-agent/pkg/eventparser/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
ebpftypes "github.com/otterize/network-mapper/src/node-agent/pkg/ebpf/types"
"github.com/otterize/network-mapper/src/node-agent/pkg/eventparser/httprequest"
"github.com/otterize/network-mapper/src/node-agent/pkg/eventparser/httpresponse"
"github.com/otterize/network-mapper/src/node-agent/pkg/eventparser/pcidata"
"github.com/otterize/network-mapper/src/node-agent/pkg/eventparser/types"
"github.com/sirupsen/logrus"
)
Expand All @@ -21,6 +22,11 @@ func init() {
// Initialize HTTP response parser
httpResponseParser := &httpresponse.Parser{}
parsers["httpresponse"] = httpResponseParser

// Initialize PCI data parser
pciParser := &pcidata.Parser{}
pciParser.RegisterHandler(pcidata.ContainsPaymentInformation)
parsers["pci"] = pciParser
}

func ProcessEvent(ctx ebpftypes.EventContext) error {
Expand Down
77 changes: 77 additions & 0 deletions src/node-agent/pkg/eventparser/pcidata/creditcard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package pcidata

import (
"strings"
"unicode"
)

// List of card prefixes and their corresponding lengths
var cardPrefixes = map[string][]int{
"34": {15}, // AMEX
"37": {15}, // AMEX
"300": {15}, // Diners
"301": {15}, // Diners
"302": {15}, // Diners
"303": {15}, // Diners
"36": {15}, // Diners
"38": {15}, // Diners
"6011": {16}, // Discover
"2014": {16}, // Enroute
"2149": {16}, // Enroute
"2100": {16}, // JCB 15
"1800": {16}, // JCB 15
"3088": {16}, // JCB 16
"3096": {16}, // JCB 16
"3112": {16}, // JCB 16
"3158": {16}, // JCB 16
"3337": {16}, // JCB 16
"3528": {16}, // JCB 16
"51": {16}, // MasterCard
"52": {16}, // MasterCard
"53": {16}, // MasterCard
"54": {16}, // MasterCard
"55": {16}, // MasterCard
"4": {13, 16}, // Visa
"4539": {16}, // Visa
"4556": {16}, // Visa
"4916": {16}, // Visa
"4532": {16}, // Visa
"4929": {16}, // Visa
"40240071": {16}, // Visa
"4485": {16}, // Visa
"4716": {16}, // Visa
"8699": {13, 16}, // Voyager
}

// Matches the following card formats:
// 4111111111111111
// 4111 1111 1111 1111
// 4111-1111-1111-1111
// 4111.1111.1111.1111
// **** **** **** 1111
const cardRegex = `(?:(\d|\*)[ -\.]*?){13,19}`

// Normalize card number by removing non-digit characters (if separated by spaces, dots, or dashes)
func normalizeCardNumber(card string) string {
var normalized string
for _, char := range card {
if unicode.IsDigit(char) {
normalized += string(char)
}
}
return normalized
}

// Check if the card number is valid based on prefixes and length
func isValidCardNumber(card string) bool {
for prefix, lengths := range cardPrefixes {
if strings.HasPrefix(card, prefix) {
for _, length := range lengths {
if len(card) == length {
return true
}
}
}
}
return false
}
32 changes: 13 additions & 19 deletions src/node-agent/pkg/eventparser/pcidata/handlers.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
package pcidata

import (
"github.com/otterize/iamlive/iamlivecore"
"github.com/otterize/intents-operator/src/shared/errors"
ebpftypes "github.com/otterize/network-mapper/src/node-agent/pkg/ebpf/types"
"io"
"net/http"
"regexp"
)

const AWSHost = "amazonaws.com"
func ContainsPaymentInformation(ctx ebpftypes.EventContext, data string) error {
// Regular expression for possible credit card patterns (13-19 digits, allowing spaces, dashes, or dots as separators)
re := regexp.MustCompile(cardRegex)

func HandleAwsRequest(ctx ebpftypes.EventContext, req *http.Request) error {
body, err := io.ReadAll(req.Body)
if err != nil {
return errors.Wrap(err)
}

// Check if the event is an AWS request - called to host "amazonaws.com"
if req.Host != AWSHost {
return nil
}
// Find all matches
matches := re.FindAllString(data, -1)

// Check if the event is an egress event
if ebpftypes.Direction(ctx.Event.Meta.Direction) != ebpftypes.DirectionEgress {
return nil
// Filter matches based on valid credit card prefix and length
for _, match := range matches {
normalized := normalizeCardNumber(match)
if isValidCardNumber(normalized) {
// Set PCI tag
ctx.Metadata.Tags[ebpftypes.EventTagPCI] = true
}
}

iamlivecore.HandleAWSRequest(req, body, 200)
return nil
}
32 changes: 16 additions & 16 deletions src/node-agent/pkg/eventparser/pcidata/parser.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
package pcidata

import (
"bufio"
"bytes"
"fmt"
"github.com/otterize/intents-operator/src/shared/errors"
ebpftypes "github.com/otterize/network-mapper/src/node-agent/pkg/ebpf/types"
"github.com/otterize/network-mapper/src/node-agent/pkg/eventparser/types"
"github.com/sirupsen/logrus"
"net/http"
"unicode"
)

type Parser struct {
handlers []types.DataHandler[*http.Request]
handlers []types.DataHandler[string]
}

// Parse parses the HTTP request from the given data
// Parse parses the data to check if its plain text
func (p *Parser) Parse(ctx ebpftypes.EventContext) (interface{}, error) {
reader := bufio.NewReader(bytes.NewReader(ctx.Data))
req, err := http.ReadRequest(reader)
if err != nil {
return nil, errors.Wrap(err)
for _, b := range ctx.Data {
// Check if the byte is a printable character or common whitespace (ASCII values 32-126 or newline/carriage return)
if b > unicode.MaxASCII || (!unicode.IsPrint(rune(b)) && b != '\n' && b != '\r' && b != '\t') {
return nil, fmt.Errorf("data is not plain text")
}
}
logrus.Debugf("Got plain text data: %s\n", string(ctx.Data))

req.RemoteAddr = ctx.Container.PodIP

logrus.Debugf("Got HTTP request: %s\n", string(ctx.Data))
return string(ctx.Data), nil
}

return req, nil
// RegisterHandler registers a handler for PCI data
func (p *Parser) RegisterHandler(handler types.DataHandler[string]) {
p.handlers = append(p.handlers, handler)
}

// RunHandlers executes all registered handlers on the parsed data
func (p *Parser) RunHandlers(ctx ebpftypes.EventContext, data interface{}) error {
req, ok := data.(*http.Request)
req, ok := data.(string)
if !ok {
return fmt.Errorf("invalid type: expected *http.Request")
return fmt.Errorf("invalid type: expected string")
}

for _, handler := range p.handlers {
Expand Down

0 comments on commit 1585fbd

Please sign in to comment.