1use serde::{Deserialize, Serialize};
2
3use crate::constants::commands as command_constants;
4
5#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
7#[derive(Debug, Clone, Deserialize, Serialize)]
8pub struct CommandsConfig {
9 #[serde(default)]
11 pub allow_list: Vec<String>,
12
13 #[serde(default = "default_extra_path_entries")]
15 pub extra_path_entries: Vec<String>,
16
17 #[serde(default)]
19 pub deny_list: Vec<String>,
20
21 #[serde(default)]
23 pub allow_glob: Vec<String>,
24
25 #[serde(default)]
27 pub deny_glob: Vec<String>,
28
29 #[serde(default)]
31 pub allow_regex: Vec<String>,
32
33 #[serde(default)]
35 pub deny_regex: Vec<String>,
36}
37
38impl Default for CommandsConfig {
39 fn default() -> Self {
40 Self {
41 allow_list: vec![
42 "ls".to_string(),
43 "pwd".to_string(),
44 "cat".to_string(),
45 "grep".to_string(),
46 "find".to_string(),
47 "head".to_string(),
48 "tail".to_string(),
49 "wc".to_string(),
50 "git status".to_string(),
51 "git diff".to_string(),
52 "git log".to_string(),
53 "git show".to_string(),
54 "git branch".to_string(),
55 "git remote".to_string(),
56 "cargo check".to_string(),
57 "cargo build".to_string(),
58 "cargo build --release".to_string(),
59 "cargo build --profile release".to_string(),
60 "cargo test".to_string(),
61 "cargo run".to_string(),
62 "cargo clippy".to_string(),
63 "cargo fmt".to_string(),
64 "cargo tree".to_string(),
65 "cargo metadata".to_string(),
66 "cargo doc".to_string(),
67 "cargo nextest run".to_string(),
68 "cargo nextest".to_string(),
69 "rustc".to_string(),
70 "which".to_string(),
71 "echo".to_string(),
72 "printf".to_string(),
73 "date".to_string(),
74 "tree".to_string(),
75 "stat".to_string(),
76 "file".to_string(),
77 "sort".to_string(),
78 "uniq".to_string(),
79 "cut".to_string(),
80 "awk".to_string(),
81 "sed".to_string(),
82 "tar".to_string(),
83 "zip".to_string(),
84 "unzip".to_string(),
85 "gzip".to_string(),
86 "gunzip".to_string(),
87 "make".to_string(),
88 "cmake".to_string(),
89 "ninja".to_string(),
90 "python3".to_string(),
91 "python3 -m pip install".to_string(),
92 "python3 -m pytest".to_string(),
93 "python3 -m build".to_string(),
94 "python".to_string(),
95 "pip3".to_string(),
96 "pip".to_string(),
97 "virtualenv".to_string(),
98 "node".to_string(),
99 "npm".to_string(),
100 "npm run build".to_string(),
101 "npm run test".to_string(),
102 "npm install".to_string(),
103 "yarn".to_string(),
104 "yarn build".to_string(),
105 "yarn test".to_string(),
106 "pnpm".to_string(),
107 "pnpm build".to_string(),
108 "pnpm test".to_string(),
109 "bun".to_string(),
110 "bun install".to_string(),
111 "bun run".to_string(),
112 "bun test".to_string(),
113 "npx".to_string(),
114 "go".to_string(),
115 "go build".to_string(),
116 "go test".to_string(),
117 "gcc".to_string(),
118 "g++".to_string(),
119 "clang".to_string(),
120 "clang++".to_string(),
121 "javac".to_string(),
122 "java".to_string(),
123 "mvn".to_string(),
124 "gradle".to_string(),
125 "docker".to_string(),
126 "docker-compose".to_string(),
127 ],
128 extra_path_entries: default_extra_path_entries(),
129 deny_list: vec![
130 "rm -rf /".to_string(),
131 "rm -rf ~".to_string(),
132 "rm -rf /*".to_string(),
133 "rm -rf /home".to_string(),
134 "rm -rf /usr".to_string(),
135 "rm -rf /etc".to_string(),
136 "rm -rf /var".to_string(),
137 "rm -rf /opt".to_string(),
138 "rmdir /".to_string(),
139 "rmdir /home".to_string(),
140 "rmdir /usr".to_string(),
141 "shutdown".to_string(),
142 "reboot".to_string(),
143 "halt".to_string(),
144 "poweroff".to_string(),
145 "init 0".to_string(),
146 "init 6".to_string(),
147 "systemctl poweroff".to_string(),
148 "systemctl reboot".to_string(),
149 "systemctl halt".to_string(),
150 "sudo rm".to_string(),
151 "sudo chmod 777".to_string(),
152 "sudo chown".to_string(),
153 "sudo passwd".to_string(),
154 "sudo su".to_string(),
155 "sudo -i".to_string(),
156 "sudo bash".to_string(),
157 "su root".to_string(),
158 "su -".to_string(),
159 "format".to_string(),
160 "fdisk".to_string(),
161 "mkfs".to_string(),
162 "mkfs.ext4".to_string(),
163 "mkfs.xfs".to_string(),
164 "mkfs.vfat".to_string(),
165 "dd if=/dev/zero".to_string(),
166 "dd if=/dev/random".to_string(),
167 "dd if=/dev/urandom".to_string(),
168 "wget --no-check-certificate".to_string(),
169 ":(){ :|:& };:".to_string(), "nohup bash -i".to_string(),
171 "exec bash -i".to_string(),
172 "eval".to_string(),
173 "source /etc/bashrc".to_string(),
174 "source ~/.bashrc".to_string(),
175 "chmod 777".to_string(),
176 "chmod -R 777".to_string(),
177 "chown -R".to_string(),
178 "chgrp -R".to_string(),
179 "rm ~/.ssh/*".to_string(),
180 "rm -r ~/.ssh".to_string(),
181 "cat /etc/passwd".to_string(),
182 "cat /etc/shadow".to_string(),
183 "cat ~/.ssh/id_*".to_string(),
184 "tail -f /var/log".to_string(),
185 "head -n 1 /var/log".to_string(),
186 ],
187 allow_glob: vec![
188 "git *".to_string(),
189 "cargo *".to_string(),
190 "cargo nextest *".to_string(),
191 "rustc *".to_string(),
192 "python *".to_string(),
193 "python3 *".to_string(),
194 "pip *".to_string(),
195 "pip3 *".to_string(),
196 "node *".to_string(),
197 "npm *".to_string(),
198 "npm run *".to_string(),
199 "yarn *".to_string(),
200 "yarn run *".to_string(),
201 "pnpm *".to_string(),
202 "pnpm run *".to_string(),
203 "bun *".to_string(),
204 "bun run *".to_string(),
205 "npx *".to_string(),
206 "go *".to_string(),
207 "gcc *".to_string(),
208 "g++ *".to_string(),
209 "clang *".to_string(),
210 "clang++ *".to_string(),
211 "javac *".to_string(),
212 "java *".to_string(),
213 "mvn *".to_string(),
214 "gradle *".to_string(),
215 "make *".to_string(),
216 "cmake *".to_string(),
217 "ninja *".to_string(),
218 "docker *".to_string(),
219 "docker-compose *".to_string(),
220 "virtualenv *".to_string(),
221 "tar *".to_string(),
222 "zip *".to_string(),
223 "unzip *".to_string(),
224 "gzip *".to_string(),
225 "gunzip *".to_string(),
226 ],
227 deny_glob: vec![
228 "rm *".to_string(),
229 "sudo *".to_string(),
230 "chmod *".to_string(),
231 "chown *".to_string(),
232 "kill *".to_string(),
233 "pkill *".to_string(),
234 "systemctl *".to_string(),
235 "service *".to_string(),
236 "mount *".to_string(),
237 "umount *".to_string(),
238 "docker run *".to_string(),
239 "kubectl *".to_string(),
240 ],
241 allow_regex: vec![
242 r"^(ls|pwd|cat|grep|find|head|tail|wc|echo|printf|date|tree|stat|file|sort|uniq|cut|awk|sed|tar|zip|unzip|gzip|gunzip)\b".to_string(),
243 r"^git (status|diff|log|show|branch|remote)\b".to_string(),
244 r"^cargo (check|build|test|run|doc|clippy|fmt|tree|metadata|nextest)\b".to_string(),
245 r"^rustc\b".to_string(),
246 r"^(python|python3) (-m | )?\w*".to_string(),
247 r"^(pip|pip3)\b".to_string(),
248 r"^virtualenv\b".to_string(),
249 r"^(node|npm|yarn|pnpm|bun|npx)\b".to_string(),
250 r"^go\b".to_string(),
251 r"^(gcc|g\+\+|clang|clang\++)\b".to_string(),
252 r"^(javac|java)\b".to_string(),
253 r"^(mvn|gradle)\b".to_string(),
254 r"^(make|cmake)\b".to_string(),
255 r"^(docker|docker-compose)\b".to_string(),
256 ],
257 deny_regex: vec![
258 r"rm\s+(-rf|--force)".to_string(),
259 r"sudo\s+.*".to_string(),
260 r"chmod\s+.*".to_string(),
261 r"chown\s+.*".to_string(),
262 r"docker\s+run\s+.*--privileged".to_string(),
263 r"kubectl\s+(delete|drain|uncordon)".to_string(),
264 ],
265 }
266 }
267}
268
269fn default_extra_path_entries() -> Vec<String> {
270 command_constants::DEFAULT_EXTRA_PATH_ENTRIES
271 .iter()
272 .map(|value| value.to_string())
273 .collect()
274}