Skip to content

Commit 454d8fa

Browse files
committed
2.0.5 13-07-2025
- Kubernetes Security Standards: [Insecure sysctls](https://protsenko.dev/infrastructure-security/insecure-sysctls/)
1 parent 67c706f commit 454d8fa

10 files changed

Lines changed: 137 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
# Cloud (IaC) Security Changelog
44

5+
## [2.0.5] 13-07-2025
6+
7+
### Added
8+
- Kubernetes Security Standards: [Insecure sysctls](https://protsenko.dev/infrastructure-security/insecure-sysctls/)
9+
510
## [2.0.4] 05-07-2025
611

712
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
Cloud (IaC) Security Linter for JetBrains IDEs (e.g., IntelliJ IDEA, PyCharm, WebStorm, and more).
1313

14-
Scan Docker, Kubernetes, and other Infrastructure-as-Code (IaC) files for security vulnerabilities and misconfigurations directly within your JetBrains IDE.
14+
Scan Docker (dockerfile and compose), Kubernetes files for security vulnerabilities and misconfigurations directly within your JetBrains IDE.
1515

1616
## Why this plugin?
1717

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
pluginGroup = dev.protsenko.securityLinter
22
pluginName = Cloud (IaC) Security
33
pluginRepositoryUrl = https://github.com/NordCoderd/cloud-security-plugin
4-
pluginVersion = 2.0.4
4+
pluginVersion = 2.0.5
55

66
# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
77
pluginSinceBuild = 231
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package dev.protsenko.securityLinter.kubernetes
2+
3+
import com.intellij.codeInspection.LocalInspectionTool
4+
import com.intellij.codeInspection.ProblemHighlightType
5+
import com.intellij.codeInspection.ProblemsHolder
6+
import com.intellij.psi.PsiElementVisitor
7+
import dev.protsenko.securityLinter.core.HtmlProblemDescriptor
8+
import dev.protsenko.securityLinter.core.SecurityPluginBundle
9+
import dev.protsenko.securityLinter.kubernetes.quickfix.ReplaceValueToDefaultQuickFix
10+
import dev.protsenko.securityLinter.utils.YamlPath
11+
import org.jetbrains.yaml.psi.YAMLDocument
12+
import org.jetbrains.yaml.psi.YAMLScalar
13+
import org.jetbrains.yaml.psi.YAMLSequence
14+
15+
class InsecureSysctlsInspection : LocalInspectionTool() {
16+
17+
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
18+
return object : BaseKubernetesVisitor() {
19+
override fun analyze(specPrefix: String, document: YAMLDocument) {
20+
val seccompProfileType = YamlPath.findByYamlPath(
21+
"$specPrefix$SYSCTL_PATH",
22+
document
23+
) as? YAMLSequence ?: return
24+
25+
for (sysctl in seccompProfileType.items) {
26+
val sysctlKey = sysctl
27+
.keysValues
28+
.firstOrNull { it.name == "name" } ?: continue
29+
val sysctlValueText = sysctlKey.valueText
30+
if (sysctlValueText !in allowedSysctls) {
31+
val descriptor = HtmlProblemDescriptor(
32+
sysctl,
33+
SecurityPluginBundle.message("kube011.documentation"),
34+
SecurityPluginBundle.message("kube011.problem-text"),
35+
ProblemHighlightType.ERROR, emptyArray()
36+
)
37+
holder.registerProblem(descriptor)
38+
}
39+
}
40+
41+
}
42+
}
43+
}
44+
}
45+
46+
private val SYSCTL_PATH = "spec.securityContext.sysctls"
47+
private val allowedSysctls = setOf(
48+
"",
49+
"kernel.shm_rmid_forced",
50+
"net.ipv4.ip_local_port_range",
51+
"net.ipv4.ip_unprivileged_port_start",
52+
"net.ipv4.tcp_syncookies",
53+
"net.ipv4.ping_group_range",
54+
"net.ipv4.ip_local_reserved_ports",
55+
"net.ipv4.tcp_keepalive_time",
56+
"net.ipv4.tcp_fin_timeout",
57+
"net.ipv4.tcp_keepalive_intvl",
58+
"net.ipv4.tcp_keepalive_probes"
59+
)

src/main/resources/META-INF/dev.protsenko.security-linter-yaml.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,10 @@
6565
displayName="Unconfined seccomp profile"
6666
groupPathKey="common.group-key" groupKey="common.kubernetes-group-key"
6767
enabledByDefault="true" language="yaml"/>
68+
<localInspection
69+
implementationClass="dev.protsenko.securityLinter.kubernetes.InsecureSysctlsInspection"
70+
displayName="Insecure systctls"
71+
groupPathKey="common.group-key" groupKey="common.kubernetes-group-key"
72+
enabledByDefault="true" language="yaml"/>
6873
</extensions>
6974
</idea-plugin>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<body>
3+
<p>Detects insecure sysctls</p>
4+
<p>Sysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed "safe" subset.</p>
5+
</body>
6+
</html>

src/main/resources/messages/SecurityPluginBundle.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ kube010.documentation=insecure-seccomp-profile
161161
kube010.problem-text=Seccomp profile set to 'Unconfined' disables syscall filtering and exposes the container to kernel-level attacks.
162162
kube010.qf.fix-value=Set the type to 'RuntimeDefault'
163163

164+
## kube011
165+
kube011.documentation=insecure-sysctls
166+
kube011.problem-text=Sysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed "safe" subset.
167+
164168
# Not implemented
165169
ds029.missing-healthcheck=Missing HEALTHCHECK instruction
166170
ds023.multiple-exposed-port=Port {0} exposed more than one time.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package dev.protsenko.securityLinter.kubernetes
2+
3+
import com.intellij.codeInspection.LocalInspectionTool
4+
import dev.protsenko.securityLinter.core.KubernetesHighlightingBaseTest
5+
6+
class KUBE011InsecureSysctls(
7+
override val ruleFolderName: String = "KUBE011",
8+
override val targetFileName: String = "pod.yaml",
9+
override val targetInspection: LocalInspectionTool = InsecureSysctlsInspection(),
10+
override val customFiles: Set<String> = setOf()
11+
) : KubernetesHighlightingBaseTest()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: safe-sysctl-demo
5+
labels:
6+
app: demo
7+
spec:
8+
securityContext:
9+
sysctls:
10+
- name: net.ipv4.ip_local_port_range
11+
value: "1024 65535"
12+
- name: net.ipv4.tcp_syncookies
13+
value: "1"
14+
- name: net.ipv4.tcp_keepalive_time # ≥ 1.29
15+
value: "7200"
16+
- name: net.ipv4.tcp_keepalive_intvl # ≥ 1.29
17+
value: "75"
18+
- name: net.ipv4.tcp_keepalive_probes # ≥ 1.29
19+
value: "9"
20+
containers:
21+
- name: nginx
22+
image: nginx:1.29-alpine
23+
ports:
24+
- containerPort: 80
25+
securityContext:
26+
allowPrivilegeEscalation: false
27+
capabilities:
28+
drop: ["ALL"]
29+
readOnlyRootFilesystem: true
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: unsafe-sysctl-demo
5+
spec:
6+
securityContext:
7+
sysctls:
8+
<error descr="Sysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed \"safe\" subset.">- name: net.core.somaxconn
9+
value: "1024"</error>
10+
<error descr="Sysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed \"safe\" subset.">- name: kernel.msgmax
11+
value: "65536"</error>
12+
containers:
13+
- name: nginx
14+
image: nginx:1.29-alpine
15+
ports:
16+
- containerPort: 80

0 commit comments

Comments
 (0)