-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into workflow/coverage/update
- Loading branch information
Showing
14 changed files
with
676 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
category: minorAnalysis | ||
--- | ||
* The query `go/sql-injection` now recognizes more sinks in the package `github.com/Masterminds/squirrel`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd"> | ||
|
||
<qhelp> | ||
<overview> | ||
<p>Using untrusted input to created with the built-in make function | ||
could lead to excessive memory allocation and potentially cause the program to crash due | ||
to running out of memory. This vulnerability could be exploited to perform a DoS attack by consuming all available server resources.</p> | ||
</overview> | ||
|
||
<recommendation> | ||
<p>Implement a maximum allowed value for creates a slice with the built-in make function to prevent excessively large allocations. | ||
For instance, you could restrict it to a reasonable upper limit.</p> | ||
</recommendation> | ||
|
||
<example> | ||
<p>In the following example snippet, the <code>n</code> field is user-controlled.</p> | ||
<p> The server trusts that n has an acceptable value, however when using a maliciously large value, | ||
it allocates a slice of <code>n</code> of strings before filling the slice with data.</p> | ||
|
||
<sample src="DenialOfServiceBad.go" /> | ||
|
||
<p>One way to prevent this vulnerability is by implementing a maximum allowed value for the user-controlled input:</p> | ||
|
||
<sample src="DenialOfServiceGood.go" /> | ||
</example> | ||
|
||
<references> | ||
<li> | ||
OWASP: <a href="https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html">Denial of Service Cheat Sheet</a> | ||
</li> | ||
</references> | ||
</qhelp> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/** | ||
* @name Denial Of Service | ||
* @description slices created with the built-in make function from user-controlled sources using a | ||
* maliciously large value possibly leading to a denial of service. | ||
* @kind path-problem | ||
* @problem.severity error | ||
* @security-severity 9 | ||
* @precision high | ||
* @id go/denial-of-service | ||
* @tags security | ||
* experimental | ||
* external/cwe/cwe-770 | ||
*/ | ||
|
||
import go | ||
|
||
/** | ||
* Holds if the guard `g` on its branch `branch` checks that `e` is not constant and is less than some other value. | ||
*/ | ||
predicate denialOfServiceSanitizerGuard(DataFlow::Node g, Expr e, boolean branch) { | ||
exists(DataFlow::Node lesser | | ||
e = lesser.asExpr() and | ||
g.(DataFlow::RelationalComparisonNode).leq(branch, lesser, _, _) and | ||
not e.isConst() | ||
) | ||
} | ||
|
||
/** | ||
* Module for defining predicates and tracking taint flow related to denial of service issues. | ||
*/ | ||
module Config implements DataFlow::ConfigSig { | ||
predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource } | ||
|
||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { | ||
exists(Function f, DataFlow::CallNode cn | cn = f.getACall() | | ||
f.hasQualifiedName("strconv", ["Atoi", "ParseInt", "ParseUint", "ParseFloat"]) and | ||
node1 = cn.getArgument(0) and | ||
node2 = cn.getResult(0) | ||
) | ||
} | ||
|
||
predicate isBarrier(DataFlow::Node node) { | ||
node = DataFlow::BarrierGuard<denialOfServiceSanitizerGuard/3>::getABarrierNode() | ||
} | ||
|
||
predicate isSink(DataFlow::Node sink) { sink = Builtin::make().getACall().getArgument(0) } | ||
} | ||
|
||
/** | ||
* Tracks taint flow for reasoning about denial of service, where source is | ||
* user-controlled and unchecked. | ||
*/ | ||
module Flow = TaintTracking::Global<Config>; | ||
|
||
import Flow::PathGraph | ||
|
||
from Flow::PathNode source, Flow::PathNode sink | ||
where Flow::flowPath(source, sink) | ||
select sink, source, sink, "This variable might be leading to denial of service." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"strconv" | ||
) | ||
|
||
func OutOfMemoryBad(w http.ResponseWriter, r *http.Request) { | ||
query := r.URL.Query() | ||
|
||
queryStr := query.Get("n") | ||
collectionSize, err := strconv.Atoi(queryStr) | ||
if err != nil { | ||
http.Error(w, err.Error(), http.StatusBadRequest) | ||
return | ||
} | ||
|
||
result := make([]string, collectionSize) | ||
for i := 0; i < collectionSize; i++ { | ||
result[i] = fmt.Sprintf("Item %d", i+1) | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"strconv" | ||
) | ||
|
||
func OutOfMemoryGood(w http.ResponseWriter, r *http.Request) { | ||
query := r.URL.Query() | ||
MaxValue := 6 | ||
queryStr := query.Get("n") | ||
collectionSize, err := strconv.Atoi(queryStr) | ||
if err != nil { | ||
http.Error(w, err.Error(), http.StatusBadRequest) | ||
return | ||
} | ||
if collectionSize < 0 || collectionSize > MaxValue { | ||
http.Error(w, "Bad request", http.StatusBadRequest) | ||
return | ||
} | ||
result := make([]string, collectionSize) | ||
for i := 0; i < collectionSize; i++ { | ||
result[i] = fmt.Sprintf("Item %d", i+1) | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
edges | ||
| DenialOfServiceBad.go:11:12:11:16 | selection of URL | DenialOfServiceBad.go:11:12:11:24 | call to Query | provenance | | | ||
| DenialOfServiceBad.go:11:12:11:24 | call to Query | DenialOfServiceBad.go:13:15:13:20 | source | provenance | | | ||
| DenialOfServiceBad.go:13:15:13:20 | source | DenialOfServiceBad.go:13:15:13:29 | call to Get | provenance | | | ||
| DenialOfServiceBad.go:13:15:13:29 | call to Get | DenialOfServiceBad.go:14:28:14:36 | sourceStr | provenance | | | ||
| DenialOfServiceBad.go:14:2:14:37 | ... := ...[0] | DenialOfServiceBad.go:20:27:20:30 | sink | provenance | | | ||
| DenialOfServiceBad.go:14:28:14:36 | sourceStr | DenialOfServiceBad.go:14:2:14:37 | ... := ...[0] | provenance | | | ||
nodes | ||
| DenialOfServiceBad.go:11:12:11:16 | selection of URL | semmle.label | selection of URL | | ||
| DenialOfServiceBad.go:11:12:11:24 | call to Query | semmle.label | call to Query | | ||
| DenialOfServiceBad.go:13:15:13:20 | source | semmle.label | source | | ||
| DenialOfServiceBad.go:13:15:13:29 | call to Get | semmle.label | call to Get | | ||
| DenialOfServiceBad.go:14:2:14:37 | ... := ...[0] | semmle.label | ... := ...[0] | | ||
| DenialOfServiceBad.go:14:28:14:36 | sourceStr | semmle.label | sourceStr | | ||
| DenialOfServiceBad.go:20:27:20:30 | sink | semmle.label | sink | | ||
subpaths | ||
#select | ||
| DenialOfServiceBad.go:20:27:20:30 | sink | DenialOfServiceBad.go:11:12:11:16 | selection of URL | DenialOfServiceBad.go:20:27:20:30 | sink | This variable might be leading to denial of service. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
experimental/CWE-770/DenialOfService.ql |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"strconv" | ||
) | ||
|
||
func OutOfMemoryBad(w http.ResponseWriter, r *http.Request) { | ||
source := r.URL.Query() | ||
|
||
sourceStr := source.Get("n") | ||
sink, err := strconv.Atoi(sourceStr) | ||
if err != nil { | ||
http.Error(w, err.Error(), http.StatusBadRequest) | ||
return | ||
} | ||
|
||
result := make([]string, sink) | ||
for i := 0; i < sink; i++ { | ||
result[i] = fmt.Sprintf("Item %d", i+1) | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"strconv" | ||
) | ||
|
||
func OutOfMemoryGood1(w http.ResponseWriter, r *http.Request) { | ||
source := r.URL.Query() | ||
MaxValue := 6 | ||
sourceStr := source.Get("n") | ||
sink, err := strconv.Atoi(sourceStr) | ||
if err != nil || sink < 0 { | ||
http.Error(w, "Bad request", http.StatusBadRequest) | ||
return | ||
} | ||
if sink > MaxValue { | ||
return | ||
} | ||
result := make([]string, sink) | ||
for i := 0; i < sink; i++ { | ||
result[i] = fmt.Sprintf("Item %d", i+1) | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(result) | ||
} | ||
|
||
func OutOfMemoryGood2(w http.ResponseWriter, r *http.Request) { | ||
source := r.URL.Query() | ||
MaxValue := 6 | ||
sourceStr := source.Get("n") | ||
sink, err := strconv.Atoi(sourceStr) | ||
if err != nil || sink < 0 { | ||
http.Error(w, "Bad request", http.StatusBadRequest) | ||
return | ||
} | ||
if sink <= MaxValue { | ||
result := make([]string, sink) | ||
for i := 0; i < sink; i++ { | ||
result[i] = fmt.Sprintf("Item %d", i+1) | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(result) | ||
} | ||
} | ||
|
||
func OutOfMemoryGood3(w http.ResponseWriter, r *http.Request) { | ||
source := r.URL.Query() | ||
MaxValue := 6 | ||
sourceStr := source.Get("n") | ||
sink, err := strconv.Atoi(sourceStr) | ||
if err != nil || sink < 0 { | ||
http.Error(w, "Bad request", http.StatusBadRequest) | ||
return | ||
} | ||
if sink > MaxValue { | ||
sink = MaxValue | ||
result := make([]string, sink) | ||
for i := 0; i < sink; i++ { | ||
result[i] = fmt.Sprintf("Item %d", i+1) | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(result) | ||
} | ||
} | ||
|
||
func OutOfMemoryGood4(w http.ResponseWriter, r *http.Request) { | ||
source := r.URL.Query() | ||
MaxValue := 6 | ||
sourceStr := source.Get("n") | ||
sink, err := strconv.Atoi(sourceStr) | ||
if err != nil || sink < 0 { | ||
http.Error(w, "Bad request", http.StatusBadRequest) | ||
return | ||
} | ||
if sink > MaxValue { | ||
sink = MaxValue | ||
} else { | ||
tmp := sink | ||
sink = tmp | ||
} | ||
result := make([]string, sink) | ||
for i := 0; i < sink; i++ { | ||
result[i] = fmt.Sprintf("Item %d", i+1) | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
json.NewEncoder(w).Encode(result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.