Skip to content

Commit ea2b73b

Browse files
committed
add a sanitizer that checks that the string does not start with "--"
1 parent b9a7f6a commit ea2b73b

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

go/ql/lib/semmle/go/security/CommandInjectionCustomizations.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,21 @@ module CommandInjection {
5252
* A call to a regexp match function, considered as a barrier guard for command injection.
5353
*/
5454
class RegexpCheckBarrierAsSanitizer extends Sanitizer instanceof RegexpCheckBarrier { }
55+
56+
private predicate noDoubleDashPrefixCheck(DataFlow::Node hasPrefixNode, Expr e, boolean branch) {
57+
exists(StringOps::HasPrefix hasPrefix | hasPrefix = hasPrefixNode |
58+
e = hasPrefix.getBaseString().asExpr() and
59+
hasPrefix.getSubstring().asExpr().getStringValue() = "--" and
60+
branch = false
61+
)
62+
}
63+
64+
/**
65+
* A call that confirms that the string does not start with `--`, considered as a barrier guard for command injection.
66+
*/
67+
class NoDoubleDashPrefixSanitizer extends Sanitizer {
68+
NoDoubleDashPrefixSanitizer() {
69+
this = DataFlow::BarrierGuard<noDoubleDashPrefixCheck/3>::getABarrierNode()
70+
}
71+
}
5572
}

go/ql/test/query-tests/Security/CWE-078/CommandInjection.expected

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ edges
1414
| GitSubcommands.go:10:13:10:27 | call to Query | GitSubcommands.go:14:30:14:36 | tainted | provenance | |
1515
| GitSubcommands.go:10:13:10:27 | call to Query | GitSubcommands.go:15:35:15:41 | tainted | provenance | |
1616
| GitSubcommands.go:10:13:10:27 | call to Query | GitSubcommands.go:16:36:16:42 | tainted | provenance | |
17+
| GitSubcommands.go:32:13:32:19 | selection of URL | GitSubcommands.go:32:13:32:27 | call to Query | provenance | MaD:735 |
18+
| GitSubcommands.go:32:13:32:27 | call to Query | GitSubcommands.go:37:32:37:38 | tainted | provenance | |
1719
| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:9:13:9:27 | call to Query | provenance | MaD:735 |
1820
| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:13:25:13:31 | tainted | provenance | |
1921
| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | |
@@ -123,6 +125,9 @@ nodes
123125
| GitSubcommands.go:14:30:14:36 | tainted | semmle.label | tainted |
124126
| GitSubcommands.go:15:35:15:41 | tainted | semmle.label | tainted |
125127
| GitSubcommands.go:16:36:16:42 | tainted | semmle.label | tainted |
128+
| GitSubcommands.go:32:13:32:19 | selection of URL | semmle.label | selection of URL |
129+
| GitSubcommands.go:32:13:32:27 | call to Query | semmle.label | call to Query |
130+
| GitSubcommands.go:37:32:37:38 | tainted | semmle.label | tainted |
126131
| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | semmle.label | selection of URL |
127132
| SanitizingDoubleDash.go:9:13:9:27 | call to Query | semmle.label | call to Query |
128133
| SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | semmle.label | array literal [array] |
@@ -212,6 +217,7 @@ subpaths
212217
| GitSubcommands.go:14:30:14:36 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:14:30:14:36 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value |
213218
| GitSubcommands.go:15:35:15:41 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:15:35:15:41 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value |
214219
| GitSubcommands.go:16:36:16:42 | tainted | GitSubcommands.go:10:13:10:19 | selection of URL | GitSubcommands.go:16:36:16:42 | tainted | This command depends on a $@. | GitSubcommands.go:10:13:10:19 | selection of URL | user-provided value |
220+
| GitSubcommands.go:37:32:37:38 | tainted | GitSubcommands.go:32:13:32:19 | selection of URL | GitSubcommands.go:37:32:37:38 | tainted | This command depends on a $@. | GitSubcommands.go:32:13:32:19 | selection of URL | user-provided value |
215221
| SanitizingDoubleDash.go:14:23:14:33 | slice expression | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:14:23:14:33 | slice expression | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value |
216222
| SanitizingDoubleDash.go:40:23:40:30 | arrayLit | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value |
217223
| SanitizingDoubleDash.go:54:23:54:30 | arrayLit | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:54:23:54:30 | arrayLit | This command depends on a $@. | SanitizingDoubleDash.go:9:13:9:19 | selection of URL | user-provided value |

go/ql/test/query-tests/Security/CWE-078/GitSubcommands.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package main
2-
32
import (
43
"net/http"
54
"os/exec"
5+
"strings"
66
)
77

88
// BAD: using git subcommands that are vulnerable to arbitrary remote command execution
@@ -26,3 +26,14 @@ func gitSubcommandsGood(req *http.Request) {
2626
exec.Command("git", "merge", tainted)
2727
exec.Command("git", "add", tainted)
2828
}
29+
30+
// BAD: using git subcommands that are vulnerable to arbitrary remote command execution
31+
func gitSubcommandsGood2(req *http.Request) {
32+
tainted := req.URL.Query()["cmd"][0]
33+
34+
if !strings.HasPrefix(tainted, "--") {
35+
exec.Command("git", "clone", tainted) // GOOD, `tainted` cannot start with "--"
36+
} else {
37+
exec.Command("git", "clone", tainted) // BAD, `tainted` can start with "--"
38+
}
39+
}

0 commit comments

Comments
 (0)