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

[WIP] Alpine support via Alpine-SecDB #272

Merged
merged 13 commits into from
Dec 19, 2016
Merged

[WIP] Alpine support via Alpine-SecDB #272

merged 13 commits into from
Dec 19, 2016

Conversation

jzelinskie
Copy link
Contributor

@jzelinskie jzelinskie commented Nov 18, 2016

I'm making this PR now just to let people know that it's finally happening. Data is sourced from Alpine SecDB (MIT licensed). This fetcher adds git as a dependency on the system path.

  • Namespace Detector based on /etc/alpine-release
  • Feature detector based on /lib/apk/db/installed
  • Fetcher using alpine-secdb via git
  • Unit tests for all
  • Ensure everything actually works 😜

@jzelinskie jzelinskie added component/fetcher kind/feature request wishes for new functionality/docs reviewed/needs rework will be closed if review not addressed labels Nov 18, 2016
@Quentin-M
Copy link
Contributor

Quentin-M commented Nov 18, 2016

  • README (source, license)
  • Dockerfile (git dep)
  • GIF centering (swag)

@barakmich
Copy link
Contributor

barakmich commented Nov 18, 2016

GIF centering

🚎

@betawaffle
Copy link

Umm, the GIF doesn't even load!


// Ask the database for the latest commit we successfully applied.
var dbCommit string
dbCommit, err = db.GetKeyValue("alpineUpdater")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

