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

Negating glob patterns not usable in AgentInjector resource #189

Open
lkallas opened this issue Apr 5, 2024 · 4 comments
Open

Negating glob patterns not usable in AgentInjector resource #189

lkallas opened this issue Apr 5, 2024 · 4 comments

Comments

@lkallas
Copy link

lkallas commented Apr 5, 2024

Background

Consider a case where there are many pods running with main container and some sidecar container (e.g. db-proxy) inside a Kubernetes cluster.

Contrast Kuberentes operator AgentInjector custom resource allows one to specify to which containers the agent is injected to inside a pod.

spec.selector.images allows specifying a glob pattern which is used to find a matching container where agent is injected.

I can see that there is C# Glob package in use.

Problem

In my case, I would like to inject nodejs agent into every container in many pods. But I do not want to inject it to db-proxy container which is not a nodejs workload and also does not need any instrumentation.

I struggle to find a good glob pattern for this purpose.
Seems that there actually isn't one for my case - well, Glob package does not implement it (not correctly at least IMO).

So to illustrate this problem, take this small program snippet I used to determine the glob pattern for my case.
I would like to match any Docker image that does not have "some-proxy" in it's name using negating pattern.

using System;
using GlobExpressions;

public interface IGlobMatcher
{
	bool Matches(string pattern, string value);
}

public class GlobMatcher : IGlobMatcher
{
	public bool Matches(string pattern, string value)
	{
		var glob = new Glob(pattern, GlobOptions.CaseInsensitive | GlobOptions.Compiled);
		return glob.IsMatch(value);
	}
}

public class Program
{
	public static void Main()
	{
		var matcher = new GlobMatcher();		
		var pattern = "!(*some-proxy*)";  // Trying to use negating pattern
		
		var result1 = matcher.Matches(pattern, "europe-docker.pkg.dev/project/docker-images/whatever:latest"); // This should return True
		Console.WriteLine(result1); // False
		
		var result2 = matcher.Matches(pattern, "europe-docker.pkg.dev/project/docker-images/some-proxy:latest"); // This should return False
		Console.WriteLine(result2); // False
	}
}

I see that you do not have a such test-case either in your tests.

I could use something like:

var pattern = "**/[!some-proxy]*";

But it will match characters "s", "o", "m", "e", "-", "p", "r", "o", "x", "y" and not in that particular order + char "o" does not have to repeat.
So it matches any permutation of those characters e.g. "oepx-msyro" and "sexy-prom". Not accurate enough.

Workaround

The only workaround right now is to specify each image name in the manifest I wish to have agent injected to. The list grows really long if there are hundreds of unique microservices/images.

apiVersion: agents.contrastsecurity.com/v1beta1
kind: AgentInjector
metadata:
  name: contrast-agent-injector
  namespace: somenamespace
spec:
  enabled: true
  version: latest
  type: nodejs
  selector:
    images:
      - "*important-web*"
      - "*some-other-web*"
      - "*restful-api*"
    labels:
      - name: contrast
        value: enabled

Could you assist/profide a fix?
@Silvenga @gamingrobot

Thank you!

@Silvenga
Copy link
Contributor

Silvenga commented Apr 5, 2024

Just a heads up, I no longer work for @Contrast-Security-OSS.

@lkallas
Copy link
Author

lkallas commented Apr 5, 2024

Just a heads up, I no longer work for @Contrast-Security-OSS.

I'm so sorry for mentioning you!
Just looked at the contributions insights and you were the top contributor - therefore mentioned you

@lkallas
Copy link
Author

lkallas commented Apr 6, 2024

Perhaps adding a regex support instead of glob patterns or adding glob + regex pattern support for image matching would make it a better/more flexible solution.

For example create new matcher e.g. RegexMatcher that will be used in the matching function if the spec.selector.images has image with a prefix re# indicating that regular expression should be used for matching (not glob).
That way it wouldn't be a breaking change either.

In my case negative lookahead regex would do the trick.

^(?!.*some-proxy).*$

So given my suggestion the manifest could look like this:

apiVersion: agents.contrastsecurity.com/v1beta1
kind: AgentInjector
metadata:
  name: contrast-agent-injector
  namespace: somenamespace
spec:
  enabled: true
  version: latest
  type: nodejs
  selector:
    images:
      - "re#^(?!.*some-proxy).*$"
    labels:
      - name: contrast
        value: enabled

@marklacasse
Copy link

Hi @lkallas Thanks for the suggestion. I've chatted with our developers and have submitted an enhancement request for the behavior updates on the operator. (Ref: CUST-4301 our ticket tracking system is internal.)

While in this case, since the other container is not a nodeJS application, we would essentially do nothing. Though it is still going through the motions, it should have no effects on the application. There is still a case for this and tighter control over the containers we inject into would be great.

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

No branches or pull requests

3 participants