Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added in adapters of sns, sqs #1208

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
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
55 changes: 55 additions & 0 deletions internal/adapters/cloud/aws/sns/sns.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package sns
import (
aws2 "github.com/aquasecurity/defsec/internal/adapters/cloud/aws"
"github.com/aquasecurity/defsec/pkg/concurrency"
"github.com/aquasecurity/defsec/pkg/providers/aws/iam"
"github.com/aquasecurity/defsec/pkg/providers/aws/sns"
"github.com/aquasecurity/defsec/pkg/state"
"github.com/aquasecurity/defsec/pkg/types"
snsapi "github.com/aws/aws-sdk-go-v2/service/sns"
snsTypes "github.com/aws/aws-sdk-go-v2/service/sns/types"
"github.com/liamg/iamgo"
)

type adapter struct {
Expand Down Expand Up @@ -38,6 +40,11 @@ func (a *adapter) Adapt(root *aws2.RootAdapter, state *state.State) error {
return err
}

state.AWS.SNS.Subscriptions, err = a.getSubscriptions()
if err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -82,6 +89,54 @@ func (a *adapter) adaptTopic(topic snsTypes.Topic) (*sns.Topic, error) {
t.Encryption.KMSKeyID = types.String(kmsKeyID, topicMetadata)
}

if policy, ok := topicAttributes.Attributes["Policy"]; ok {
iampolicy, err := iamgo.ParseString(policy)
if err == nil {
t.Policy = append(t.Policy, iam.Policy{
Metadata: topicMetadata,
Name: types.StringDefault("", topicMetadata),
Document: iam.Document{
Metadata: topicMetadata,
Parsed: *iampolicy,
},
Builtin: types.Bool(false, topicMetadata),
})
}
}

return t, nil

}

func (a *adapter) getSubscriptions() (subscriptions []sns.Subscription, err error) {

a.Tracker().SetServiceLabel("Discovering SNS subscriptions...")
var apiSubscriptions []snsTypes.Subscription
var input snsapi.ListSubscriptionsInput

for {
output, err := a.client.ListSubscriptions(a.Context(), &input)
if err != nil {
return nil, err
}
apiSubscriptions = append(apiSubscriptions, output.Subscriptions...)
a.Tracker().SetTotalResources(len(apiSubscriptions))
if output.NextToken == nil {
break
}
input.NextToken = output.NextToken
}

a.Tracker().SetServiceLabel("Adapting SNS subscriptions...")
return concurrency.Adapt(apiSubscriptions, a.RootAdapter, a.adaptSubscription), nil

}