// Append any changed vulnerabilities to the response.
if commit == dbCommit {
log.Debug("no alpine update")
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set FlagName/FlagValue before; then no need for else, just return; saves an indentation level.

for _, fix := range pkg.Fixes {
version, err := types.NewVersion(pkg.Version)
if err != nil {
continue
Copy link
Contributor

@Quentin-M Quentin-M Nov 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log.Warningf("could not parse package version '%s': %s. skipping", pkg.version, err.Error())

continue
}

var vuln database.Vulnerability
Copy link
Contributor

@Quentin-M Quentin-M Nov 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we use the database.Vulnerability{} notation?

var vuln database.Vulnerability
vuln.Name = fix
vuln.Link = nvdURLPrefix + fix
vuln.FixedIn = append(vuln.FixedIn, database.FeatureVersion{
Copy link
Contributor

@Quentin-M Quentin-M Nov 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why append() if you just created the object?

// one.
if ipkg.Feature.Name != "" && ipkg.Version.String() != "" {
pkgSet[ipkg.Feature.Name+"#"+ipkg.Version.String()] = ipkg
ipkg = database.FeatureVersion{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ipkg = intermediary package, once you have both the name and version, we reset it so that we can parse a new one.


func (d *detector) Detect(data map[string][]byte) ([]database.FeatureVersion, error) {
file, exists := data["lib/apk/db/installed"]
if exists {
Copy link
Contributor

@Quentin-M Quentin-M Nov 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    f, hasFile := data["lib/apk/db/installed"]
    if !hasFile {
        return []database.FeatureVersion{}, nil
    }

simpler, avoids one level of indentation

@mattmoor
Copy link
Contributor

Instead of adding a dependency on Git, did you consider simply fetching the tarball at HEAD?

http://git.alpinelinux.org/cgit/alpine-secdb/snapshot/alpine-secdb-master.tar.bz2

@Quentin-M
Copy link
Contributor

Quentin-M commented Nov 19, 2016

It makes a lot of sense now because their database is extremely small. As the database gets bigger (hopefully.. but maybe never big enough to make sense), git pull will become faster and download less data after few update loops. However using the tarball would surely make adapting the fetcher easier when we'll want to adapt Clair to be used without external network connectivity.

@jzelinskie
Copy link
Contributor Author

jzelinskie commented Nov 19, 2016

However using the tarball would surely make adapting the fetcher easier when we'll want to adapt Clair to be used without external network connectivity.

I'm absolutely open to changing to the tarball download if this a goal for the future. Do we have a plan for migrating existing fetchers to systems that could support this?

@mattmoor
Copy link
Contributor

FWIW, we run in contexts where shelling out to tools like bzr, git, rpm simply isn't practical. In our pseudo air-gapped environment we can reach outside by swapping out http.DefaultTransport in-process for certain sites, but tool invocations create trouble (harder to do the same, especially without carrying patches).

@jzelinskie
Copy link
Contributor Author

@mattmoor Have you been unable to use Ubuntu fetchers for this same reason? They depend on bzr.

@mattmoor
Copy link
Contributor

@jzelinskie Yes, we have a variant (that we were supposed to upstream, which I'm running down) that basically makes the mechanism pluggable.

The tl;dr is that we define an interface for the core methods that shell out to bzr and implement it one way with bzr and another with the bzr tarball url.

@mwarkentin
Copy link

Does anyone have a feel for how maintained alpine-secdb is? It looks like it was last updated ~7 weeks ago?

Really hoping for a good solution here for monitoring for vulnerable packages in Alpine, just wondering if there are any plans for how the upstream database will be kept up to date?

@Quentin-M
Copy link
Contributor

Quentin-M commented Nov 28, 2016

@mwarkentin That's a very good question. We have contacted the main committer to ask about the license and whether we should expect this database to be a first-time citizen / updated regularly or not. We now know that the database is licensed under MIT but as far as I know, we have had no update on that second question yet. We hope that our implementation will increase demand on this important topic at Alpine.

@mwarkentin
Copy link

@Quentin-M Thanks! I agree that having an implementation like this could be a good driver for keeping the db updated.

Please update if you get any further information about this. :)

@jzelinskie
Copy link
Contributor Author

@mattmoor any timeline on upstreaming this work? If we could settle on a streamlined a process for backchanneling data sources for air-gapped Clair instances, that'd be great!

@mattmoor
Copy link
Contributor

FWIW, I wouldn't characterize it as a general air-gap solution so much as a pattern that enables it. No timeframe yet, so don't block this for it.

@Quentin-M
Copy link
Contributor

@jzelinskie Have any e2e tested it on an image that actually contains one of the managed vulnerability? Also, I am aware that an existing namespace detector catched Alpine (probably wrongly) on some images, that'd be good to make sure they don't collide and that only the actual new Alpine detector gets it rather than the other one.

)

const (
secdbGitURL = "http://git.alpinelinux.org/cgit/alpine-secdb"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a note for 'httpss://' when supported?

}

// Append any changed vulnerabilities to the response.
for _, namespace := range []string{"v3.3", "v3.4"} {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: It'd be neat to extract the version->parser mapping outside of this function, at the top.

}
}

out, err := utils.Exec(f.repositoryLocalPath, "git", "rev-parse", "HEAD")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the first time, we clone. The next times, we just rev-parse HEAD. Shouldn't we pull before? Otherwise even if HEAD moved, we'd still be reading the old files when opening them.

continue
}

var vuln database.Vulnerability
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is not using database.Vulnerability{Name: "", Link: ""} style a conscious decision?

@Quentin-M
Copy link
Contributor

Quentin-M commented Dec 16, 2016

Besides my comment regarding to potential Alpine detections with the existing detectors above, this looks fine.

I think my idea around range []string{"v3.3", "v3.4"} was to have a map Version->Parsing function at the top and avoid having these hardcoded in a function (in which we range and switch over). So we could simply modify the map and add a new parsing function whenever we need to. Now they are hardcoded in two functions (parseVulnsFromNamespace and FetchUpdate). It doesn't matter too much though, just style.


parseFunc, exists := parsers[namespace]
if !exists {
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these are much better. Please just add a Warning here as well as an updater Note for that so we can be alerted when we need to take action. See https://github.com/coreos/clair/blob/master/updater/fetchers/ubuntu/ubuntu.go#L139

@Quentin-M
Copy link
Contributor

LGTM. Users will then be able to figure out action is needed by reading Prometheus.

@jzelinskie jzelinskie merged commit d62bddd into quay:master Dec 19, 2016
@jzelinskie jzelinskie deleted the alpine branch December 19, 2016 16:39
@adityacs
Copy link

@jzelinskie Could you please provide me a alpine docker image which has some CVEs?
I scanned many images with alpine but always getting 0 vulnerabilities.

@boydgreenfield
Copy link

@adityacs Very late, but node:6.9.4-alpine has a bunch of vulnerabilities (first one I googled, was also worried as the latest few all returned 0 and I wasn't sure if any real checks were being executed):

2018/01/25 18:44:33 [WARN] ▶ Image [node:6.9.4-alpine] contains 7 total vulnerabilities
2018/01/25 18:44:33 [ERRO] ▶ Image [node:6.9.4-alpine] contains 7 unapproved vulnerabilities
+------------+-----------------------+--------------+-----------------+---------------------------------------------------------------+
| STATUS     | CVE SEVERITY          | PACKAGE NAME | PACKAGE VERSION | CVE DESCRIPTION                                               |
+------------+-----------------------+--------------+-----------------+---------------------------------------------------------------+
| Unapproved | High CVE-2016-9843    | zlib         | 1.2.8-r2        |                                                               |
|            |                       |              |                 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9843  |
+------------+-----------------------+--------------+-----------------+---------------------------------------------------------------+
| Unapproved | High CVE-2016-9841    | zlib         | 1.2.8-r2        |                                                               |
|            |                       |              |                 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9841  |
+------------+-----------------------+--------------+-----------------+---------------------------------------------------------------+
| Unapproved | Medium CVE-2017-16544 | busybox      | 1.24.2-r12      |                                                               |
|            |                       |              |                 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-16544 |
+------------+-----------------------+--------------+-----------------+---------------------------------------------------------------+
| Unapproved | Medium CVE-2017-15650 | musl         | 1.1.14-r14      |                                                               |
|            |                       |              |                 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15650 |
+------------+-----------------------+--------------+-----------------+---------------------------------------------------------------+
| Unapproved | Medium CVE-2016-9842  | zlib         | 1.2.8-r2        |                                                               |
|            |                       |              |                 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9842  |
+------------+-----------------------+--------------+-----------------+---------------------------------------------------------------+
| Unapproved | Medium CVE-2016-9840  | zlib         | 1.2.8-r2        |                                                               |
|            |                       |              |                 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9840  |
+------------+-----------------------+--------------+-----------------+---------------------------------------------------------------+
| Unapproved | Medium CVE-2017-15873 | busybox      | 1.24.2-r12      |                                                               |
|            |                       |              |                 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15873 |
+------------+-----------------------+--------------+-----------------+---------------------------------------------------------------+

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature request wishes for new functionality/docs reviewed/needs rework will be closed if review not addressed
Development

Successfully merging this pull request may close these issues.

None yet

8 participants