Skip to content

Commit

Permalink
removed the use of labels (#300)
Browse files Browse the repository at this point in the history
  • Loading branch information
jt-dd authored Dec 3, 2024
1 parent 7dd7f32 commit 5965f9b
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 294 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,21 @@
import static org.apache.tinkerpop.gremlin.process.traversal.Scope.local;
import static org.apache.tinkerpop.gremlin.structure.Column.values;


/**
* This KubeHound DSL is meant to be used with the Kubernetes attack graph created by the KubeHound application.
* This KubeHound DSL is meant to be used with the Kubernetes attack graph
* created by the KubeHound application.
* <p/>
* All DSLs should extend {@code GraphTraversal.Admin} and be suffixed with "TraversalDsl". Simply add DSL traversal
* methods to this interface. Use Gremlin's steps to build the underlying traversal in these methods to ensure
* compatibility with the rest of the TinkerPop stack and provider implementations.
* All DSLs should extend {@code GraphTraversal.Admin} and be suffixed with
* "TraversalDsl". Simply add DSL traversal
* methods to this interface. Use Gremlin's steps to build the underlying
* traversal in these methods to ensure
* compatibility with the rest of the TinkerPop stack and provider
* implementations.
* <p/>
* Arguments provided to the {@code GremlinDsl} annotation are all optional. In this case, a {@code traversalSource} is
* specified which points to a specific implementation to use. Had that argument not been specified then a default
* Arguments provided to the {@code GremlinDsl} annotation are all optional. In
* this case, a {@code traversalSource} is
* specified which points to a specific implementation to use. Had that argument
* not been specified then a default
* {@code TraversalSource} would have been generated.
*/
@GremlinDsl(traversalSource = "com.datadog.ase.kubehound.KubeHoundTraversalSourceDsl")
Expand All @@ -54,148 +59,161 @@ public interface KubeHoundTraversalDsl<S, E> extends GraphTraversal.Admin<S, E>
public static final int PATH_HOPS_MIN_DEFAULT = 6;

/**
* From a {@code Vertex} traverse immediate edges to display the next set of possible attacks and targets.
* From a {@code Vertex} traverse immediate edges to display the next set of
* possible attacks and targets.
*
*/
public default GraphTraversal<S, Path> attacks() {
return outE().inV().path();
}

/**
* From a {@code Vertex} filter on whether incoming vertices are critical assets.
* From a {@code Vertex} filter on whether incoming vertices are critical
* assets.
*/
@GremlinDsl.AnonymousMethod(returnTypeParameters = {"A", "A"}, methodTypeParameters = {"A"})
@GremlinDsl.AnonymousMethod(returnTypeParameters = { "A", "A" }, methodTypeParameters = { "A" })
public default GraphTraversal<S, E> critical() {
return has("critical", true);
}

/**
* From a {@code Vertex} traverse edges until {@code maxHops} is exceeded or a critical asset is reached and return all paths.
* From a {@code Vertex} traverse edges until {@code maxHops} is exceeded or a
* critical asset is reached and return all paths.
*
* @param maxHops the maximum number of hops in an attack path
*/
public default GraphTraversal<S, Path> criticalPaths(int maxHops) {
if (maxHops < PATH_HOPS_MIN) throw new IllegalArgumentException(String.format("maxHops must be >= %d", PATH_HOPS_MIN));
if (maxHops > PATH_HOPS_MAX) throw new IllegalArgumentException(String.format("maxHops must be <= %d", PATH_HOPS_MAX));
if (maxHops < PATH_HOPS_MIN)
throw new IllegalArgumentException(String.format("maxHops must be >= %d", PATH_HOPS_MIN));
if (maxHops > PATH_HOPS_MAX)
throw new IllegalArgumentException(String.format("maxHops must be <= %d", PATH_HOPS_MAX));

return repeat((
(KubeHoundTraversalDsl) __.outE())
return repeat(((KubeHoundTraversalDsl) __.outE())
.inV()
.simplePath()
).until(
__.has("critical", true)
.or()
.loops()
.is(maxHops)
).has("critical", true)
.path();
.simplePath()).until(
__.has("critical", true)
.or()
.loops()
.is(maxHops))
.has("critical", true)
.path();
}

/**
* From a {@code Vertex} traverse edges until a critical asset is reached and return all paths.
* From a {@code Vertex} traverse edges until a critical asset is reached and
* return all paths.
*/
public default GraphTraversal<S, Path> criticalPaths() {
return criticalPaths(PATH_HOPS_DEFAULT);
}

/**
* From a {@code Vertex} traverse edges EXCLUDING labels provided in {@code exclusions} until {@code maxHops} is exceeded or
* a critical asset is reached and return all paths.
* From a {@code Vertex} traverse edges EXCLUDING labels provided in
* {@code exclusions} until {@code maxHops} is exceeded or
* a critical asset is reached and return all paths.
*
* @param maxHops the maximum number of hops in an attack path
* @param maxHops the maximum number of hops in an attack path
* @param exclusions edge labels to exclude from paths
*/
public default GraphTraversal<S, Path> criticalPathsFilter(int maxHops, String... exclusions) {
if (exclusions.length <= 0) throw new IllegalArgumentException("exclusions must be provided (otherwise use criticalPaths())");
if (maxHops < PATH_HOPS_MIN) throw new IllegalArgumentException(String.format("maxHops must be >= %d", PATH_HOPS_MIN));
if (maxHops > PATH_HOPS_MAX) throw new IllegalArgumentException(String.format("maxHops must be <= %d", PATH_HOPS_MAX));

return repeat((
(KubeHoundTraversalDsl) __.outE())
.hasLabel(P.not(P.within(exclusions)))
if (exclusions.length <= 0)
throw new IllegalArgumentException("exclusions must be provided (otherwise use criticalPaths())");
if (maxHops < PATH_HOPS_MIN)
throw new IllegalArgumentException(String.format("maxHops must be >= %d", PATH_HOPS_MIN));
if (maxHops > PATH_HOPS_MAX)
throw new IllegalArgumentException(String.format("maxHops must be <= %d", PATH_HOPS_MAX));

return repeat(((KubeHoundTraversalDsl) __.outE())
.has("class", P.not(P.within(exclusions)))
.inV()
.simplePath()
).until(
__.has("critical", true)
.or()
.loops()
.is(maxHops)
).has("critical", true)
.path();
.simplePath()).until(
__.has("critical", true)
.or()
.loops()
.is(maxHops))
.has("critical", true)
.path();
}

/**
* From a {@code Vertex} filter on whether incoming vertices have at least one path to a critical asset.
* From a {@code Vertex} filter on whether incoming vertices have at least one
* path to a critical asset.
*/
@GremlinDsl.AnonymousMethod(returnTypeParameters = {"A", "A"}, methodTypeParameters = {"A"})
@GremlinDsl.AnonymousMethod(returnTypeParameters = { "A", "A" }, methodTypeParameters = { "A" })
public default GraphTraversal<S, E> hasCriticalPath() {
return where(__.criticalPaths().limit(1));
return where(__.criticalPaths().limit(1));
}

/**
* From a {@code Vertex} returns the hop count of the shortest path to a critical asset.
* From a {@code Vertex} returns the hop count of the shortest path to a
* critical asset.
*
*/
public default <E2 extends Comparable> GraphTraversal<S, E2> minHopsToCritical() {
return minHopsToCritical(PATH_HOPS_MIN_DEFAULT);
}

/**
* From a {@code Vertex} returns the hop count of the shortest path to a critical asset.
*
* From a {@code Vertex} returns the hop count of the shortest path to a
* critical asset.
*
* @param maxHops the maximum number of hops in an attack path to consider
*
*/
public default <E2 extends Comparable> GraphTraversal<S, E2> minHopsToCritical(int maxHops) {
if (maxHops < PATH_HOPS_MIN) throw new IllegalArgumentException(String.format("maxHops must be >= %d", PATH_HOPS_MIN));
if (maxHops > PATH_HOPS_MAX) throw new IllegalArgumentException(String.format("maxHops must be <= %d", PATH_HOPS_MAX));

return repeat((
(KubeHoundTraversalDsl) __.out())
.simplePath()
).until(
__.has("critical", true)
.or()
.loops()
.is(maxHops)
).has("critical", true)
.path()
.count(local)
.min();
if (maxHops < PATH_HOPS_MIN)
throw new IllegalArgumentException(String.format("maxHops must be >= %d", PATH_HOPS_MIN));
if (maxHops > PATH_HOPS_MAX)
throw new IllegalArgumentException(String.format("maxHops must be <= %d", PATH_HOPS_MAX));

return repeat(((KubeHoundTraversalDsl) __.out())
.simplePath()).until(
__.has("critical", true)
.or()
.loops()
.is(maxHops))
.has("critical", true)
.path()
.count(local)
.min();
}

/**
* From a {@code Vertex} returns a group count (by label) of paths to a critical asset.
* From a {@code Vertex} returns a group count (by label) of paths to a critical
* asset.
*
*/
public default <K> GraphTraversal<S, Map<K, Long>> criticalPathsFreq() {
return criticalPathsFreq(PATH_HOPS_DEFAULT);
return criticalPathsFreq(PATH_HOPS_DEFAULT);
}

/**
* From a {@code Vertex} returns a group count (by label) of paths to a critical asset.
* From a {@code Vertex} returns a group count (by label) of paths to a critical
* asset.
*
* @param maxHops the maximum number of hops in an attack path
*/
public default <K> GraphTraversal<S, Map<K, Long>> criticalPathsFreq(int maxHops) {
if (maxHops < PATH_HOPS_MIN) throw new IllegalArgumentException(String.format("maxHops must be >= %d", PATH_HOPS_MIN));
if (maxHops > PATH_HOPS_MAX) throw new IllegalArgumentException(String.format("maxHops must be <= %d", PATH_HOPS_MAX));
if (maxHops < PATH_HOPS_MIN)
throw new IllegalArgumentException(String.format("maxHops must be >= %d", PATH_HOPS_MIN));
if (maxHops > PATH_HOPS_MAX)
throw new IllegalArgumentException(String.format("maxHops must be <= %d", PATH_HOPS_MAX));

return repeat(
(KubeHoundTraversalDsl) __.outE()
.inV()
.simplePath()
).emit()
.until(
__.has("critical", true)
.or()
.loops()
.is(maxHops)
).has("critical", true)
.path()
.by(T.label)
.groupCount()
.order(local)
.by(__.select(values), Order.desc);
.inV()
.simplePath())
.emit()
.until(
__.has("critical", true)
.or()
.loops()
.is(maxHops))
.has("critical", true)
.path()
.by(T.label)
.groupCount()
.order(local)
.by(__.select(values), Order.desc);
}
}
Loading

0 comments on commit 5965f9b

Please sign in to comment.