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

feat: disable container app scan with feature flag #4105

Merged
merged 2 commits into from
Oct 31, 2022

Conversation

tommyknows
Copy link
Contributor

What does this PR do?

This commit adds a check for the containerCliAppVulnsEnabled feature flag. If neither --exclude-app-vulns nor --app-vulns are set, the feature flag will be used to determine whether app vulnerabilities will be scanned or not.

Any background context you want to provide?

Part of the work to enable app vulnerability scanning in containers by default. Build upon @yaronschwimmer's change, but that needed some adjustments to ensure the ordering and precedence of flags.

What are the relevant tickets?

https://snyksec.atlassian.net/browse/MYC-177

@tommyknows tommyknows requested a review from a team as a code owner October 5, 2022 09:18
@github-actions
Copy link
Contributor

github-actions bot commented Oct 5, 2022

Warnings
⚠️

Since the CLI is unifying on a standard and improved tooling, we're starting to migrate old-style imports and exports to ES6 ones.
A file you've modified is using either module.exports or require(). If you can, please update them to ES6 import syntax and export syntax.
Files found:

  • src/cli/commands/monitor/index.ts
  • src/cli/commands/test/index.ts
  • test/tap/cli-monitor.acceptance.test.ts

Generated by 🚫 dangerJS against a2cbec3

@tommyknows tommyknows force-pushed the feat/app-vulns-feature-flag branch 2 times, most recently from 8cde5d7 to 76fa28b Compare October 5, 2022 14:51
@tommyknows tommyknows requested a review from a team as a code owner October 5, 2022 14:51
// the JSON output invalid.
// We also only want to print the message if the user did not overwrite
// the default with one of the flags.
if (options['exclude-app-vulns'] && !options['json']) {

Choose a reason for hiding this comment

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

It might be my basic TS knowledge, but don't we want here options['exclude-app-vulns'] == null && !options['json']?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so, though I agree that having a negated boolean is confusing (exclude-app-vulns vs. app-vulns).

Either way, we want to print the message if exclude-app-vulns is true. Also, this condition is within the larger if-else chain of "has the user overwritten this through the CLI". We only get to this expression if the user has not done so, and relies on the setting of the feature flag on the API.

The reasoning behind this is that if the user explicitly sets --app-vulns or --exclude-app-vulns, he already knows about this & does not need a warning message :)

