Git Product home page Git Product logo

paranoia's Introduction

Paranoia

Who do you trust?

Paranoia is a tool to analyse and export trust bundles (e.g., "ca-certificates") from container images. These certificates identify the certificate authorities that your container trusts when establishing TLS connections. The design of TLS is that any certificate authority that your container trusts can issue a certificate for any domain. This means that a malicious or compromised certificate authority could issue a certificate to impersonate any other service, including your internal infrastructure.

Paranoia can be used to inspect and validate the certificates within your container images. This gives you visibility into which certificate authorities your container images are trusting; allows you to forbid or require certificates at build-time in CI; and help you decide who to trust in your container images.

Paranoia is built by Jetstack and made available under the Apache 2.0 license, see LICENSE.txt.

Installation

Homebrew

On macOS and Linux, if you have Homebrew you can install Paranoia with:

brew install jetstack/jetstack/paranoia

This will also install man pages and shell completion.

Binaries

Binaries for common platforms and architectures are provided on the releases. Man pages are also attached to the release. You can generate shell completion from Paranoia itself with paranoia completion.

Go Install

If you have Go installed you can install Paranoia using Go directly.

go install github.com/jetstack/paranoia@latest

Examples

Paranoia can be used to list out the certificates in a container image:

$ paranoia export alpine:latest
File Location                       Subject                                                                                                                                                                        
/etc/ssl/certs/ca-certificates.crt  CN=ACCVRAIZ1,OU=PKIACCV,O=ACCV,C=ES                                                                                                                                            
/etc/ssl/certs/ca-certificates.crt  OU=AC RAIZ FNMT-RCM,O=FNMT-RCM,C=ES                                                                                                                                            
/etc/ssl/certs/ca-certificates.crt  CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS,OU=Ceres,O=FNMT-RCM,C=ES,2.5.4.97=#130f56415445532d51323832363030344a                                                                   
…
/etc/ssl/certs/ca-certificates.crt  CN=vTrus ECC Root CA,O=iTrusChina Co.\,Ltd.,C=CN                                                                                                                               
/etc/ssl/certs/ca-certificates.crt  CN=vTrus Root CA,O=iTrusChina Co.\,Ltd.,C=CN                                                                                                                                   
Found 140 certificates

Export them for further audit:

paranoia export --output json python:3 | jq '.certificates[].fingerprintSHA256' | head -n 5

"ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99"
"6dc47172e01cbcb0bf62580d895fe2b8ac9ad4f873801e0c10b9c837d21eb177"
"16af57a9f676b0ab126095aa5ebadef22ab31119d644ac95cd4b93dbf3f26aeb"
"73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c"
"d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4"

Detect internal certificates left over from internal testing:

cat << EOF > .paranoia.yaml
version: "1"
forbid:
  - comment: "An internal-only cert"
    fingerprints:
      sha256: bd40be0eccfce513ab318882f03962e4e2ec3799b51392e82805d9249e426d28
EOF
paranoia validate my-image

Find certificates inside binaries:

paranoia export -o json consul:latest | jq '.certificates[] | select(.fileLocation == "/bin/consul")'
{
  "fileLocation": "/bin/consul",
  "owner": "CN=Circonus Certificate Authority,OU=Circonus,O=Circonus\\, Inc.,L=Columbia,ST=Maryland,C=US,1.2.840.113549.1.9.1=#0c0f636140636972636f6e75732e6e6574",
  "parser": "pem",
  "signature": "01C1B65D790706D2CAAD1D30406911D41884789A9D4FEBBCE31EE7B7628019A8C7B6643C46C1FDB684B18272B33880DAB68EB51C5546D731B9948C8A3D918890EC2F1CC8A751FAD1786BF2599FEEA17A63EB1997B577E8A65B9F67B368EA11B6C425F5D86A10C7BCCE02FBEA9F5867913AF409749A08A27D3B5EC8D8E332E216",
  "notBefore": "2009-12-23T19:17:06Z",
  "notAfter": "2019-12-21T19:17:06Z",
  "fingerprintSHA1": "063ff657e055b0036d794cda892c85417c07739a",
  "fingerprintSHA256": "0c97e0898343c5b1973c6568a15c8c853dd663d363020071e34f789859ece19f"
}

