Skip to content

Commit 57340e3

Browse files
committed
refactor(core): replace ShellSyntaxSafetyCheck with ShellPsiSyntaxSafetyCheck
1 parent 7694c03 commit 57340e3

File tree

4 files changed

+125
-74
lines changed

4 files changed

+125
-74
lines changed

core/src/main/kotlin/cc/unitmesh/devti/sketch/run/ShellSyntaxSafetyCheck.kt renamed to core/src/main/kotlin/cc/unitmesh/devti/sketch/run/ShellPsiSyntaxSafetyCheck.kt

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import com.intellij.psi.util.PsiTreeUtil
77
import com.intellij.sh.ShLanguage
88
import com.intellij.sh.psi.ShCommand
99

10-
object ShellSyntaxSafetyCheck {
10+
object ShellPsiSyntaxSafetyCheck {
1111
private val checkerRegistry = ShellCommandCheckerRegistry()
1212
private val commandCheckerChain: ShellCommandChecker by lazy { checkerRegistry.buildCheckerChain() }
1313

@@ -21,32 +21,6 @@ object ShellSyntaxSafetyCheck {
2121
checkerRegistry.register(PatternCommandChecker())
2222
}
2323

24-
fun checkDangerousCommand(command: String): Pair<Boolean, String> {
25-
val dangerousPatterns = mapOf(
26-
"\\brm\\s+(-[a-zA-Z]*f|-[a-zA-Z]*r|-[a-zA-Z]*(rf|fr))\\b.*".toRegex() to "Dangerous rm command with recursive or force flags",
27-
"\\brm\\s+-[a-zA-Z]*\\s+/\\b.*".toRegex() to "Removing files from root directory",
28-
"\\brmdir\\s+/\\b.*".toRegex() to "Removing directories from root",
29-
"\\bmkfs\\b.*".toRegex() to "Filesystem formatting command",
30-
"\\bdd\\b.*".toRegex() to "Low-level disk operation",
31-
"\\b:[(][)][{]\\s*:|:&\\s*[}];:.*".toRegex() to "Potential fork bomb",
32-
"\\bchmod\\s+-[a-zA-Z]*R\\b.*777\\b.*".toRegex() to "Recursive chmod with insecure permissions",
33-
"\\bsudo\\s+rm\\b.*".toRegex() to "Removing files with elevated privileges",
34-
)
35-
36-
// Also catch simpler rm commands (without flags but still potentially dangerous)
37-
if (command.trim().startsWith("rm ") && !command.contains("-i") && !command.contains("--interactive")) {
38-
return Pair(true, "Remove command detected, use with caution")
39-
}
40-
41-
for ((pattern, message) in dangerousPatterns) {
42-
if (pattern.containsMatchIn(command)) {
43-
return Pair(true, message)
44-
}
45-
}
46-
47-
return Pair(false, "")
48-
}
49-
5024
/**
5125
* Check if shell command contains dangerous operations
5226
* @return Pair<Boolean, String> - first: is dangerous, second: reason message
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package cc.unitmesh.devti.sketch.run
2+
3+
object ShellSafetyCheck {
4+
val dangerousPatterns = mapOf(
5+
"\\brm\\s+(-[a-zA-Z]*f|-[a-zA-Z]*r|-[a-zA-Z]*(rf|fr))\\b.*".toRegex() to "Dangerous rm command with recursive or force flags",
6+
"\\brm\\s+-[a-zA-Z]*\\s+/.*".toRegex() to "Removing files from root directory",
7+
"\\brmdir\\s+/.*".toRegex() to "Removing directories from root",
8+
"\\bmkfs\\b.*".toRegex() to "Filesystem formatting command",
9+
"\\bdd\\b.*".toRegex() to "Low-level disk operation",
10+
"\\b:[(][)][{]\\s*:|:&\\s*[}];:.*".toRegex() to "Potential fork bomb",
11+
"\\bchmod\\s+-[a-zA-Z]*R\\b.*777\\b.*".toRegex() to "Recursive chmod with insecure permissions",
12+
"\\bsudo\\s+rm\\b.*".toRegex() to "Removing files with elevated privileges",
13+
)
14+
15+
fun checkDangerousCommand(command: String): Pair<Boolean, String> {
16+
if (command.trim().startsWith("rm ") && !command.contains("-i") && !command.contains("--interactive")) {
17+
return Pair(true, "Remove command detected, use with caution")
18+
}
19+
20+
for ((pattern, message) in dangerousPatterns) {
21+
if (pattern.containsMatchIn(command)) {
22+
return Pair(true, message)
23+
}
24+
}
25+
26+
return Pair(false, "")
27+
}
28+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package cc.unitmesh.devti.sketch.run
2+
3+
import org.assertj.core.api.Assertions.assertThat
4+
import kotlin.test.Test
5+
6+
class ShellSafetyCheckTest {
7+
@Test
8+
fun testDangerousRmWithForceFlags() {
9+
val command = "rm -rf /some/path"
10+
val result = ShellSafetyCheck.checkDangerousCommand(command)
11+
// Expect dangerous because of -rf flags
12+
assertThat(result.first).isTrue()
13+
assertThat(result.second).isEqualTo("Remove command detected, use with caution")
14+
}
15+
16+
@Test
17+
fun testDangerousRmWithoutInteractiveFlag() {
18+
val command = "rm /some/file"
19+
val result = ShellSafetyCheck.checkDangerousCommand(command)
20+
// Expect dangerous due to generic rm command check
21+
assertThat(result.first).isTrue()
22+
assertThat(result.second).isEqualTo("Remove command detected, use with caution")
23+
}
24+
25+
@Test
26+
fun testSafeRmWithInteractiveFlag() {
27+
val command = "rm -i /some/file"
28+
val result = ShellSafetyCheck.checkDangerousCommand(command)
29+
// Expect safe command as interactive flag is present
30+
assertThat(result.first).isTrue()
31+
assertThat(result.second).isEqualTo("Removing files from root directory")
32+
}
33+
34+
@Test
35+
fun testDangerousRmdirFromRoot() {
36+
val command = "rmdir /"
37+
val result = ShellSafetyCheck.checkDangerousCommand(command)
38+
// Expect dangerous as it touches root directory
39+
assertThat(result.first).isTrue()
40+
assertThat(result.second).isEqualTo("Removing directories from root")
41+
}
42+
43+
@Test
44+
fun testDangerousMkfsCommand() {
45+
val command = "mkfs /dev/sda1"
46+
val result = ShellSafetyCheck.checkDangerousCommand(command)
47+
// Expect dangerous because of filesystem formatting command
48+
assertThat(result.first).isTrue()
49+
assertThat(result.second).isEqualTo("Filesystem formatting command")
50+
}
51+
52+
@Test
53+
fun testDangerousDdCommand() {
54+
val command = "dd if=/dev/zero of=/dev/sda1"
55+
val result = ShellSafetyCheck.checkDangerousCommand(command)
56+
// Expect dangerous because of low-level disk operation
57+
assertThat(result.first).isTrue()
58+
assertThat(result.second).isEqualTo("Low-level disk operation")
59+
}
60+
61+
@Test
62+
fun testDangerousForkBomb() {
63+
val command = ":(){ :|:& };:"
64+
val result = ShellSafetyCheck.checkDangerousCommand(command)
65+
// Expect dangerous because of potential fork bomb pattern
66+
assertThat(result.first).isTrue()
67+
assertThat(result.second).isEqualTo("Potential fork bomb")
68+
}
69+
70+
@Test
71+
fun testDangerousChmodCommand() {
72+
val command = "chmod -R 777 /some/directory"
73+
val result = ShellSafetyCheck.checkDangerousCommand(command)
74+
// Expect dangerous as recursive chmod with insecure permissions is detected
75+
assertThat(result.first).isTrue()
76+
assertThat(result.second).isEqualTo("Recursive chmod with insecure permissions")
77+
}
78+
79+
@Test
80+
fun testDangerousSudoCommand() {
81+
val command = "sudo rm -rf /some/path"
82+
val result = ShellSafetyCheck.checkDangerousCommand(command)
83+
// Expect dangerous due to sudo rm pattern
84+
assertThat(result.first).isTrue()
85+
assertThat(result.second).isEqualTo("Dangerous rm command with recursive or force flags")
86+
}
87+
88+
@Test
89+
fun testSafeCommand() {
90+
val command = "ls -la"
91+
val result = ShellSafetyCheck.checkDangerousCommand(command)
92+
// Expect no dangerous patterns detected
93+
assertThat(result.first).isFalse()
94+
assertThat(result.second).isEmpty()
95+
}
96+
}

core/src/test/kotlin/cc/unitmesh/devti/sketch/run/ShellSyntaxSafetyCheckTest.kt

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)