func (a *adapter) adaptSubscription(apisubcription snsTypes.Subscription) (*sns.Subscription, error) {
metadata := a.CreateMetadataFromARN(*apisubcription.SubscriptionArn)

return &sns.Subscription{
Metadata: metadata,
Endpoint: types.String(*apisubcription.Endpoint, metadata),
}, nil
}
20 changes: 17 additions & 3 deletions internal/adapters/cloud/aws/sqs/sqs.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ func (a *adapter) adaptQueue(queueUrl string) (*sqs.Queue, error) {
sqsTypes.QueueAttributeNameKmsMasterKeyId,
sqsTypes.QueueAttributeNamePolicy,
sqsTypes.QueueAttributeNameQueueArn,
sqsTypes.QueueAttributeNameApproximateNumberOfMessages,
sqsTypes.QueueAttributeNameRedrivePolicy,
},
})
if err != nil {
Expand All @@ -88,9 +90,11 @@ func (a *adapter) adaptQueue(queueUrl string) (*sqs.Queue, error) {
queueMetadata := a.CreateMetadataFromARN(queueARN)

queue := &sqs.Queue{
Metadata: queueMetadata,
QueueURL: defsecTypes.String(queueUrl, queueMetadata),
Policies: []iam.Policy{},
Metadata: queueMetadata,
QueueURL: defsecTypes.String(queueUrl, queueMetadata),
ApproximateNumberOfMessages: defsecTypes.String("", queueMetadata),
RedrivePolicy: defsecTypes.String("", queueMetadata),
Policies: []iam.Policy{},
Encryption: sqs.Encryption{
Metadata: queueMetadata,
KMSKeyID: defsecTypes.StringDefault("", queueMetadata),
Expand All @@ -101,6 +105,8 @@ func (a *adapter) adaptQueue(queueUrl string) (*sqs.Queue, error) {
sseEncrypted := queueAttributes.Attributes[string(sqsTypes.QueueAttributeNameSqsManagedSseEnabled)]
kmsEncryption := queueAttributes.Attributes[string(sqsTypes.QueueAttributeNameKmsMasterKeyId)]
queuePolicy := queueAttributes.Attributes[string(sqsTypes.QueueAttributeNamePolicy)]
approximateNoOfMessages := queueAttributes.Attributes[string(sqsTypes.QueueAttributeNameApproximateNumberOfMessages)]
redrivePolicy := queueAttributes.Attributes[string(sqsTypes.QueueAttributeNameRedrivePolicy)]

if sseEncrypted == "SSE-SQS" || sseEncrypted == "SSE-KMS" {
queue.Encryption.ManagedEncryption = defsecTypes.Bool(true, queueMetadata)
Expand All @@ -110,6 +116,14 @@ func (a *adapter) adaptQueue(queueUrl string) (*sqs.Queue, error) {
queue.Encryption.KMSKeyID = defsecTypes.String(kmsEncryption, queueMetadata)
}

if redrivePolicy != "" {
queue.RedrivePolicy = defsecTypes.String(redrivePolicy, queueMetadata)
}

if approximateNoOfMessages != "" {
queue.ApproximateNumberOfMessages = defsecTypes.String(approximateNoOfMessages, queueMetadata)
}

if queuePolicy != "" {
policy, err := iamgo.ParseString(queuePolicy)
if err == nil {
Expand Down
3 changes: 2 additions & 1 deletion internal/adapters/cloudformation/aws/sns/sns.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
// Adapt ...
func Adapt(cfFile parser.FileContext) sns.SNS {
return sns.SNS{
Topics: getTopics(cfFile),
Topics: getTopics(cfFile),
Subscriptions: getSubscriptions(cfFile),
}
}
60 changes: 57 additions & 3 deletions internal/adapters/cloudformation/aws/sns/topic.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,78 @@
package sns

import (
"github.com/aquasecurity/defsec/pkg/providers/aws/sns"
"fmt"

defsecTypes "github.com/aquasecurity/defsec/pkg/types"

"github.com/aquasecurity/defsec/pkg/scanners/cloudformation/parser"
"github.com/aquasecurity/defsec/pkg/types"

"github.com/aquasecurity/defsec/pkg/providers/aws/iam"
"github.com/aquasecurity/defsec/pkg/providers/aws/sns"

"github.com/liamg/iamgo"
)

func getTopics(ctx parser.FileContext) (topics []sns.Topic) {
for _, r := range ctx.GetResourcesByType("AWS::SNS::Topic") {

topic := sns.Topic{
Metadata: r.Metadata(),
ARN: types.StringDefault("", r.Metadata()),
ARN: defsecTypes.StringDefault("", r.Metadata()),
Policy: []iam.Policy{},
Encryption: sns.Encryption{
Metadata: r.Metadata(),
KMSKeyID: r.GetStringProperty("KmsMasterKeyId"),
},
}
if policy, err := getPolicy(r.ID(), ctx); err == nil {
topic.Policy = append(topic.Policy, *policy)
}

topics = append(topics, topic)
}
return topics
}

func getSubscriptions(ctx parser.FileContext) (subcriptions []sns.Subscription) {
for _, r := range ctx.GetResourcesByType("AWS::SNS::Subscription") {
subcription := sns.Subscription{
Metadata: r.Metadata(),
Endpoint: r.GetStringProperty("Endpoint"),
}
subcriptions = append(subcriptions, subcription)
}
return subcriptions
}

func getPolicy(id string, ctx parser.FileContext) (*iam.Policy, error) {
for _, policyResource := range ctx.GetResourcesByType("AWS::SNS::TopicPolicy") {
documentProp := policyResource.GetProperty("PolicyDocument")
if documentProp.IsNil() {
continue
}
queuesProp := policyResource.GetProperty("Topics")
if queuesProp.IsNil() {
continue
}
for _, queueRef := range queuesProp.AsList() {
if queueRef.IsString() && queueRef.AsString() == id {
raw := documentProp.GetJsonBytes()
parsed, err := iamgo.Parse(raw)
if err != nil {
continue
}
return &iam.Policy{
Metadata: documentProp.Metadata(),
Name: defsecTypes.StringDefault("", documentProp.Metadata()),
Document: iam.Document{
Metadata: documentProp.Metadata(),
Parsed: *parsed,
},
Builtin: defsecTypes.Bool(false, documentProp.Metadata()),
}, nil
}
}
}
return nil, fmt.Errorf("no matching policy found")
}
6 changes: 4 additions & 2 deletions internal/adapters/cloudformation/aws/sqs/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import (
func getQueues(ctx parser.FileContext) (queues []sqs.Queue) {
for _, r := range ctx.GetResourcesByType("AWS::SQS::Queue") {
queue := sqs.Queue{
Metadata: r.Metadata(),
QueueURL: defsecTypes.StringDefault("", r.Metadata()),
Metadata: r.Metadata(),
QueueURL: defsecTypes.StringDefault("", r.Metadata()),
ApproximateNumberOfMessages: defsecTypes.String("", r.Metadata()),
RedrivePolicy: r.GetStringProperty("RedrivePolicy"),
Encryption: sqs.Encryption{
Metadata: r.Metadata(),
ManagedEncryption: defsecTypes.Bool(false, r.Metadata()),
Expand Down
61 changes: 58 additions & 3 deletions internal/adapters/terraform/aws/sns/adapt.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,87 @@
package sns

import (
"github.com/aquasecurity/defsec/internal/adapters/terraform/aws/iam"
iamp "github.com/aquasecurity/defsec/pkg/providers/aws/iam"
"github.com/aquasecurity/defsec/pkg/providers/aws/sns"
"github.com/aquasecurity/defsec/pkg/terraform"
"github.com/aquasecurity/defsec/pkg/types"
"github.com/liamg/iamgo"
)

func Adapt(modules terraform.Modules) sns.SNS {
return sns.SNS{
Topics: adaptTopics(modules),
Topics: adaptTopics(modules),
Subscriptions: adaptSubscriptions(modules),
}
}

func adaptTopics(modules terraform.Modules) []sns.Topic {
var topics []sns.Topic
for _, module := range modules {
for _, resource := range module.GetResourcesByType("aws_sns_topic") {
topics = append(topics, adaptTopic(resource))
topics = append(topics, adaptTopic(resource, modules))
}
}
return topics
}

func adaptTopic(resourceBlock *terraform.Block) sns.Topic {
func adaptSubscriptions(modules terraform.Modules) []sns.Subscription {
var subscriptions []sns.Subscription
for _, module := range modules {
for _, resource := range module.GetResourcesByType(" aws_sns_topic_subscription") {
subscriptions = append(subscriptions, sns.Subscription{
Metadata: resource.GetMetadata(),
Endpoint: resource.GetAttribute("endpoint").AsStringValueOrDefault("", resource),
})
}
}
return subscriptions
}

func adaptTopic(resourceBlock *terraform.Block, modules terraform.Modules) sns.Topic {

var policy iamp.Policy
for _, policyBlock := range modules.GetResourcesByType("aws_sns_topic_policy") {

policy = iamp.Policy{
Metadata: policyBlock.GetMetadata(),
Name: types.StringDefault("", policyBlock.GetMetadata()),
Document: iamp.Document{
Metadata: policyBlock.GetMetadata(),
},
Builtin: types.Bool(false, policyBlock.GetMetadata()),
}
if attr := policyBlock.GetAttribute("policy"); attr.IsString() {
dataBlock, err := modules.GetBlockById(attr.Value().AsString())
if err != nil {
parsed, err := iamgo.ParseString(attr.Value().AsString())
if err != nil {
continue
}
policy.Document.Parsed = *parsed
policy.Document.Metadata = attr.GetMetadata()
} else if dataBlock.Type() == "data" && dataBlock.TypeLabel() == "aws_iam_policy_document" {
if doc, err := iam.ConvertTerraformDocument(modules, dataBlock); err == nil {
policy.Document.Parsed = doc.Document
policy.Document.Metadata = doc.Source.GetMetadata()
policy.Document.IsOffset = true
}
}
} else if refBlock, err := modules.GetReferencedBlock(attr, policyBlock); err == nil {
if refBlock.Type() == "data" && refBlock.TypeLabel() == "aws_iam_policy_document" {
if doc, err := iam.ConvertTerraformDocument(modules, refBlock); err == nil {
policy.Document.Parsed = doc.Document
policy.Document.Metadata = doc.Source.GetMetadata()
}
}
}
}
return sns.Topic{
Metadata: resourceBlock.GetMetadata(),
ARN: types.StringDefault("", resourceBlock.GetMetadata()),
Encryption: adaptEncryption(resourceBlock),
Policy: []iamp.Policy{policy},
}
}

Expand Down
2 changes: 1 addition & 1 deletion internal/adapters/terraform/aws/sns/adapt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func Test_adaptTopic(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
modules := tftestutil.CreateModulesFromSource(t, test.terraform, ".tf")
adapted := adaptTopic(modules.GetBlocks()[0])
adapted := adaptTopic(modules.GetBlocks()[0], modules)
testutil.AssertDefsecEqual(t, test.expected, adapted)
})
}
Expand Down
12 changes: 8 additions & 4 deletions internal/adapters/terraform/aws/sqs/adapt.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ func (a *adapter) adaptQueues() []sqs.Queue {
}

a.queues[uuid.NewString()] = sqs.Queue{
Metadata: defsecTypes.NewUnmanagedMetadata(),
QueueURL: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
Metadata: defsecTypes.NewUnmanagedMetadata(),
QueueURL: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
ApproximateNumberOfMessages: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
RedrivePolicy: defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
Encryption: sqs.Encryption{
Metadata: defsecTypes.NewUnmanagedMetadata(),
ManagedEncryption: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
Expand Down Expand Up @@ -155,8 +157,10 @@ func (a *adapter) adaptQueue(resource *terraform.Block) {
}

a.queues[resource.ID()] = sqs.Queue{
Metadata: resource.GetMetadata(),
QueueURL: defsecTypes.StringDefault("", resource.GetMetadata()),
Metadata: resource.GetMetadata(),
QueueURL: defsecTypes.StringDefault("", resource.GetMetadata()),
ApproximateNumberOfMessages: defsecTypes.StringDefault("", resource.GetMetadata()),
RedrivePolicy: resource.GetAttribute("redrive_policy").AsStringValueOrDefault("", resource),
Encryption: sqs.Encryption{
Metadata: resource.GetMetadata(),
ManagedEncryption: managedEncryption.AsBoolValueOrDefault(false, resource),
Expand Down
11 changes: 10 additions & 1 deletion pkg/providers/aws/sns/sns.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package sns

import (
"github.com/aquasecurity/defsec/pkg/providers/aws/iam"
defsecTypes "github.com/aquasecurity/defsec/pkg/types"
)

type SNS struct {
Topics []Topic
Topics []Topic
Subscriptions []Subscription
}

func NewTopic(arn string, metadata defsecTypes.Metadata) *Topic {
return &Topic{
Metadata: metadata,
ARN: defsecTypes.String(arn, metadata),
Policy: []iam.Policy{},
Encryption: Encryption{
Metadata: metadata,
KMSKeyID: defsecTypes.StringDefault("", metadata),
Expand All @@ -22,10 +25,16 @@ func NewTopic(arn string, metadata defsecTypes.Metadata) *Topic {
type Topic struct {
Metadata defsecTypes.Metadata
ARN defsecTypes.StringValue
Policy []iam.Policy
Encryption Encryption
}

type Encryption struct {
Metadata defsecTypes.Metadata
KMSKeyID defsecTypes.StringValue
}

type Subscription struct {
Metadata defsecTypes.Metadata
Endpoint defsecTypes.StringValue
}
Loading