Limitations

Paranoia will detect certificate authorities in most cases, and is especially useful at finding accidental inclusion or for conducting a certificate authority inventory. However, there are some limitations to bear in mind while using Paranoia:

  • Paranoia only functions on container images, not running containers. Anything added into the container at runtime is not seen.
  • If a certificate is found, that doesn’t guarantee that the container will trust it as a certificate authority. It could, for example, be an unused leftover file.
  • It’s possible for an attacker to ‘hide’ a certificate authority from Paranoia (e.g., by encoding it in a format Paranoia doesn’t understand). In general Paranoia isn’t designed to defend against an adversary with supply chain write access intentionally sneaking obfuscated certificate authorities into container images.

Usage

The usage documentation for Paranoia is included in the help text. Invoke a command with --help for usage instructions, or see the manual pages.

paranoia's People

Contributors

alexwootton avatar dependabot[bot] avatar developer-guy avatar hawksight avatar jameslaverack avatar joshvanl avatar joshw123 avatar ribbybibby avatar robingileborg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paranoia's Issues

Validate Command

Add a new command validate that takes a YAML file which can describe certificates to not have and certificates to definately have. Can be used to validate things in CI.

Allow use as a Library

Following a discussion on Slack there's a desire to make the APIs for Paranoia available for use. Presently they are in internal/ which forbids their use by other programs (convention by the Go compiler).

We have a few options:

  • Move all code currently under internal/ to pkg/, exposing all of it as an API surface.
  • Add new code under pkg/ that calls the implementation in internal/, exposing a more selected API surface.

The latter would be more work, but would expose an intentfully designed API instead of everything, which might make future code changes easier without breaking changes.

cc @mt-inside

Asking for suggestions for my use cases

Hi there, I was at KCD UK when I found out about this project; I immediately found it interesting and wanted to experiment a little bit with it.

