Skip to content
This repository was archived by the owner on Jan 13, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 91 additions & 1 deletion cloud-inquisitor/aws_cloudfront_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,58 @@ func (cf *AWSCloudFrontDistributionResource) createDistributionEntries() error {
return nil
}

func (cf *AWSCloudFrontDistributionResource) deleteDistributionEntries() error {
db, err := database.NewDBConnection()
defer db.Close()
if err != nil {
cf.logger.WithFields(cf.GetMetadata()).Error(err.Error())
return err
}

// get account
account := model.Account{AccountID: cf.AccountID}
err = db.FirstOrCreate(&account, account).Error
if err != nil {
cf.logger.WithFields(cf.GetMetadata()).Error(err.Error())
return err
}
cf.logger.WithFields(cf.GetMetadata()).Debugf("account: %#v", account)

distro := model.Distribution{DistributionID: cf.DistributionID, Domain: cf.DomainName, AccountID: account.ID}
err = db.Delete(&distro).Error
if err != nil {
cf.logger.WithFields(cf.GetMetadata()).Error(err.Error())
return err
}

// delete origins
for _, cfOrigin := range cf.Origins {
origin := model.Origin{
OriginID: cfOrigin.ID,
Domain: cfOrigin.Domain,
DistributionID: distro.ID,
}
err = db.Delete(&origin).Error
if err != nil {
cf.logger.WithFields(cf.GetMetadata()).Error(err.Error())
return err
}

// delete origin groups
for _, cfGroup := range cf.OriginGroups {
group := model.OriginGroup{
GroupID: cfGroup.ID,
DistributionID: distro.ID,
}
err = db.Delete(&group).Error
if err != nil {
cf.logger.WithFields(cf.GetMetadata()).Error(err.Error())
return err
}

return nil
}

func (cf *AWSCloudFrontDistributionResource) updateDistributionEntries() error {
db, err := database.NewDBConnection()
defer db.Close()
Expand Down Expand Up @@ -496,6 +548,8 @@ func (cf *AWSCloudFrontDistributionHijackableResource) PublishState() error {
switch cf.EventName {
case "CreateDistribution":
return cf.createDistributionEntries()
case "DeleteDistribution":
return cf.deleteDistributionEntries()
case "UpdateDistribution":
return cf.updateDistributionEntries()
default:
Expand All @@ -506,5 +560,41 @@ func (cf *AWSCloudFrontDistributionHijackableResource) PublishState() error {
}

func (cf *AWSCloudFrontDistributionHijackableResource) AnalyzeForHijack() (*model.HijackableResourceChain, error) {
return &model.HijackableResourceChain{}, nil
switch cf.EventName {
case "DeleteDistribution":
return cf.analyzedeleteDistributionEntries()
default:
return &model.HijackableResourceChain{}, nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a check here to see if its possible to create a cloud front distribution with an origin that points to a resource that doesnt exist. If this is possible, we need to check for this.

Need to check here to see if it is possible to create a distro that point to a resource that exists but we dont own.

Both cases need to have analysis code.

This may just need to be its own ticket.

}
}

func (cf *AWSCloudFrontDistributionHijackableResourc) analyzedeleteDistributionEntries(*model.HijackableResourceChain, error) {
resolver, err := graph.NewResolver()
if err != nil {
cf.GetLogger().Errorf("error creating a new resolver to evaluate cloudfront hijacks: %v", err.Error())
return &model.HijackableResourceChain{}, err
}

domains := make([]string, len(cf.Origins))
for i, ori := range cf.Origins {
domain[i] = ori.Domain
}

ctx := context.Background()
chain, err := resolver.Query().HijackChainByDomain(
ctx,
fmt.Sprintf(
"cloudfront-%s-%s-%s",
cf.AccountID,
cf.DistributionID,
cf.DomainName,
),
domains,
model.TypeDistribution,
)
if err != nil {
eb.GetLogger().Errorf("error querying graph for cloudfront hijack analysis: %v", err.Error())
}

return chain, err
}
79 changes: 79 additions & 0 deletions cloud-inquisitor/graph/schema.resolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,51 @@ func (r *queryResolver) ElasticbeanstalkByEndpoint(ctx context.Context, endpoint
return &beanstalk, err
}

func (r *queryResolver) GetCloudFrontUpstreamHijack(ctx context.Context, domains []string) ([]*model.HijackableResource, error) {
hijackChain := []*model.HijackableResource{}

// 1. check origins
for _, domain := range domains {
origins, err := r.Query().PointedAtByOrigin(ctx, domain)
if err != nil {
log.Errorf("error looking up domain %s", domain)
continue
}

for _, origin := range origins {
completeOrigin, err := r.Query().Origin(ctx, origin.OriginID)
if err != nil {
log.Errorf("error looking up origin with id %v", origin.OriginID)
continue
}

var account model.Account
err = r.DB.First(&account, origin.OriginID).Error
if err != nil {
log.Errorf("unable to get account for origin %#v", *completeOrigin)
continue
}
hijackChain = append(hijackChain, &model.HijackableResource{
ID: completeOrigin.OriginID,
Type: model.TypeDistribution,
Account: account.AccountID,
Value: &model.Value{
ValueID: completeOrigin.Domain,
},
})
}
}

if log.GetLevel() == log.DebugLevel {
log.Debugf("found hijack chain for endpoints: %#v", domains)
for idx, chainElement := range hijackChain {
log.Debugf("%v: %#v", idx, *chainElement)
}
}

return hijackChain, nil
}

func (r *queryResolver) GetElasticbeanstalkUpstreamHijack(ctx context.Context, endpoints []string) ([]*model.HijackableResource, error) {
// elasticbeanstalks are endpoints are only fronted by other resources
hijackChain := []*model.HijackableResource{}
Expand Down Expand Up @@ -554,6 +599,40 @@ func (r *queryResolver) GetElasticbeanstalkUpstreamHijack(ctx context.Context, e

func (r *queryResolver) HijackChainByDomain(ctx context.Context, id string, domains []string, typeArg model.Type) (*model.HijackableResourceChain, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should have its params changed.

switch typeArg {
case model.TypeDistribution:
cf, err := r.Query().Distribution(ctx, id)
if err != nil {
log.Errorf("error getting cloudfront: %v", err.Error())
return nil, err
}

var account *model.Account = nil
err = r.DB.Find(account, cf.AccountID).Error
if err != nil {
log.Errorf("unable to find account for cloudfront distribution: %#v", *cf)
return nil, err
}

chain, err := r.Query().GetCloudFrontUpstreamHijack(ctx, domains)
if err != nil {
log.Errorf("recieved error when querying for cloudfront distribution hijacks: %v", err.Error())
return nil, err
}

return &model.HijackableResourceChain{
ID: id,
Resource: &model.HijackableResource{
ID: id,
Account: account.AccountID,
Type: model.TypeElasticbeanstalk,
Value: &model.Value{
ValueID: cf.Domain,
},
},
Upstream: chain,
Downstream: []*model.HijackableResource{},
}, err

case model.TypeElasticbeanstalk:
/*
ID string `json:"id"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
],
"eventName": [
"CreateDistribution",
"DeleteDistribution",
"UpdateDistribution"
]
}
Expand Down