Yelp / detect-secrets

An enterprise friendly way of detecting and preventing secrets in code.
Apache License 2.0
3.76k stars 467 forks source link

False Negative - YAML Parser Stops Reading After First String Value/Does Not Read Lists of Strings #791

Open RobertRosca opened 7 months ago

RobertRosca commented 7 months ago

Secrets are not detected in (docker compose) yaml files when a top-level entry for a string is present.

This will not detect any secrets:

version: "3.8"

services:
  foo:
    environment:
      - SECRET_KEY=k0l7eDvHl2PhniP0Z146aCOeiw86LGJh5hS2i4LJM

But changing the first line to version: 3.8 will:

version: 3.8

services:
  foo:
    environment:
      - SECRET_KEY=k0l7eDvHl2PhniP0Z146aCOeiw86LGJh5hS2i4LJM
ERROR: Potential secrets about to be committed to git repo!

Secret Type: Secret Keyword
Location:    ./foo.yaml:6

edit: actually, it's a bit more complex, when removing the version value secrets are detected:

services:
  foo:
    environment:
      - SECRET_KEY=k0l7eDvHl2PhniP0Z146aCOeiw86LGJh5hS2i4LJM

Unless you add in something else which is not a mapping to a string:

services:
  foo:
    build: .
    environment:
      - SECRET_KEY=k0l7eDvHl2PhniP0Z146aCOeiw86LGJh5hS2i4LJM

Changing environment from a list of strings to a mapping fixes the issue though:

services:
  foo:
    build: .
    environment:
      SECRET_KEY: k0l7eDvHl2PhniP0Z146aCOeiw86LGJh5hS2i4LJM

But then you're no longer able to use docker compose interpolation within the environment variables, which can be a problem if it's being done for some other variables, e.g the following only works when environment is a list of strings, if it's a mapping you can't do this anymore:

services:
  foo:
    environment:
      - SOMETHING_${FOO}=${BAR}
      - SECRET_KEY=k0l7eDvHl2PhniP0Z146aCOeiw86LGJh5hS2i4LJM

Secrets to be detected when a string entry is present before some nested structure.

Problem seems to be with the yaml parser, for the buggy case of version: "3.8" the lines variable in detect_secrets.scan:269 is:

['version: "3.8"']

So nothing was parsed after that value, which is why the secret isn't found. For the working case of version: 3.8 it is:

[
  'version: 3.8\n',
  '\n', 'services:\n',
  '  foo:\n',
  '    environment:\n',
  '      - SECRET_KEY=k0l7eDvHl2PhniP0Z146aCOeiw86LGJh5hS2i4LJM\n'
]