@@ -98,14 +98,27 @@ export default async function test(
// TODO remove 'app-vulns' options and warning message once
// https://github.com/snyk/cli/pull/3433 is merged
if (options.docker) {
if (!options['app-vulns'] || options['exclude-app-vulns']) {
// order is important here, we want:

Choose a reason for hiding this comment

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

I guess there isn't a nice way to reuse the code we have for monitor..?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess there is, but that would probably be for a separate ticket. It would be a good idea though so that we also don't need reviews from other teams when changing these parts....

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(I'd also like to split out the API feature flag names into a separate package with constants, so that we don't need to copy that string...)

Choose a reason for hiding this comment

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

👍 for both

@@ -10,6 +10,7 @@ const featureFlagDefaults = (): Map<string, boolean> => {
return new Map([
['cliFailFast', false],
['iacIntegratedExperience', false],
['containerCliAppVulnsEnabled', false],

Choose a reason for hiding this comment

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

Is this the only testing we have? Makes me feel a little uncomfortable 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not directly - I actually had a couple of tests fail before I set that, as it returned true as the default value? By setting this here we make sure the fake API returns false, which makes our tests pass :)

I can add some more tests to check if everything behaves correctly if the API returns true though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a dedicated test, when the feature flag is set to true, and also had to fix some other tests :)

Choose a reason for hiding this comment

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

Great!

@tommyknows tommyknows force-pushed the feat/app-vulns-feature-flag branch 9 times, most recently from 0470984 to fdc274b Compare October 10, 2022 07:26
@@ -98,14 +98,27 @@ export default async function test(
// TODO remove 'app-vulns' options and warning message once
// https://github.com/snyk/cli/pull/3433 is merged
if (options.docker) {
if (!options['app-vulns'] || options['exclude-app-vulns']) {
// order is important here, we want:

Choose a reason for hiding this comment

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

👍 for both

@@ -10,6 +10,7 @@ const featureFlagDefaults = (): Map<string, boolean> => {
return new Map([
['cliFailFast', false],
['iacIntegratedExperience', false],
['containerCliAppVulnsEnabled', false],

Choose a reason for hiding this comment

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

Great!

This commit adds a check for the `containerCliAppVulnsEnabled` feature
flag. If neither `--exclude-app-vulns` nor `--app-vulns` are set, the
feature flag will be used to determine whether app vulnerabilities will
be scanned or not.
@tommyknows tommyknows force-pushed the feat/app-vulns-feature-flag branch from fdc274b to e6d1cda Compare October 18, 2022 10:41
@tommyknows
Copy link
Contributor Author

Added a second commit to fix the test failures.

See the commit message for a proper description. What I want to add is why this just came up with this PR, and has not been an issue before.

global-agent has two different initialisation routines, either by import 'global-agent/bootstrap'; or by import {bootstrap} from 'global-agent'; bootstrap().

The second way means that bootstrap needs to be explicitly called, and before this PR it was only called after we were done talking to the docker socket.

By adding the hasFeatureFlag call, which in turn calls bootstrap, the agent has now been replaced before we talked to the docker socket, thus triggering the issue.

@tommyknows tommyknows force-pushed the feat/app-vulns-feature-flag branch from e6d1cda to e697727 Compare October 18, 2022 11:35
For CLIv2, all traffic is proxied through a local server that the CLIv2
spawns. This is achieved by updating the `http.globalAgent` and
`http.request` and `http.get` functions through the `global-agent`
library.

However, this causes issues with HTTP traffic that is supposed to go to
local sockets. For example, `snyk container` talks to the
`/var/run/docker.sock` socket for doing some image operations (if the
socket exists). When the http agent and functions are replaced, this
causes traffic to the socket to be routed to / through the proxy, and
because at that point it is "proper" HTTP traffic, the destination is
not the socket anymore but `localhost:80` (the fallback).

The proxy has no way of handling this correctly, as all the information
of the socket is lost.

To fix this, there would have been two possibilities:
- Make it possible to use custom agents. Currently, even if a user
  creates a custom agent and passes it to `http.request` or `http.get`,
  this custom agent will not be used. This is because the `global-agent`
  library *enforces* the usage of the proxy-agent. There is a flag to
  change this behaviour (`forceGLobalAgent`), but we do not want to
  use this as traffic should *always* go through the proxy.
- Fix the `global-agent` library to not use the proxy-agent if traffic
  is supposed to go to sockets.

A [PR](gajus/global-agent#60) has been raised on
the library, but the repository seems to be unmaintaned. Because we need
this fix to continue with the app vulnerability enablement, this commit
adds a `postinstall` hook that patches the library in the `node-modules`
folder through a `git apply` command.

With the applied patch, traffic to the Docker socket (and all other
sockets) will not be rerouted through the proxy anymore.
@tommyknows tommyknows force-pushed the feat/app-vulns-feature-flag branch from e697727 to a2cbec3 Compare October 19, 2022 07:18
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
Copy link
Member

Choose a reason for hiding this comment

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

Quick note: How can we make sure the logic in this script file will correctly work (e.g. do we have any tests)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't have any tests directly, but...
every npm install (or npm ci) will call this script.
I've also needed to add the patch because some tests where failing without it.

-> if applying the patch wouldn't work, the tests won't pass :-)

So we have indirect tests, I guess 😄

I hope that's good enough, let me know if not.

Copy link
Member

Choose a reason for hiding this comment

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

Okey dokey, sounds good to me.

Copy link

@tony-snoop tony-snoop Oct 31, 2022

Choose a reason for hiding this comment

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

Hi @tommyknows,

Just a heads up about this issue that started happening today:
https://github.com/snyk/cli/issues/4183

Copy link
Member

Choose a reason for hiding this comment

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

Really sorry for this, @tony-snoop! And thank you a lot for reporting it!
We are rollbacking the changes right now: #4184

Copy link

@tony-snoop tony-snoop Oct 31, 2022

Choose a reason for hiding this comment

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

It's all good - thanks for jumping onto the fix so quickly @danlucian and for rolling back the changes.
Really REALLY appreciated :)

Quick question - do you know when the new version will become publicly available on https://www.npmjs.com/package/snyk ?

It's currently on version 1.1045.0. I'm refreshing the page regularly waiting for 1.1046.0 to appear :)

@tommyknows tommyknows merged commit 08c30f1 into master Oct 31, 2022
@tommyknows tommyknows deleted the feat/app-vulns-feature-flag branch October 31, 2022 08:07
danlucian added a commit that referenced this pull request Oct 31, 2022
@danlucian danlucian mentioned this pull request Oct 31, 2022
Avishagp added a commit that referenced this pull request Oct 31, 2022
tommyknows added a commit that referenced this pull request Dec 13, 2022
feat: disable container app scan with feature flag #4105
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants