Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The perils of configuration security

The perils of configuration security

Talk from MyDevSecOps on configuration security, with a discussion of the problem and lots of examples from the Kubernetes and Terraform ecosystem.

Gareth Rushgrove

March 05, 2020
Tweet

More Decks by Gareth Rushgrove

Other Decks in Technology

Transcript

  1. The perils of
    configuration security
    Gareth Rushgrove

    View full-size slide

  2. Gareth Rushgrove
    Director, Product Management, Snyk
    Devops Weekly curator
    Open Source contributor
    @garethr

    View full-size slide

  3. Agenda Configuration security
    01
    Static analysis
    02
    Kubernetes
    03
    Terraform
    04
    Conclusions
    05

    View full-size slide

  4. Configuration security
    In a world of infrastructure as code

    View full-size slide

  5. Configuration is increasingly in code

    View full-size slide

  6. Configuration is increasingly in code YAML

    View full-size slide

  7. Configuration is everywhere
    Azure ARM
    250k+
    Terraform
    140k+
    Kubernetes
    2m+
    AWS CF
    90k+
    Serverless
    40k+
    Compose
    600k+

    View full-size slide

  8. The financial giant said the
    intruder exploited a
    configuration vulnerability


    Configuration is a security risk

    View full-size slide

  9. Some kind of misconfiguration
    is encountered on an
    penetration test over
    96% of the time.


    Configuration is a security risk

    View full-size slide

  10. While CSPs often provide tools
    to help manage cloud
    configuration, misconfiguration
    of cloud resources remains the
    most prevalent cloud
    vulnerability


    Configuration is a security risk

    View full-size slide

  11. Static analysis
    A very quick introduction

    View full-size slide

  12. Static analysis
    Static program analysis is the analysis of
    computer software that is performed
    without actually executing programs

    View full-size slide

  13. A typical testing progression
    Acceptance
    tests
    Unit tests
    Integration
    tests
    Static
    analysis

    View full-size slide

  14. The importance of fast feedback
    Acceptance
    tests
    Unit tests
    Integration
    tests
    Static
    analysis
    Fast Middling Slow Slower

    View full-size slide

  15. Declarative
    Config
    Static
    analysis

    View full-size slide

  16. Kubernetes
    An example ecosystem

    View full-size slide

  17. The current configuration explosion
    Kubernetes YAML files
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: hello-kubernetes
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: hello-kubernetes
    template:
    metadata:
    labels:
    app: hello-kubernetes
    spec:
    containers:
    - name: hello-kubernetes
    ~2 million
    Kubernetes
    configuration files
    public on GitHub

    View full-size slide

  18. Insecure by default
    Limits to prevent denial of service
    CPU and Memory Limits
    spec:
    containers:
    - name: db
    image: mysql
    resources:
    limits:
    memory: "128Mi"
    cpu: "500m"
    Limiting the expected CPU and Memory limits has
    operational as well as security benefits. In the
    context of security this is about limiting the
    impact of potential denial of service attacks to
    affecting the app rather than the node and
    potentially the whole cluster.

    View full-size slide

  19. Insecure by default
    Root level permissions by default
    runAsNonRoot
    apiVersion: v1
    kind: Pod
    metadata:
    name: hello-world
    spec:
    containers:
    ...
    securityContext:
    readOnlyRootFilesystem: true
    runAsNonRoot: true
    By default, containers can run as the root user.
    This property prevents that at the container
    runtime level, meaning an attacker would only
    have limited permissions if they we’re to be able
    to execute a command in the context of the
    container.

    View full-size slide

  20. Insecure by default
    Writable file systems making attackers lives easier
    readOnlyRootFilesystem
    apiVersion: v1
    kind: Pod
    metadata:
    name: hello-world
    spec:
    containers:
    ...
    securityContext:
    readOnlyRootFilesystem: true
    runAsNonRoot: true
    By default the file system mounted for the
    container will be writable. That means an
    attacker who compromises the container can also
    write to disk, which makes certain attacks easier.
    If you’re containers are stateless then you don’t
    need a writable filesystem.

    View full-size slide

  21. Insecure by default
    Access to all the power of linux by default
    Capabilities
    apiVersion: v1
    kind: Pod
    metadata:
    name: hello-world
    spec:
    containers:
    ...
    securityContext:
    capabilities:
    add: ["NET_ADMIN", "SYS_TIME"]
    drop: ["ALL"]
    Linux capabilities control at a low-level what
    processes in the container can do. From being
    able to write to disk to being able to
    communicate over the network. Dropping all
    capabilities and adding in those that are required
    is possible but requires understanding the list of
    capabilities.

    View full-size slide

  22. KubeSec
    github.com/controlplaneio/kubesec
    Security risk analysis for Kubernetes resources Active, started 2 years ago
    245
    Static set of rules
    @sublimino, @stefanprodan

    View full-size slide

  23. Conftest
    github.com/instrumenta/conftest
    Write tests against structured configuration data
    using the Open Policy Agent Rego query language.
    - Currently supports YAML, JSON, INI, TOML,
    HOCON, HCL, CUE, Dockerfile, HCL2, EDN, VCL
    and XML
    - Share policies using OCI registries, Git, S3
    - Built-in debugging and testing tools
    Active, started 10 months ago
    902
    Write your own rules
    @garethr, @jpreese, @blokje5,
    @boranx, @KeisukeYamashita,
    @xchapter7x, @proplex, ...

    View full-size slide

  24. What is Open Policy Agent?
    github.com/open-policy-agent/opa
    Service
    OPA
    .rego
    Query
    (any JSON value)
    Decision
    (any JSON value)
    Data
    (JSON)
    Policy
    (Rego)
    Request, Event, etc. - An open source policy engine
    - Written in Go
    - WebAssembly support coming along
    - A CNCF project
    - Usable as a library and a service
    - A vibrant open source community
    - Provides a declarative DSL for writing policy called Rego

    View full-size slide

  25. Conftest integrations
    Easy to run in common CI/CD systems

    View full-size slide

  26. Conftest
    Kubernetes assertions in Rego
    package main
    deny[msg] {
    input.kind = "Deployment"
    not input.spec.template.spec.securityContext.runAsNonRoot = true
    msg = "Containers must not run as root"
    }
    deny[msg] {
    input.kind = "Deployment"
    not input.spec.selector.matchLabels.app
    msg = "Containers must provide app label for pod selectors"
    }

    View full-size slide

  27. Conftest
    Running tests against your configuration
    $ conftest test deployment.yaml
    FAIL - deployment.yaml - Containers must not run as root
    $ echo $status
    1

    View full-size slide

  28. Conftest
    Shareable policies mean lower barrier to entry
    $ conftest test --update github.com/instrumenta/policies.git//kubernetes deployment+service.yaml
    PASS - deployment+service.yaml - data.main.violation
    FAIL - deployment+service.yaml - hello-kubernetes in the Deployment hello-kubernetes does not hav
    FAIL - deployment+service.yaml - hello-kubernetes in the Deployment hello-kubernetes does not hav
    FAIL - deployment+service.yaml - hello-kubernetes in the Deployment hello-kubernetes doesn't drop
    FAIL - deployment+service.yaml - hello-kubernetes in the Deployment hello-kubernetes is not using
    FAIL - deployment+service.yaml - hello-kubernetes in the Deployment hello-kubernetes allows privi
    FAIL - deployment+service.yaml - hello-kubernetes in the Deployment hello-kubernetes is running a

    View full-size slide

  29. Terraform
    Another example ecosystem

    View full-size slide

  30. Insecure Terraform
    Can you spot issues in the following code?
    resource "aws_security_group_rule" "my-rule" {
    type = "ingress"
    cidr_blocks = ["0.0.0.0/0"]
    }
    resource "aws_alb_listener" "my-alb-listener" {
    port = "80"
    protocol = "HTTP"
    }
    resource "aws_db_security_group" "my-group" {
    }
    resource "azurerm_managed_disk" "source" {
    encryption_settings {
    enabled = false
    }
    }

    View full-size slide

  31. Insecure Terraform
    Can you spot issues in the following code?
    resource "aws_security_group_rule" "my-rule" {
    type = "ingress"
    cidr_blocks = ["0.0.0.0/0"]
    }
    resource "aws_alb_listener" "my-alb-listener" {
    port = "80"
    protocol = "HTTP"
    }
    resource "aws_db_security_group" "my-group" {
    }
    resource "azurerm_managed_disk" "source" {
    encryption_settings {
    enabled = false
    }
    }
    Wide open ingress rule

    View full-size slide

  32. Insecure Terraform
    Can you spot issues in the following code?
    resource "aws_security_group_rule" "my-rule" {
    type = "ingress"
    cidr_blocks = ["0.0.0.0/0"]
    }
    resource "aws_alb_listener" "my-alb-listener" {
    port = "80"
    protocol = "HTTP"
    }
    resource "aws_db_security_group" "my-group" {
    }
    resource "azurerm_managed_disk" "source" {
    encryption_settings {
    enabled = false
    }
    }
    Use of unencrypted transport protocol

    View full-size slide

  33. Insecure Terraform
    Can you spot issues in the following code?
    resource "aws_security_group_rule" "my-rule" {
    type = "ingress"
    cidr_blocks = ["0.0.0.0/0"]
    }
    resource "aws_alb_listener" "my-alb-listener" {
    port = "80"
    protocol = "HTTP"
    }
    resource "aws_db_security_group" "my-group" {
    }
    resource "azurerm_managed_disk" "source" {
    encryption_settings {
    enabled = false
    }
    }
    Unencrypted storage

    View full-size slide

  34. Center for Internet Security
    Benchmarks

    View full-size slide

  35. CIS Benchmarks
    Azure and AWS

    View full-size slide

  36. Terrascan
    github.com/cesar-rodriguez/terrascan
    A collection of security and best practice tests for
    static code analysis of terraform templates using
    terraform_validate.
    Active, started 4 months ago
    333
    Python
    35 rules, mainly for AWS
    @cesar-rodriguez
    Ran 16 tests in 0.015s
    OK
    Processed 19 files in
    C:\DEV\terraforms\backends\10-network-analytics
    Results (took 1.08 seconds):
    Failures: (2)
    [high] [aws_dynamodb_table.encryption.server_side_encryption.ena
    [high] [aws_s3_bucket.noEncryption] should have property: 'server
    Errors: (0)

    View full-size slide

  37. Terrafirma
    github.com/wayfair/terrafirma
    Terrafirma is a Terraform static analysis tool
    designed for detecting security misconfigurations.
    Inactive, created 2 years ago
    17
    Python
    14 rules, mainly for GCP
    ---
    ISSUE FW_1
    - Source range open to Internet
    - SEVERITY WARN
    - RESOURCE example_fw_rule.google_compute_firewall
    ---
    ISSUE FW_2
    - SSH Open
    - SEVERITY INFO
    - RESOURCE example_fw_rule.google_compute_firewall

    View full-size slide

  38. Checkov
    github.com/bridgecrewio/checkov
    Checkov is a static code analysis tool for
    infrastructure as code. It scans cloud infrastructure
    managed in Terraform and detects misconfigurations.
    Active, created 3 months ago
    511
    Python
    50 rules, for AWS, Azure and GCP
    @schosterbarak, @tronxd,
    @guyeisenkot, @nimrodkor
    Passed checks: 4, Failed checks: 0, Skipped checks: 0
    Check: "Ensure all data stored in the S3 bucket is securely
    encrypted at rest"
    PASSED for resource: aws_s3_bucket.foo-bucket
    File: /example.tf:1-25
    Check: "Ensure the S3 bucket has access logging enabled"
    PASSED for resource: aws_s3_bucket.foo-bucket
    File: /example.tf:1-25

    View full-size slide

  39. tfsec
    github.com/liamg/tfsec
    tfsec uses static analysis of your terraform
    templates to spot potential security issues
    - Checks for sensitive data inclusion across all
    providers
    - Checks for violations of AWS, Azure and GCP
    security best practice recommendations
    - Scans modules (currently only local modules
    are supported)
    - Evaluates expressions as well as literal values
    Active, started 4 months ago
    927
    35 rules, mainly for AWS
    @liamg

    View full-size slide

  40. tfsec
    Detect common configuration issues
    $ tfsec
    5 potential problems detected:
    Problem 1
    [AWS018][ERROR] Resource 'aws_security_group_rule.my-rule' should include a description for auditing purposes.
    /Users/garethr/Documents/terraform-security/main.tf:1-4
    1 | resource "aws_security_group_rule" "my-rule" {
    2 | type = "ingress"
    3 | cidr_blocks = ["0.0.0.0/0"]
    4 | }
    5 |
    6 | resource "aws_alb_listener" "my-alb-listener"{
    7 | port = "80"
    See https://github.com/liamg/tfsec/wiki/AWS018 for more information.
    Problem 2
    [AWS006][WARNING] Resource 'aws_security_group_rule.my-rule' defines a fully open ingress security group rule.
    /Users/garethr/Documents/terraform-security/main.tf:3
    Decision
    (any JSON value)

    View full-size slide

  41. Conftest (again)
    Terraform/HCL assertions in Rego
    package main
    deny[msg] {
    proto := input.resource.aws_alb_listener[lb].protocol
    proto == "HTTP"
    msg = sprintf("ALB `%v` is using HTTP rather than HTTPS", [lb])
    }
    deny[msg] {
    rule := input.resource.aws_security_group_rule[name]
    rule.type == "ingress"
    contains(rule.cidr_blocks, "0.0.0.0/0")
    msg = sprintf("ASG `%v` defines a fully open ingress", [name])
    }

    View full-size slide

  42. Conftest (again)
    Running tests against your Terraform code
    $ conftest test -i hcl2 main.tf
    FAIL - main.tf - ALB `my-alb-listener` is using HTTP rather than HTTPS
    FAIL - main.tf - ASG `my-rule` defines a fully open ingress
    FAIL - main.tf - Azure disk `source` is not encrypted
    Decision
    (any JSON value)

    View full-size slide

  43. Conftest
    Write unit tests for Rego in Rego
    test_blank_input {
    no_violations with input as {}
    }
    test_correctly_encrypted_azure_disk {
    no_violations with input as {"resource": { "azurerm_managed_disk": { "sample": { "encrypted
    }
    test_unencrypted_azure_disk {
    deny["Azure disk `sample` is not encrypted"] with input as {"resource": { "azurerm_managed_
    }

    View full-size slide

  44. Conclusions
    If all you remember is...

    View full-size slide

  45. Infrastructure is
    increasingly part of the app
    Your configuration is in the same repo
    as your code, maintained by the same
    developers and going through CI

    View full-size slide

  46. Infrastructure as code leads to
    its own security challenges
    But static analysis is surprisingly useful
    when applied to declarative languages

    View full-size slide

  47. Shift security left
    Automatically catching security issues
    during development means less
    issues in production, and more time
    to focus on finding and fixing them

    View full-size slide

  48. Thanks for listening
    Sign up for free at snyk.io/signup

    View full-size slide