Now I've tried adding the paranoia action in a project I'm maintaining where unfortunately I was already adding lots of cerfiicates so I now find myself with having three options:

  1. remove all the certs and find a better way to add only a specific subset of certs (I'm still studying whether this is actually feasible but I'm worried it won't)
  2. audit every single certificate and add them to the allow list so that, after the audit, I have 100% control and understanding over the certificates I'm using
  3. allow any certificate that is installed (like I did in this PR or better by allowing all the current fingerprints) but it practically means I'm not actually using the tool so I'm just wasting action resources without adding any security with the risk of having to patch the paranoia.yml file anytime a new certificate is issued.

I believe that I should stick with option 1, however if that's not feasible what do you think would be the best option in your experience?

Also, assuming that option 1 is not feasible and that auditing +100certificate will be a pain, do you think option 3 can still be useful? I believe it can if paranoia fails the check for some unexpected issues (such as expired certificates, etc) do you see that coming? or have any plan for some interesting features that may be letting me adopt the tool even with such options at hand?

Thanks in advance!
Cheers!

🐞 PANIC when specified image can't be found

Observed behaviour

When the given container image can't be found the program panics. See the example output below when trying to scan quay.io/cert-manager-controller:v1.8.0:

$ paranoia inspect quay.io/cert-manager-controller:v1.8.0
panic: GET https://quay.io/v2/cert-manager-controller/manifests/v1.8.0: unexpected status code 404 Not Found: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>


goroutine 1 [running]:
github.com/jetstack/paranoia/cmd.glob..func2(0x1719840?, {0xc000119590, 0x1, 0x1?})
        /Users/alexwootton/repos/jetstack/paranoia/cmd/inspect.go:45 +0x611
github.com/spf13/cobra.(*Command).execute(0x1719840, {0xc000119550, 0x1, 0x1})
        /Users/alexwootton/go/pkg/mod/github.com/spf13/[email protected]/command.go:860 +0x663
github.com/spf13/cobra.(*Command).ExecuteC(0x1719340)
        /Users/alexwootton/go/pkg/mod/github.com/spf13/[email protected]/command.go:974 +0x3b4
github.com/spf13/cobra.(*Command).Execute(...)
        /Users/alexwootton/go/pkg/mod/github.com/spf13/[email protected]/command.go:902
github.com/jetstack/paranoia/cmd.Execute()
        /Users/alexwootton/repos/jetstack/paranoia/cmd/root.go:22 +0x25
main.main()
        /Users/alexwootton/repos/jetstack/paranoia/main.go:8 +0x17
exit status 2

Or this example where the given tag didn't exist:

$ paranoia inspect rancher/jetstack-cert-manager-controller:latest
panic: GET https://index.docker.io/v2/rancher/jetstack-cert-manager-controller/manifests/latest: MANIFEST_UNKNOWN: manifest unknown; unknown tag=latest

goroutine 1 [running]:
github.com/jetstack/paranoia/cmd.glob..func2(0x1719840?, {0xc00006d5c0, 0x1, 0x1?})
        /Users/alexwootton/repos/jetstack/paranoia/cmd/inspect.go:45 +0x611
github.com/spf13/cobra.(*Command).execute(0x1719840, {0xc00006d580, 0x1, 0x1})
        /Users/alexwootton/go/pkg/mod/github.com/spf13/[email protected]/command.go:860 +0x663
github.com/spf13/cobra.(*Command).ExecuteC(0x1719340)
        /Users/alexwootton/go/pkg/mod/github.com/spf13/[email protected]/command.go:974 +0x3b4
github.com/spf13/cobra.(*Command).Execute(...)
        /Users/alexwootton/go/pkg/mod/github.com/spf13/[email protected]/command.go:902
github.com/jetstack/paranoia/cmd.Execute()
        /Users/alexwootton/repos/jetstack/paranoia/cmd/root.go:22 +0x25
main.main()
        /Users/alexwootton/repos/jetstack/paranoia/main.go:8 +0x17
exit status 2

Expected Behaviour

Human readable error message printed to STDOUT containing relevant details about the error

Raw Certificate Output

Add a --output pem option to the export command that will output the full raw certificate data of all found certificates.

Add integration tests

Add a suite of integration tests that verify that Paranoia works on a few given containers.

Deep Container Inspection

Look for certs in more interesting places than just "files that end in .crt". This could be inside bash scripts, or in the strings of binaries.

Maybe this needs gating behind a --deep flag or something similar, if it's gonna take a while.

File system parser

We should build a more sophisticated parser that takes no/little assumptions about the shape and location of certificates in an image file system. This will make the tool more robust, and give users a higher degree of confidence of the correctness of the results.

Certs come it different forms- either as '.pem'/'.crt' files, echos in bash scripts, and even hard coded strings in binaries.

The parser should approach parsing files in a "sliding window" strategy, by reading a stream of bytes from the file and attempting to match that against what a certificate looks like; accounting for different encodings (base64, DER/PEM, PKCS#x), as well as string escaping (namely new lines ('/n' '/r').

Update README with latest functionality, usage examples and feature roadmap

The current README isn't descriptive of the current or the intended behaviour of the software.

Let's update it to include:

  • Short synopsis of functionality (readers should understand the most common/intended use-case for the software)
  • Installation requirements/instructions
  • Usage examples covering top level functionality (things shown when you run paranoia --help, currently export and inspect)
    • including example output will help potential users evaluate the software without needing to download it
  • Feature roadmap (a simple TODO style section at the bottom linking to related GitHub issues would do)
    • this will hopefully give a good indication of the intended direction of development and reduce the number of duplicated enhancement requests

Add progress indicators to long running tasks

We have a few areas in our application where users can be waiting seconds with no output to stdout even though the application is running.

It would be good to give users some indication of life and progress being made to minimise frustration and confusion. A simple message printed to stdout when starting a potentially long running task could be enough. An animated progress wheel would be a nice touch but potentially more effort than it's worth at this stage.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.