Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions ql/lib/semmle/go/security/TaintedPathCustomizations.qll
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ module TaintedPath {
}
}

/**
* A call to `filepath.Clean("/" + e)`, considered to sanitize `e` against path traversal.
*/
class FilepathCleanSanitizer extends Sanitizer {
FilepathCleanSanitizer() {
exists(DataFlow::CallNode cleanCall, StringOps::Concatenation concatNode |
cleanCall = any(Function f | f.hasQualifiedName("path/filepath", "Clean")).getACall() and
concatNode = cleanCall.getArgument(0) and
concatNode.getOperand(0).asExpr().(StringLit).getValue() = "/" and
this = cleanCall.getResult()
)
}
}

/**
* A check of the form `!strings.Contains(nd, "..")`, considered as a sanitizer guard for
* path traversal.
Expand Down
5 changes: 5 additions & 0 deletions ql/test/query-tests/Security/CWE-022/TaintedPath.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,9 @@ func handler(w http.ResponseWriter, r *http.Request) {
data, _ = ioutil.ReadFile(filepath.Join("/home/user/", path))
w.Write(data)
}

// GOOD: Sanitized by filepath.Clean with a prepended '/' forcing interpretation
// as an absolute path, so that Clean will throw away any leading `..` components.
data, _ = ioutil.ReadFile(filepath.Clean("/" + path))
w.Write(data)
}