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

Overprivileged crossfeed functions #2496

Open
bates151 opened this issue Jan 29, 2024 · 1 comment
Open

Overprivileged crossfeed functions #2496

bates151 opened this issue Jan 29, 2024 · 1 comment
Labels
Backend ASM-VDB Technical Infrastructure and Database Security - AcctMgmt User account management requirements User Feedback

Comments

@bates151
Copy link

We are submitting this issue to notify you of an IAM policy analysis we conducted based on an October 2021 copy of the cisagov/crossfeed repository. We recognize that your application has continued to change since then, but wanted to share our results with you.

Analyzing backend/serverless.yml in https://github.com/cisagov/crossfeed/tree/fedb7eb, we determined that the provider-level iamRoleStatements definition leads to over-privileged functions -- in other words, more permissions are granted to the function than are necessary to fulfill their task. By looking at the API calls that were actually being made by your application at that time, we determined that the following changes would reduce unnecessary privilege while still permitting the application to function.

Note: the following policy changes use the https://github.com/functionalone/serverless-iam-roles-per-function serverless plugin to create detailed per-function iam policies.

High level overview:
Only the api function needed lambda:Invoke, ses:sendRawEmail and s3 permissions. bastion and makeGlobalAdmin functions did not need any permissions. To the best of our knowledge, the scheduler, syncdb, and updateScanTask functions only needed ecs permissions, logs:GetLogEvents, and iam:PassRole permission for running ecs tasks.

src/api/functions.yml:

api:
  handler: src/api.handler
  events:
    - http:
        path: / # this matches the base path
        method: ANY
        cors: true
    - http:
        path: /{any+} # this matches any path, the token 'any' doesn't mean anything special
        method: ANY
        cors: true
  provisionedConcurrency: 1
  iamRoleStatements:
    - Effect: Allow
      Action:
        - lambda:InvokeAsync
        - lambda:InvokeFunction
      Resource: 'scheduler'
    - Effect: Allow
      Action:
        - ses:SendRawEmail
      Resource: '*'
    - Effect: Allow
      Action:
        - s3:GetObject
        - s3:GetObjectAcl
        - s3:PutObject
        - s3:PutObjectAcl
      Resource: '*'
    - Effect: Allow
      Action:
        - logs:GetLogEvents
      Resource: '*'
    - Effect: Allow
      Action:
        - ecs:RunTask
        - ecs:ListTasks
      Resource: '*'
    - Effect: Allow
      Action:
        - iam:PassRole
      Resource: '*'

src/tasks/function.yml:

scheduler:
  handler: src/tasks/scheduler.handler
  timeout: 300
  events:
    - schedule: rate(5 minutes)
  reservedConcurrency: 1
  memorySize: 4096
  iamRoleStatements:
    - Effect: Allow
      Action:
        - logs:GetLogEvents
      Resource: '*'
    - Effect: Allow
      Action:
        - ecs:RunTask
        - ecs:ListTasks
      Resource: '*'
    - Effect: Allow
      Action:
        - iam:PassRole
      Resource: '*'

syncdb:
  handler: src/tasks/syncdb.handler
  iamRoleStatements:
    - Effect: Allow
      Action:
        - logs:GetLogEvents
      Resource: '*'
    - Effect: Allow
      Action:
        - ecs:RunTask
        - ecs:ListTasks
      Resource: '*'
    - Effect: Allow
      Action:
        - iam:PassRole
      Resource: '*'

bastion:
  timeout: 900
  handler: src/tasks/bastion.handler

makeGlobalAdmin:
  handler: src/tasks/makeGlobalAdmin.handler

updateScanTaskStatus:
  handler: src/tasks/updateScanTaskStatus.handler
  events:
    - eventBridge:
        pattern:
          source:
            - aws.ecs
          detail-type:
            - ECS Task State Change
          detail:
            clusterArn:
              - ${file(env.yml):${self:provider.stage}-ecs-cluster, ''}
  iamRoleStatements:
    - Effect: Allow
      Action:
        - logs:GetLogEvents
      Resource: '*'
    - Effect: Allow
      Action:
        - ecs:RunTask
        - ecs:ListTasks
      Resource: '*'
    - Effect: Allow
      Action:
        - iam:PassRole
      Resource: '*'

src/tasks/function.yml:
scheduler:
  handler: src/tasks/scheduler.handler
  timeout: 300
  events:
    - schedule: rate(5 minutes)
  reservedConcurrency: 1
  memorySize: 4096
  iamRoleStatements:
    - Effect: Allow
      Action:
        - logs:GetLogEvents
      Resource: '*'
    - Effect: Allow
      Action:
        - ecs:RunTask
        - ecs:ListTasks
      Resource: '*'
    - Effect: Allow
      Action:
        - iam:PassRole
      Resource: '*'

syncdb:
  handler: src/tasks/syncdb.handler
  iamRoleStatements:
    - Effect: Allow
      Action:
        - logs:GetLogEvents
      Resource: '*'
    - Effect: Allow
      Action:
        - ecs:RunTask
        - ecs:ListTasks
      Resource: '*'
    - Effect: Allow
      Action:
        - iam:PassRole
      Resource: '*'

bastion:
  timeout: 900
  handler: src/tasks/bastion.handler

makeGlobalAdmin:
  handler: src/tasks/makeGlobalAdmin.handler

updateScanTaskStatus:
  handler: src/tasks/updateScanTaskStatus.handler
  events:
    - eventBridge:
        pattern:
          source:
            - aws.ecs
          detail-type:
            - ECS Task State Change
          detail:
            clusterArn:
              - ${file(env.yml):${self:provider.stage}-ecs-cluster, ''}
  iamRoleStatements:
    - Effect: Allow
      Action:
        - logs:GetLogEvents
      Resource: '*'
    - Effect: Allow
      Action:
        - ecs:RunTask
        - ecs:ListTasks
      Resource: '*'
    - Effect: Allow
      Action:
        - iam:PassRole
      Resource: '*'

Your IAM policy was studied as part of a research project that was conducted jointly by researchers at the North Carolina State University and the University of Illinois at Urbana-Champaign. We developed an algorithm that leveraged graph reachability analysis to inspect privilege in serverless applications. This work has been accepted to appear at the 2024 Web Conference (Paper Title: “GRASP: Hardening Serverless Applications through Graph Reachability Analysis of Security Policies”). We will be discussing the results from our 2021 analysis of your application as part of this work, but will be sure to note that the policy has been updated since then.

Since our analysis, the backend/serverless.yml has added significantly more permissions (e.g., ssm, sts, sqs, and additional logs permissions) to the provider level policy granted to all functions. If you’d like, we’d be happy to update our analysis to reflect the present state of your application. Do let us know if you have any thoughts or feedback.

Best,
Adam Bates (co-authors: Isaac Polinsky, Pubali Datta, Will Enck)

@dmfezzareed dmfezzareed added User Feedback Backend ASM-VDB Technical Infrastructure and Database Security - AcctMgmt User account management requirements labels Jan 29, 2024
@dmfezzareed
Copy link

Thank you @bates151 for the thoughtful and detailed feedback.

CC @schmelz21 @rapidray12 @cduhn17 @stewartl97

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backend ASM-VDB Technical Infrastructure and Database Security - AcctMgmt User account management requirements User Feedback
Projects
None yet
Development

No branches or pull requests

2 participants