Merge branch 'main' into sourcesinkdoc

This commit is contained in:
Geoffrey White
2025-03-12 16:04:56 +00:00
1547 changed files with 23117 additions and 13831 deletions

View File

@@ -8,5 +8,6 @@ paths-ignore:
- '/java/'
- '/python/'
- '/javascript/ql/test'
- '/javascript/ql/integration-tests'
- '/javascript/extractor/tests'
- '/rust/ql'

View File

@@ -18,6 +18,10 @@ on:
jobs:
CodeQL-Build:
strategy:
fail-fast: false
matrix:
language: ['actions', 'csharp']
runs-on: ubuntu-latest
@@ -38,9 +42,8 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@main
# Override language selection by uncommenting this and choosing your languages
with:
languages: csharp
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).

View File

@@ -43,7 +43,7 @@ jobs:
The following example, correctly creates a temporary directory and extracts the contents of the artifact there before calling `cmd.sh`.
```yaml
name: Insecure Workflow
name: Secure Workflow
on:
workflow_run:

View File

@@ -43,7 +43,7 @@ jobs:
The following example, correctly creates a temporary directory and extracts the contents of the artifact there before calling `cmd.sh`.
```yaml
name: Insecure Workflow
name: Secure Workflow
on:
workflow_run:

View File

@@ -8,3 +8,4 @@ extractor: actions
defaultSuiteFile: codeql-suites/actions-code-scanning.qls
dependencies:
codeql/actions-all: ${workspace}
codeql/suite-helpers: ${workspace}

View File

@@ -16,6 +16,7 @@
import csharp
import Dispose
import semmle.code.csharp.frameworks.System
import semmle.code.csharp.frameworks.system.threading.Tasks
import semmle.code.csharp.commons.Disposal
private class ReturnNode extends DataFlow::ExprNode {
@@ -24,15 +25,27 @@ private class ReturnNode extends DataFlow::ExprNode {
}
}
private class Task extends Type {
Task() {
this instanceof SystemThreadingTasksTaskClass or
this instanceof SystemThreadingTasksTaskTClass
}
}
module DisposeCallOnLocalIDisposableConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
node.asExpr() =
any(LocalScopeDisposableCreation disposable |
// Only care about library types - user types often have spurious IDisposable declarations
disposable.getType().fromLibrary() and
// WebControls are usually disposed automatically
not disposable.getType() instanceof WebControl
)
exists(LocalScopeDisposableCreation disposable, Type t |
node.asExpr() = disposable and
t = disposable.getType()
|
// Only care about library types - user types often have spurious IDisposable declarations
t.fromLibrary() and
// WebControls are usually disposed automatically
not t instanceof WebControl and
// It is typically not nessesary to dispose tasks
// https://devblogs.microsoft.com/pfxteam/do-i-need-to-dispose-of-tasks/
not t instanceof Task
)
}
predicate isSink(DataFlow::Node node) {

View File

@@ -119,9 +119,14 @@ class ConstantMatchingCondition extends ConstantCondition {
}
override predicate isWhiteListed() {
exists(SwitchExpr se, int i |
se.getCase(i).getPattern() = this.(DiscardExpr) and
exists(Switch se, Case c, int i |
c = se.getCase(i) and
c.getPattern() = this.(DiscardExpr)
|
i > 0
or
i = 0 and
exists(Expr cond | c.getCondition() = cond and not isConstantCondition(cond, true))
)
or
this = any(PositionalPatternExpr ppe).getPattern(_)

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `cs/local-not-disposed` query no longer flags un-disposed tasks as this is often not needed (explained [here](https://devblogs.microsoft.com/pfxteam/do-i-need-to-dispose-of-tasks/)).

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Increase query precision for `cs/constant-condition` and allow the use of discards in switch/case statements and also take the condition (if any) into account.

View File

@@ -8,3 +8,4 @@
- cs/self-assignment
- cs/inefficient-containskey
- cs/call-to-object-tostring
- cs/local-not-disposed

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.IO.Compression;
using System.Xml;
using System.Threading;
using System.Threading.Tasks;
class Test
{
@@ -86,6 +87,13 @@ class Test
using (XmlReader.Create(source ?? new StringReader("xml"), null))
;
// GOOD: Flagging these generates too much noise and there is a general
// acceptance that Tasks are not disposed.
// https://devblogs.microsoft.com/pfxteam/do-i-need-to-dispose-of-tasks/
Task t = new Task(() => { });
t.Start();
t.Wait();
return null;
}

View File

@@ -1,7 +1,7 @@
| NoDisposeCallOnLocalIDisposable.cs:50:19:50:38 | object creation of type Timer | Disposable 'Timer' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:51:18:51:73 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:52:9:52:64 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:74:25:74:71 | call to method Create | Disposable 'XmlReader' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:74:42:74:64 | object creation of type StringReader | Disposable 'StringReader' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:79:38:79:67 | object creation of type StreamWriter | Disposable 'StreamWriter' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:51:19:51:38 | object creation of type Timer | Disposable 'Timer' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:52:18:52:73 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:53:9:53:64 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:75:25:75:71 | call to method Create | Disposable 'XmlReader' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:75:42:75:64 | object creation of type StringReader | Disposable 'StringReader' is created but not disposed. |
| NoDisposeCallOnLocalIDisposable.cs:80:38:80:67 | object creation of type StreamWriter | Disposable 'StreamWriter' is created but not disposed. |
| NoDisposeCallOnLocalIDisposableBad.cs:8:22:8:56 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |

View File

@@ -35,18 +35,18 @@ class ConstantNullness
{
void M1(int i)
{
var j = ((string)null)?.Length; // BAD
var s = ((int?)i)?.ToString(); // BAD
var j = ((string)null)?.Length; // $ Alert
var s = ((int?)i)?.ToString(); // $ Alert
var k = s?.Length; // GOOD
k = s?.ToLower()?.Length; // GOOD
}
void M2(int i)
{
var j = (int?)null ?? 0; // BAD
var s = "" ?? "a"; // BAD
j = (int?)i ?? 1; // BAD
s = ""?.CommaJoinWith(s); // BAD
var j = (int?)null ?? 0; // $ Alert
var s = "" ?? "a"; // $ Alert
j = (int?)i ?? 1; // $ Alert
s = ""?.CommaJoinWith(s); // $ Alert
s = s ?? ""; // GOOD
s = (i == 0 ? s : null) ?? s; // GOOD
var k = (i == 0 ? s : null)?.Length; // GOOD
@@ -59,9 +59,9 @@ class ConstantMatching
{
switch (1 + 2)
{
case 2: // BAD
case 2: // $ Alert
break;
case 3: // BAD
case 3: // $ Alert
break;
case int _: // GOOD
break;
@@ -72,7 +72,7 @@ class ConstantMatching
{
switch ((object)s)
{
case int _: // BAD
case int _: // $ Alert
break;
case "": // GOOD
break;
@@ -92,7 +92,7 @@ class ConstantMatching
{
return o switch
{
_ => o.ToString() // BAD
_ => o.ToString() // $ Alert
};
}
@@ -111,7 +111,7 @@ class ConstantMatching
return;
if (!b2)
return;
if (b1 && b2) // BAD
if (b1 && b2) // $ Alert
return;
}
@@ -124,6 +124,35 @@ class ConstantMatching
_ => "" // GOOD
};
}
string M8(int i)
{
return i switch
{
_ when i % 2 == 0 => "even", // GOOD
_ => "odd" // GOOD
};
}
string M9(int i)
{
switch (i)
{
case var _: // $ Alert
return "even";
}
}
string M10(int i)
{
switch (i)
{
case var _ when i % 2 == 0: // GOOD
return "even";
case var _: // GOOD
return "odd";
}
}
}
class Assertions

View File

@@ -10,7 +10,7 @@
| ConstantCondition.cs:95:13:95:13 | _ | Pattern always matches. |
| ConstantCondition.cs:114:13:114:14 | access to parameter b1 | Condition always evaluates to 'true'. |
| ConstantCondition.cs:114:19:114:20 | access to parameter b2 | Condition always evaluates to 'true'. |
| ConstantConditionBad.cs:5:16:5:20 | ... > ... | Condition always evaluates to 'false'. |
| ConstantCondition.cs:141:22:141:22 | _ | Pattern always matches. |
| ConstantConditionalExpressionCondition.cs:11:22:11:34 | ... == ... | Condition always evaluates to 'true'. |
| ConstantConditionalExpressionCondition.cs:12:21:12:25 | false | Condition always evaluates to 'false'. |
| ConstantConditionalExpressionCondition.cs:13:21:13:30 | ... == ... | Condition always evaluates to 'true'. |
@@ -19,6 +19,7 @@
| ConstantIfCondition.cs:11:17:11:29 | ... == ... | Condition always evaluates to 'true'. |
| ConstantIfCondition.cs:14:17:14:21 | false | Condition always evaluates to 'false'. |
| ConstantIfCondition.cs:17:17:17:26 | ... == ... | Condition always evaluates to 'true'. |
| ConstantIfCondition.cs:30:20:30:24 | ... > ... | Condition always evaluates to 'false'. |
| ConstantIsNullOrEmpty.cs:10:21:10:54 | call to method IsNullOrEmpty | Condition always evaluates to 'false'. |
| ConstantIsNullOrEmpty.cs:46:21:46:46 | call to method IsNullOrEmpty | Condition always evaluates to 'true'. |
| ConstantIsNullOrEmpty.cs:50:21:50:44 | call to method IsNullOrEmpty | Condition always evaluates to 'true'. |

View File

@@ -1 +1,2 @@
Bad Practices/Control-Flow/ConstantCondition.ql
query: Bad Practices/Control-Flow/ConstantCondition.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,7 +0,0 @@
class Bad
{
public int Max(int a, int b)
{
return a > a ? a : b;
}
}

View File

@@ -8,10 +8,10 @@ namespace ConstantConditionalExpression
public void Foo()
{
int i = (ZERO == 1 - 1) ? 0 : 1; // BAD
int j = false ? 0 : 1; // BAD
int k = " " == " " ? 0 : 1; // BAD
int l = (" "[0] == ' ') ? 0 : 1; // BAD: but not flagged
int i = (ZERO == 1 - 1) ? 0 : 1; // $ Alert
int j = false ? 0 : 1; // $ Alert
int k = " " == " " ? 0 : 1; // $ Alert
int l = (" "[0] == ' ') ? 0 : 1; // Missing Alert
int m = Bar() == 0 ? 0 : 1; // GOOD
}
@@ -21,5 +21,4 @@ namespace ConstantConditionalExpression
}
}
}

View File

@@ -6,9 +6,9 @@ namespace ConstantForCondition
{
public void M()
{
for (int i = 0; false; i++) // GOOD
for (int i = 0; false; i++) // $ Alert
;
for (int i = 0; 0 == 1; i++) // BAD
for (int i = 0; 0 == 1; i++) // $ Alert
;
for (; ; ) // GOOD
;

View File

@@ -8,23 +8,28 @@ namespace ConstantIfCondition
public void Foo()
{
if (ZERO == 1 - 1)
{ // BAD
if (ZERO == 1 - 1) // $ Alert
{
}
if (false)
{ // BAD
if (false) // $ Alert
{
}
if (" " == " ")
{ // BAD
if (" " == " ") // $ Alert
{
}
if (" "[0] == ' ')
{ // BAD: but not flagged
if (" "[0] == ' ') // Missing Alert
{
}
if (Bar() == 0)
{ // GOOD
if (Bar() == 0) // GOOD
{
}
}
public int Max(int a, int b)
{
return a > a ? a : b; // $ Alert
}
public int Bar()
{
return ZERO;

View File

@@ -7,17 +7,17 @@ namespace ConstantIsNullOrEmpty
static void Main(string[] args)
{
{
if (string.IsNullOrEmpty(nameof(args))) // bad: always false
if (string.IsNullOrEmpty(nameof(args))) // $ Alert
{
}
string? x = null;
if (string.IsNullOrEmpty(x)) // would be nice... bad: always true
if (string.IsNullOrEmpty(x)) // Missing Alert (always true)
{
}
string y = "";
if (string.IsNullOrEmpty(y)) // would be nice... bad: always true
if (string.IsNullOrEmpty(y)) // Missing Alert (always true)
{
}
@@ -28,12 +28,12 @@ namespace ConstantIsNullOrEmpty
}
string z = " ";
if (string.IsNullOrEmpty(z)) // would be nice... bad: always false
if (string.IsNullOrEmpty(z)) // Missing Alert (always false)
{
}
string a = "a";
if (string.IsNullOrEmpty(a)) // would be nice... bad: always false
if (string.IsNullOrEmpty(a)) // Missing Alert (always false)
{
}
@@ -43,18 +43,18 @@ namespace ConstantIsNullOrEmpty
{
}
if (string.IsNullOrEmpty(null)) // bad: always true
if (string.IsNullOrEmpty(null)) // $ Alert
{
}
if (string.IsNullOrEmpty("")) // bad: always true
if (string.IsNullOrEmpty("")) // $ Alert
{
}
if (string.IsNullOrEmpty(" ")) // bad: always false
if (string.IsNullOrEmpty(" ")) // $ Alert
{
}
}
}
}
}
}

View File

@@ -8,8 +8,8 @@ namespace ConstantNullCoalescingLeftHandOperand
public void Foo()
{
object i = NULL_OBJECT ?? ""; // BAD
object j = null ?? ""; // BAD
object i = NULL_OBJECT ?? ""; // $ Alert
object j = null ?? ""; // $ Alert
object k = Bar() ?? ""; // GOOD
}

View File

@@ -9,28 +9,28 @@ namespace ConstantWhileCondition
public void Foo()
{
while (ZERO == 1 - 1)
{ // BAD
while (ZERO == 1 - 1) // $ Alert
{
break;
}
while (false)
{ // GOOD
while (false) // $ Alert
{
break;
}
while (true)
{ // GOOD
while (true) // GOOD
{
break;
}
while (" " == " ")
{ // BAD
while (" " == " ") // $ Alert
{
break;
}
while (" "[0] == ' ')
{ // BAD: but not flagged
while (" "[0] == ' ') // Missing Alert
{
break;
}
while (Bar() == 0)
{ // GOOD
while (Bar() == 0) // GOOD
{
break;
}
}

View File

@@ -97,6 +97,7 @@ predicate isCloseSink(DataFlow::Node sink, DataFlow::CallNode closeCall) {
// where the function is called on the sink
closeCall.getReceiver() = sink and
// and check that it is not dominated by a call to `os.File.Sync`.
// TODO: fix this logic when `closeCall` is in a defer statement.
not exists(IR::Instruction syncInstr, DataFlow::Node syncReceiver, DataFlow::CallNode syncCall |
// match the instruction corresponding to an `os.File.Sync` call with the predecessor
syncCall.asInstruction() = syncInstr and

View File

@@ -1,48 +1,52 @@
#select
| tests.go:9:8:9:8 | f | tests.go:31:5:31:78 | ... := ...[0] | tests.go:9:8:9:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:31:15:31:78 | call to OpenFile | call to OpenFile |
| tests.go:9:8:9:8 | f | tests.go:45:5:45:76 | ... := ...[0] | tests.go:9:8:9:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:45:15:45:76 | call to OpenFile | call to OpenFile |
| tests.go:14:3:14:3 | f | tests.go:31:5:31:78 | ... := ...[0] | tests.go:14:3:14:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:31:15:31:78 | call to OpenFile | call to OpenFile |
| tests.go:14:3:14:3 | f | tests.go:45:5:45:76 | ... := ...[0] | tests.go:14:3:14:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:45:15:45:76 | call to OpenFile | call to OpenFile |
| tests.go:56:3:56:3 | f | tests.go:54:5:54:78 | ... := ...[0] | tests.go:56:3:56:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:54:15:54:78 | call to OpenFile | call to OpenFile |
| tests.go:68:3:68:3 | f | tests.go:66:5:66:76 | ... := ...[0] | tests.go:68:3:68:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:66:15:66:76 | call to OpenFile | call to OpenFile |
| tests.go:110:9:110:9 | f | tests.go:108:5:108:78 | ... := ...[0] | tests.go:110:9:110:9 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:108:15:108:78 | call to OpenFile | call to OpenFile |
| tests.go:129:3:129:3 | f | tests.go:125:5:125:78 | ... := ...[0] | tests.go:129:3:129:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:125:15:125:78 | call to OpenFile | call to OpenFile |
| tests.go:10:8:10:8 | f | tests.go:32:5:32:78 | ... := ...[0] | tests.go:10:8:10:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:32:15:32:78 | call to OpenFile | call to OpenFile |
| tests.go:10:8:10:8 | f | tests.go:46:5:46:76 | ... := ...[0] | tests.go:10:8:10:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:46:15:46:76 | call to OpenFile | call to OpenFile |
| tests.go:15:3:15:3 | f | tests.go:32:5:32:78 | ... := ...[0] | tests.go:15:3:15:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:32:15:32:78 | call to OpenFile | call to OpenFile |
| tests.go:15:3:15:3 | f | tests.go:46:5:46:76 | ... := ...[0] | tests.go:15:3:15:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:46:15:46:76 | call to OpenFile | call to OpenFile |
| tests.go:57:3:57:3 | f | tests.go:55:5:55:78 | ... := ...[0] | tests.go:57:3:57:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:55:15:55:78 | call to OpenFile | call to OpenFile |
| tests.go:69:3:69:3 | f | tests.go:67:5:67:76 | ... := ...[0] | tests.go:69:3:69:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:67:15:67:76 | call to OpenFile | call to OpenFile |
| tests.go:111:9:111:9 | f | tests.go:109:5:109:78 | ... := ...[0] | tests.go:111:9:111:9 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:109:15:109:78 | call to OpenFile | call to OpenFile |
| tests.go:130:3:130:3 | f | tests.go:126:5:126:78 | ... := ...[0] | tests.go:130:3:130:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:126:15:126:78 | call to OpenFile | call to OpenFile |
| tests.go:151:8:151:8 | f | tests.go:147:2:147:74 | ... := ...[0] | tests.go:151:8:151:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:147:12:147:74 | call to OpenFile | call to OpenFile |
edges
| tests.go:8:24:8:24 | definition of f | tests.go:9:8:9:8 | f | provenance | |
| tests.go:12:32:12:32 | definition of f | tests.go:13:13:15:2 | capture variable f | provenance | |
| tests.go:13:13:15:2 | capture variable f | tests.go:14:3:14:3 | f | provenance | |
| tests.go:31:5:31:78 | ... := ...[0] | tests.go:32:21:32:21 | f | provenance | Src:MaD:1 |
| tests.go:31:5:31:78 | ... := ...[0] | tests.go:33:29:33:29 | f | provenance | Src:MaD:1 |
| tests.go:32:21:32:21 | f | tests.go:8:24:8:24 | definition of f | provenance | |
| tests.go:33:29:33:29 | f | tests.go:12:32:12:32 | definition of f | provenance | |
| tests.go:45:5:45:76 | ... := ...[0] | tests.go:46:21:46:21 | f | provenance | Src:MaD:1 |
| tests.go:45:5:45:76 | ... := ...[0] | tests.go:47:29:47:29 | f | provenance | Src:MaD:1 |
| tests.go:46:21:46:21 | f | tests.go:8:24:8:24 | definition of f | provenance | |
| tests.go:47:29:47:29 | f | tests.go:12:32:12:32 | definition of f | provenance | |
| tests.go:54:5:54:78 | ... := ...[0] | tests.go:56:3:56:3 | f | provenance | Src:MaD:1 |
| tests.go:66:5:66:76 | ... := ...[0] | tests.go:68:3:68:3 | f | provenance | Src:MaD:1 |
| tests.go:108:5:108:78 | ... := ...[0] | tests.go:110:9:110:9 | f | provenance | Src:MaD:1 |
| tests.go:125:5:125:78 | ... := ...[0] | tests.go:129:3:129:3 | f | provenance | Src:MaD:1 |
| tests.go:9:24:9:24 | definition of f | tests.go:10:8:10:8 | f | provenance | |
| tests.go:13:32:13:32 | definition of f | tests.go:14:13:16:2 | capture variable f | provenance | |
| tests.go:14:13:16:2 | capture variable f | tests.go:15:3:15:3 | f | provenance | |
| tests.go:32:5:32:78 | ... := ...[0] | tests.go:33:21:33:21 | f | provenance | Src:MaD:1 |
| tests.go:32:5:32:78 | ... := ...[0] | tests.go:34:29:34:29 | f | provenance | Src:MaD:1 |
| tests.go:33:21:33:21 | f | tests.go:9:24:9:24 | definition of f | provenance | |
| tests.go:34:29:34:29 | f | tests.go:13:32:13:32 | definition of f | provenance | |
| tests.go:46:5:46:76 | ... := ...[0] | tests.go:47:21:47:21 | f | provenance | Src:MaD:1 |
| tests.go:46:5:46:76 | ... := ...[0] | tests.go:48:29:48:29 | f | provenance | Src:MaD:1 |
| tests.go:47:21:47:21 | f | tests.go:9:24:9:24 | definition of f | provenance | |
| tests.go:48:29:48:29 | f | tests.go:13:32:13:32 | definition of f | provenance | |
| tests.go:55:5:55:78 | ... := ...[0] | tests.go:57:3:57:3 | f | provenance | Src:MaD:1 |
| tests.go:67:5:67:76 | ... := ...[0] | tests.go:69:3:69:3 | f | provenance | Src:MaD:1 |
| tests.go:109:5:109:78 | ... := ...[0] | tests.go:111:9:111:9 | f | provenance | Src:MaD:1 |
| tests.go:126:5:126:78 | ... := ...[0] | tests.go:130:3:130:3 | f | provenance | Src:MaD:1 |
| tests.go:147:2:147:74 | ... := ...[0] | tests.go:151:8:151:8 | f | provenance | Src:MaD:1 |
models
| 1 | Source: os; ; false; OpenFile; ; ; ReturnValue[0]; file; manual |
nodes
| tests.go:8:24:8:24 | definition of f | semmle.label | definition of f |
| tests.go:9:8:9:8 | f | semmle.label | f |
| tests.go:12:32:12:32 | definition of f | semmle.label | definition of f |
| tests.go:13:13:15:2 | capture variable f | semmle.label | capture variable f |
| tests.go:14:3:14:3 | f | semmle.label | f |
| tests.go:31:5:31:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:32:21:32:21 | f | semmle.label | f |
| tests.go:33:29:33:29 | f | semmle.label | f |
| tests.go:45:5:45:76 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:46:21:46:21 | f | semmle.label | f |
| tests.go:47:29:47:29 | f | semmle.label | f |
| tests.go:54:5:54:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:56:3:56:3 | f | semmle.label | f |
| tests.go:66:5:66:76 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:68:3:68:3 | f | semmle.label | f |
| tests.go:108:5:108:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:110:9:110:9 | f | semmle.label | f |
| tests.go:125:5:125:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:129:3:129:3 | f | semmle.label | f |
| tests.go:9:24:9:24 | definition of f | semmle.label | definition of f |
| tests.go:10:8:10:8 | f | semmle.label | f |
| tests.go:13:32:13:32 | definition of f | semmle.label | definition of f |
| tests.go:14:13:16:2 | capture variable f | semmle.label | capture variable f |
| tests.go:15:3:15:3 | f | semmle.label | f |
| tests.go:32:5:32:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:33:21:33:21 | f | semmle.label | f |
| tests.go:34:29:34:29 | f | semmle.label | f |
| tests.go:46:5:46:76 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:47:21:47:21 | f | semmle.label | f |
| tests.go:48:29:48:29 | f | semmle.label | f |
| tests.go:55:5:55:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:57:3:57:3 | f | semmle.label | f |
| tests.go:67:5:67:76 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:69:3:69:3 | f | semmle.label | f |
| tests.go:109:5:109:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:111:9:111:9 | f | semmle.label | f |
| tests.go:126:5:126:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:130:3:130:3 | f | semmle.label | f |
| tests.go:147:2:147:74 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:151:8:151:8 | f | semmle.label | f |
subpaths

View File

@@ -1,2 +1,4 @@
query: InconsistentCode/UnhandledCloseWritableHandle.ql
postprocess: utils/test/PrettyPrintModels.ql
postprocess:
- utils/test/PrettyPrintModels.ql
- utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,17 +1,18 @@
package test
import (
"io"
"log"
"os"
)
func closeFileDeferred(f *os.File) {
defer f.Close() // NOT OK, if `f` is writable
defer f.Close() // $ Alert=w Alert=rw
}
func closeFileDeferredIndirect(f *os.File) {
var cont = func() {
f.Close() // NOT OK, if `f` is writable
f.Close() // $ Alert=w Alert=rw
}
defer cont()
@@ -28,7 +29,7 @@ func closeFileDeferredIndirectReturn(f *os.File) {
func deferredCalls() {
// open file for writing
if f, err := os.OpenFile("foo.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err != nil {
if f, err := os.OpenFile("foo.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err != nil { // $ Source=w
closeFileDeferred(f) // NOT OK
closeFileDeferredIndirect(f) // NOT OK
closeFileDeferredIndirectReturn(f) // OK - the error is not discarded at the call to Close (though it is discarded later)
@@ -42,7 +43,7 @@ func deferredCalls() {
}
// open file for reading and writing
if f, err := os.OpenFile("foo.txt", os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0666); err != nil {
if f, err := os.OpenFile("foo.txt", os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0666); err != nil { // $ Source=rw
closeFileDeferred(f) // NOT OK
closeFileDeferredIndirect(f) // NOT OK
closeFileDeferredIndirectReturn(f) // OK - the error is not discarded at the call to Close (though it is discarded later)
@@ -51,9 +52,9 @@ func deferredCalls() {
func notDeferred() {
// open file for writing
if f, err := os.OpenFile("foo.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err != nil {
if f, err := os.OpenFile("foo.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err != nil { // $ Source
// the handle is write-only and we don't check if `Close` succeeds
f.Close() // NOT OK
f.Close() // $ Alert
}
// open file for reading
@@ -63,9 +64,9 @@ func notDeferred() {
}
// open file for reading and writing
if f, err := os.OpenFile("foo.txt", os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0666); err != nil {
if f, err := os.OpenFile("foo.txt", os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0666); err != nil { // $ Source
// the handle is read-write and we don't check if `Close` succeeds
f.Close() // NOT OK
f.Close() // $ Alert
}
}
@@ -105,9 +106,9 @@ func deferredCloseWithSync() {
func deferredCloseWithSyncEarlyReturn(n int) {
// open file for writing
if f, err := os.OpenFile("foo.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err != nil {
if f, err := os.OpenFile("foo.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err != nil { // $ Source
// a call to `Close` is deferred
defer f.Close() // NOT OK
defer f.Close() // $ Alert
if n > 100 {
return
@@ -122,10 +123,36 @@ func deferredCloseWithSyncEarlyReturn(n int) {
func unhandledSync() {
// open file for writing
if f, err := os.OpenFile("foo.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err != nil {
if f, err := os.OpenFile("foo.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666); err != nil { // $ Source
// we have a call to `Sync` which precedes the call to `Close`, but there is no check
// to see if `Sync` may have failed
f.Sync()
f.Close() // NOT OK
f.Close() // $ Alert
}
}
func returnedSync() error {
// open file for writing
f, err := os.OpenFile("foo.txt", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
if err != nil {
// we have a call to `Sync` which precedes the call to `Close`, but there is no check
// to see if `Sync` may have failed
return err
}
defer f.Close()
return f.Sync()
}
func copyFile(destFile string, mode os.FileMode, src io.Reader) error {
f, err := os.OpenFile(destFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode) // $ Source
if err != nil {
return err
}
defer f.Close() // $ SPURIOUS: Alert
_, err = io.Copy(f, src)
if err != nil {
return err
}
return f.Sync()
}

View File

@@ -0,0 +1,6 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf
*.cmd text eol=crlf

View File

@@ -0,0 +1,84 @@
{
"markdownMessage": "Java analysis used build tool Maven to pick a JDK version and/or to recommend external dependencies.",
"severity": "unknown",
"source": {
"extractorName": "java",
"id": "java/autobuilder/buildless/using-build-tool-advice",
"name": "Java analysis used build tool Maven to pick a JDK version and/or to recommend external dependencies"
},
"visibility": {
"cliSummaryTable": true,
"statusPage": false,
"telemetry": true
}
}
{
"markdownMessage": "Java analysis used the system default JDK.",
"severity": "unknown",
"source": {
"extractorName": "java",
"id": "java/autobuilder/buildless/jdk-system-default",
"name": "Java analysis used the system default JDK"
},
"visibility": {
"cliSummaryTable": true,
"statusPage": false,
"telemetry": true
}
}
{
"markdownMessage": "Java analysis with build-mode 'none' completed.",
"severity": "unknown",
"source": {
"extractorName": "java",
"id": "java/autobuilder/buildless/complete",
"name": "Java analysis with build-mode 'none' completed"
},
"visibility": {
"cliSummaryTable": true,
"statusPage": false,
"telemetry": true
}
}
{
"markdownMessage": "Java was extracted with build-mode set to 'none'. This means that all Java source in the working directory will be scanned, with build tools such as Maven and Gradle only contributing information about external dependencies.",
"severity": "note",
"source": {
"extractorName": "java",
"id": "java/autobuilder/buildless/mode-active",
"name": "Java was extracted with build-mode set to 'none'"
},
"visibility": {
"cliSummaryTable": true,
"statusPage": true,
"telemetry": true
}
}
{
"markdownMessage": "Reading the dependency graph from build files provided 2 classpath entries",
"severity": "unknown",
"source": {
"extractorName": "java",
"id": "java/autobuilder/buildless/depgraph-provided-by-maven",
"name": "Java analysis extracted precise dependency graph information from tool Maven"
},
"visibility": {
"cliSummaryTable": true,
"statusPage": false,
"telemetry": true
}
}
{
"markdownMessage": "The maven-enforcer-plugin recommended a specific Maven version be used. Trying to download it failed; extraction will continue, but retrieving dependency information from Maven may fail if the system default version is incompatible with project build scripts. Consider checking if a firewall configuration or similar is preventing downloading the required version.",
"severity": "note",
"source": {
"extractorName": "java",
"id": "java/autobuilder/buildless/maven-download-failed",
"name": "Java analysis failed to download a Maven version recommended by the maven-enforcer-plugin"
},
"visibility": {
"cliSummaryTable": true,
"statusPage": true,
"telemetry": true
}
}

View File

@@ -0,0 +1,10 @@
#!/bin/bash
>&2 echo "Running mvn wrapper script"
if [ "$1" == "dependency:copy" ]; then
>&2 echo "Arguments ($@) look like a dependency:copy command; failing"
exit 1
fi
${REAL_MVN_PATH} "$@"

View File

@@ -0,0 +1 @@
@bash mvn %*

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>maven-sample</artifactId>
<version>1.0-SNAPSHOT</version>
<name>maven-sample</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>1.1.1</version>
<executions>
<execution>
<id>check-maven-version</id>
<phase>package</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.example.App</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>2.19.1</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
<configuration>
<java>
<licenseHeader>
<content>/* FAIL ME */</content>
</licenseHeader>
</java>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-maven</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>[3.1.1,)</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -0,0 +1,7 @@
pom.xml
src/main/java/com/example/App.java
src/main/resources/my-app.properties
src/main/resources/page.xml
src/main/resources/struts.xml
src/test/java/com/example/AppTest.java
test-db/working/settings.xml

View File

@@ -0,0 +1,30 @@
package com.example;
import java.util.regex.Pattern;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
String expectedVersion = System.getenv("EXPECT_MAVEN");
Path mavenHome = Paths.get(System.getProperty("maven.home")).normalize();
String observedVersion = mavenHome.getFileName().toString();
if (expectedVersion != null && !expectedVersion.equals(observedVersion)) {
System.err.println("Wrong maven version, expected '" + expectedVersion + "' but got '" + observedVersion + "'" + mavenHome);
System.exit(1);
}
String commandMatcher = System.getenv("EXPECT_COMMAND_REGEX");
String command = System.getProperty("sun.java.command");
if (commandMatcher != null && !Pattern.matches(commandMatcher, command)) {
System.err.println("Wrong command line, '" + command + "' does not match '" + commandMatcher + "'");
System.exit(1);
}
}
}

View File

@@ -0,0 +1,8 @@
<html>
<head>
<title>A sample</title>
</head>
<body>
<p>Hello world!</p>
</body>
</html>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<struts>
This is a sample file
</struts>

View File

@@ -0,0 +1,20 @@
package com.example;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
/**
* Unit test for simple App.
*/
public class AppTest
{
/**
* Rigorous Test :-)
*/
@Test
public void shouldAnswerWithTrue()
{
assertTrue( true );
}
}

View File

@@ -0,0 +1,14 @@
import os
import os.path
import shutil
def test(codeql, java, check_diagnostics):
# Avoid shutil resolving mvn to the wrapper script in the test dir:
os.environ["NoDefaultCurrentDirectoryInExePath"] = "0"
runenv = {
"PATH": os.path.realpath(os.path.dirname(__file__)) + os.pathsep + os.getenv("PATH"),
"REAL_MVN_PATH": shutil.which("mvn"),
}
del os.environ["NoDefaultCurrentDirectoryInExePath"]
codeql.database.create(build_mode = "none", _env = runenv)

View File

@@ -0,0 +1,5 @@
---
category: fix
---
* Java build-mode `none` no longer fails when a required version of Maven cannot be downloaded, such as due to a firewall. It will now attempt to use the system version of Maven if present, or otherwise proceed without detailed dependency information.
* Java build-mode `none` now correctly uses Maven dependency information on Windows platforms.

View File

@@ -0,0 +1,24 @@
/**
* Provides classes for working with Spring classes and interfaces from
* `org.springframework.boot.*`.
*/
import java
/**
* The class `org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest`.
*/
class SpringEndpointRequest extends Class {
SpringEndpointRequest() {
this.hasQualifiedName("org.springframework.boot.actuate.autoconfigure.security.servlet",
"EndpointRequest")
}
}
/** A call to `EndpointRequest.toAnyEndpoint` method. */
class SpringToAnyEndpointCall extends MethodCall {
SpringToAnyEndpointCall() {
this.getMethod().hasName("toAnyEndpoint") and
this.getMethod().getDeclaringType() instanceof SpringEndpointRequest
}
}

View File

@@ -0,0 +1,124 @@
/**
* Provides classes for working with Spring classes and interfaces from
* `org.springframework.security.*`.
*/
import java
/** The class `org.springframework.security.config.annotation.web.builders.HttpSecurity`. */
class SpringHttpSecurity extends Class {
SpringHttpSecurity() {
this.hasQualifiedName("org.springframework.security.config.annotation.web.builders",
"HttpSecurity")
}
}
/**
* The class
* `org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer$AuthorizedUrl`
* or the class
* `org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer$AuthorizedUrl`.
*/
class SpringAuthorizedUrl extends Class {
SpringAuthorizedUrl() {
this.hasQualifiedName("org.springframework.security.config.annotation.web.configurers",
[
"ExpressionUrlAuthorizationConfigurer<HttpSecurity>$AuthorizedUrl<>",
"AuthorizeHttpRequestsConfigurer<HttpSecurity>$AuthorizedUrl<>"
])
}
}
/**
* The class `org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry`.
*/
class SpringAbstractRequestMatcherRegistry extends Class {
SpringAbstractRequestMatcherRegistry() {
this.hasQualifiedName("org.springframework.security.config.annotation.web",
"AbstractRequestMatcherRegistry<AuthorizedUrl<>>")
}
}
/**
* A call to the `HttpSecurity.authorizeRequests` method.
*
* Note: this method is deprecated and scheduled for removal
* in Spring Security 7.0.
*/
class SpringAuthorizeRequestsCall extends MethodCall {
SpringAuthorizeRequestsCall() {
this.getMethod().hasName("authorizeRequests") and
this.getMethod().getDeclaringType() instanceof SpringHttpSecurity
}
}
/**
* A call to the `HttpSecurity.authorizeHttpRequests` method.
*
* Note: the no-argument version of this method is deprecated
* and scheduled for removal in Spring Security 7.0.
*/
class SpringAuthorizeHttpRequestsCall extends MethodCall {
SpringAuthorizeHttpRequestsCall() {
this.getMethod().hasName("authorizeHttpRequests") and
this.getMethod().getDeclaringType() instanceof SpringHttpSecurity
}
}
/**
* A call to the `HttpSecurity.requestMatcher` method.
*
* Note: this method was removed in Spring Security 6.0.
* It was replaced by `securityMatcher`.
*/
class SpringRequestMatcherCall extends MethodCall {
SpringRequestMatcherCall() {
this.getMethod().hasName("requestMatcher") and
this.getMethod().getDeclaringType() instanceof SpringHttpSecurity
}
}
/**
* A call to the `HttpSecurity.requestMatchers` method.
*
* Note: this method was removed in Spring Security 6.0.
* It was replaced by `securityMatchers`.
*/
class SpringRequestMatchersCall extends MethodCall {
SpringRequestMatchersCall() {
this.getMethod().hasName("requestMatchers") and
this.getMethod().getDeclaringType() instanceof SpringHttpSecurity
}
}
/** A call to the `HttpSecurity.securityMatcher` method. */
class SpringSecurityMatcherCall extends MethodCall {
SpringSecurityMatcherCall() {
this.getMethod().hasName("securityMatcher") and
this.getMethod().getDeclaringType() instanceof SpringHttpSecurity
}
}
/** A call to the `HttpSecurity.securityMatchers` method. */
class SpringSecurityMatchersCall extends MethodCall {
SpringSecurityMatchersCall() {
this.getMethod().hasName("securityMatchers") and
this.getMethod().getDeclaringType() instanceof SpringHttpSecurity
}
}
/** A call to the `AuthorizedUrl.permitAll` method. */
class SpringPermitAllCall extends MethodCall {
SpringPermitAllCall() {
this.getMethod().hasName("permitAll") and
this.getMethod().getDeclaringType() instanceof SpringAuthorizedUrl
}
}
/** A call to the `AbstractRequestMatcherRegistry.anyRequest` method. */
class SpringAnyRequestCall extends MethodCall {
SpringAnyRequestCall() {
this.getMethod().hasName("anyRequest") and
this.getMethod().getDeclaringType() instanceof SpringAbstractRequestMatcherRegistry
}
}

View File

@@ -0,0 +1,110 @@
/** Provides classes and predicates to reason about exposed actuators in Spring Boot. */
import java
private import semmle.code.java.frameworks.spring.SpringSecurity
private import semmle.code.java.frameworks.spring.SpringBoot
/**
* A call to an `HttpSecurity` matcher method with argument
* `EndpointRequest.toAnyEndpoint()`.
*/
private class HttpSecurityMatcherCall extends MethodCall {
HttpSecurityMatcherCall() {
(
this instanceof SpringRequestMatcherCall or
this instanceof SpringSecurityMatcherCall
) and
this.getArgument(0) instanceof SpringToAnyEndpointCall
}
}
/**
* A call to an `HttpSecurity` matchers method with lambda
* argument `EndpointRequest.toAnyEndpoint()`.
*/
private class HttpSecurityMatchersCall extends MethodCall {
HttpSecurityMatchersCall() {
(
this instanceof SpringRequestMatchersCall or
this instanceof SpringSecurityMatchersCall
) and
this.getArgument(0).(LambdaExpr).getExprBody() instanceof SpringToAnyEndpointCall
}
}
/**
* A call to an `AbstractRequestMatcherRegistry.requestMatchers` method with
* argument `EndpointRequest.toAnyEndpoint()`.
*/
private class RegistryRequestMatchersCall extends MethodCall {
RegistryRequestMatchersCall() {
this.getMethod().hasName("requestMatchers") and
this.getMethod().getDeclaringType() instanceof SpringAbstractRequestMatcherRegistry and
this.getAnArgument() instanceof SpringToAnyEndpointCall
}
}
/** A call to an `HttpSecurity` method that authorizes requests. */
private class AuthorizeCall extends MethodCall {
AuthorizeCall() {
this instanceof SpringAuthorizeRequestsCall or
this instanceof SpringAuthorizeHttpRequestsCall
}
}
/** Holds if `permitAllCall` is called on request(s) mapped to actuator endpoint(s). */
predicate permitsSpringBootActuators(SpringPermitAllCall permitAllCall) {
exists(AuthorizeCall authorizeCall |
// .requestMatcher(EndpointRequest).authorizeRequests([...]).[...]
authorizeCall.getQualifier() instanceof HttpSecurityMatcherCall
or
// .requestMatchers(matcher -> EndpointRequest).authorizeRequests([...]).[...]
authorizeCall.getQualifier() instanceof HttpSecurityMatchersCall
|
// [...].authorizeRequests(r -> r.anyRequest().permitAll()) or
// [...].authorizeRequests(r -> r.requestMatchers(EndpointRequest).permitAll())
authorizeCall.getArgument(0).(LambdaExpr).getExprBody() = permitAllCall and
(
permitAllCall.getQualifier() instanceof SpringAnyRequestCall or
permitAllCall.getQualifier() instanceof RegistryRequestMatchersCall
)
or
// [...].authorizeRequests().requestMatchers(EndpointRequest).permitAll() or
// [...].authorizeRequests().anyRequest().permitAll()
authorizeCall.getNumArgument() = 0 and
exists(RegistryRequestMatchersCall registryRequestMatchersCall |
registryRequestMatchersCall.getQualifier() = authorizeCall and
permitAllCall.getQualifier() = registryRequestMatchersCall
)
or
exists(SpringAnyRequestCall anyRequestCall |
anyRequestCall.getQualifier() = authorizeCall and
permitAllCall.getQualifier() = anyRequestCall
)
)
or
exists(AuthorizeCall authorizeCall |
// http.authorizeRequests([...]).[...]
authorizeCall.getQualifier() instanceof VarAccess
|
// [...].authorizeRequests(r -> r.requestMatchers(EndpointRequest).permitAll())
authorizeCall.getArgument(0).(LambdaExpr).getExprBody() = permitAllCall and
permitAllCall.getQualifier() instanceof RegistryRequestMatchersCall
or
// [...].authorizeRequests().requestMatchers(EndpointRequest).permitAll() or
authorizeCall.getNumArgument() = 0 and
exists(RegistryRequestMatchersCall registryRequestMatchersCall |
registryRequestMatchersCall.getQualifier() = authorizeCall and
permitAllCall.getQualifier() = registryRequestMatchersCall
)
or
exists(Variable v, HttpSecurityMatcherCall matcherCall |
// http.securityMatcher(EndpointRequest.toAnyEndpoint());
// http.authorizeRequests([...].permitAll())
v.getAnAccess() = authorizeCall.getQualifier() and
v.getAnAccess() = matcherCall.getQualifier() and
authorizeCall.getArgument(0).(LambdaExpr).getExprBody() = permitAllCall and
permitAllCall.getQualifier() instanceof SpringAnyRequestCall
)
)
}

View File

@@ -0,0 +1,25 @@
@Configuration(proxyBeanMethods = false)
public class CustomSecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// BAD: Unauthenticated access to Spring Boot actuator endpoints is allowed
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll());
return http.build();
}
}
@Configuration(proxyBeanMethods = false)
public class CustomSecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// GOOD: only users with ENDPOINT_ADMIN role are allowed to access the actuator endpoints
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
return http.build();
}
}

View File

@@ -0,0 +1,36 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Spring Boot includes features called actuators that let you monitor and interact with your
web application. Exposing unprotected actuator endpoints can lead to information disclosure or
even to remote code execution.</p>
</overview>
<recommendation>
<p>Since actuator endpoints may contain sensitive information, carefully consider when to expose them,
and secure them as you would any sensitive URL. Actuators are secured by default when using Spring
Security without a custom configuration. If you wish to define a custom security configuration,
consider only allowing users with certain roles to access these endpoints.
</p>
</recommendation>
<example>
<p>In the first example, the custom security configuration allows unauthenticated access to all
actuator endpoints. This may lead to sensitive information disclosure and should be avoided.</p>
<p>In the second example, only users with <code>ENDPOINT_ADMIN</code> role are allowed to access
the actuator endpoints.</p>
<sample src="SpringBootActuators.java" />
</example>
<references>
<li>
Spring Boot Reference Documentation:
<a href="https://docs.spring.io/spring-boot/reference/actuator/endpoints.html">Endpoints</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,20 @@
/**
* @name Exposed Spring Boot actuators
* @description Exposing Spring Boot actuators may lead to information leak from the internal application,
* or even to remote code execution.
* @kind problem
* @problem.severity error
* @security-severity 6.5
* @precision high
* @id java/spring-boot-exposed-actuators
* @tags security
* external/cwe/cwe-200
*/
import java
import semmle.code.java.frameworks.spring.SpringSecurity
import semmle.code.java.security.SpringBootActuatorsQuery
from SpringPermitAllCall permitAllCall
where permitsSpringBootActuators(permitAllCall)
select permitAllCall, "Unauthenticated access to Spring Boot actuator is allowed."

View File

@@ -0,0 +1,4 @@
---
category: newQuery
---
* The query `java/spring-boot-exposed-actuators` has been promoted from experimental to the main query pack. Its results will now appear by default, and the query itself will be removed from the [CodeQL Community Packs](https://github.com/GitHubSecurityLab/CodeQL-Community-Packs). This query was originally submitted as an experimental query [by @ggolawski](https://github.com/github/codeql/pull/2901).

View File

@@ -1,22 +0,0 @@
@Configuration(proxyBeanMethods = false)
public class SpringBootActuators extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// BAD: Unauthenticated access to Spring Boot actuator endpoints is allowed
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) ->
requests.anyRequest().permitAll());
}
}
@Configuration(proxyBeanMethods = false)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// GOOD: only users with ENDPOINT_ADMIN role are allowed to access the actuator endpoints
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) ->
requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
http.httpBasic();
}
}

View File

@@ -1,39 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Spring Boot includes a number of additional features called actuators that let you monitor
and interact with your web application. Exposing unprotected actuator endpoints via JXM or HTTP
can, however, lead to information disclosure or even to remote code execution vulnerability.</p>
</overview>
<recommendation>
<p>Since actuator endpoints may contain sensitive information, careful consideration should be
given about when to expose them. You should take care to secure exposed HTTP endpoints in the same
way that you would any other sensitive URL. If Spring Security is present, endpoints are secured by
default using Spring Securitys content-negotiation strategy. If you wish to configure custom
security for HTTP endpoints, for example, only allow users with a certain role to access them,
Spring Boot provides some convenient <code>RequestMatcher</code> objects that can be used in
combination with Spring Security.</p>
</recommendation>
<example>
<p>In the first example, the custom security configuration allows unauthenticated access to all
actuator endpoints. This may lead to sensitive information disclosure and should be avoided.</p>
<p>In the second example, only users with <code>ENDPOINT_ADMIN</code> role are allowed to access
the actuator endpoints.</p>
<sample src="SpringBootActuators.java" />
</example>
<references>
<li>
Spring Boot documentation:
<a href="https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html">Actuators</a>.
</li>
<li>
<a href="https://www.veracode.com/blog/research/exploiting-spring-boot-actuators">Exploiting Spring Boot Actuators</a>
</li>
</references>
</qhelp>

View File

@@ -1,20 +0,0 @@
/**
* @name Exposed Spring Boot actuators
* @description Exposing Spring Boot actuators may lead to internal application's information leak
* or even to remote code execution.
* @kind problem
* @problem.severity error
* @precision high
* @id java/spring-boot-exposed-actuators
* @tags security
* experimental
* external/cwe/cwe-16
*/
import java
deprecated import SpringBootActuators
deprecated query predicate problems(PermitAllCall permitAllCall, string message) {
permitAllCall.permitsSpringBootActuators() and
message = "Unauthenticated access to Spring Boot actuator is allowed."
}

View File

@@ -1,157 +0,0 @@
deprecated module;
import java
/** The class `org.springframework.security.config.annotation.web.builders.HttpSecurity`. */
class TypeHttpSecurity extends Class {
TypeHttpSecurity() {
this.hasQualifiedName("org.springframework.security.config.annotation.web.builders",
"HttpSecurity")
}
}
/**
* The class
* `org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer`.
*/
class TypeAuthorizedUrl extends Class {
TypeAuthorizedUrl() {
this.hasQualifiedName("org.springframework.security.config.annotation.web.configurers",
"ExpressionUrlAuthorizationConfigurer<HttpSecurity>$AuthorizedUrl<>")
}
}
/**
* The class `org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry`.
*/
class TypeAbstractRequestMatcherRegistry extends Class {
TypeAbstractRequestMatcherRegistry() {
this.hasQualifiedName("org.springframework.security.config.annotation.web",
"AbstractRequestMatcherRegistry<AuthorizedUrl<>>")
}
}
/**
* The class `org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest`.
*/
class TypeEndpointRequest extends Class {
TypeEndpointRequest() {
this.hasQualifiedName("org.springframework.boot.actuate.autoconfigure.security.servlet",
"EndpointRequest")
}
}
/** A call to `EndpointRequest.toAnyEndpoint` method. */
class ToAnyEndpointCall extends MethodCall {
ToAnyEndpointCall() {
this.getMethod().hasName("toAnyEndpoint") and
this.getMethod().getDeclaringType() instanceof TypeEndpointRequest
}
}
/**
* A call to `HttpSecurity.requestMatcher` method with argument `RequestMatcher.toAnyEndpoint()`.
*/
class RequestMatcherCall extends MethodCall {
RequestMatcherCall() {
this.getMethod().hasName("requestMatcher") and
this.getMethod().getDeclaringType() instanceof TypeHttpSecurity and
this.getArgument(0) instanceof ToAnyEndpointCall
}
}
/**
* A call to `HttpSecurity.requestMatchers` method with lambda argument
* `RequestMatcher.toAnyEndpoint()`.
*/
class RequestMatchersCall extends MethodCall {
RequestMatchersCall() {
this.getMethod().hasName("requestMatchers") and
this.getMethod().getDeclaringType() instanceof TypeHttpSecurity and
this.getArgument(0).(LambdaExpr).getExprBody() instanceof ToAnyEndpointCall
}
}
/** A call to `HttpSecurity.authorizeRequests` method. */
class AuthorizeRequestsCall extends MethodCall {
AuthorizeRequestsCall() {
this.getMethod().hasName("authorizeRequests") and
this.getMethod().getDeclaringType() instanceof TypeHttpSecurity
}
}
/** A call to `AuthorizedUrl.permitAll` method. */
class PermitAllCall extends MethodCall {
PermitAllCall() {
this.getMethod().hasName("permitAll") and
this.getMethod().getDeclaringType() instanceof TypeAuthorizedUrl
}
/** Holds if `permitAll` is called on request(s) mapped to actuator endpoint(s). */
predicate permitsSpringBootActuators() {
exists(AuthorizeRequestsCall authorizeRequestsCall |
// .requestMatcher(EndpointRequest).authorizeRequests([...]).[...]
authorizeRequestsCall.getQualifier() instanceof RequestMatcherCall
or
// .requestMatchers(matcher -> EndpointRequest).authorizeRequests([...]).[...]
authorizeRequestsCall.getQualifier() instanceof RequestMatchersCall
|
// [...].authorizeRequests(r -> r.anyRequest().permitAll()) or
// [...].authorizeRequests(r -> r.requestMatchers(EndpointRequest).permitAll())
authorizeRequestsCall.getArgument(0).(LambdaExpr).getExprBody() = this and
(
this.getQualifier() instanceof AnyRequestCall or
this.getQualifier() instanceof RegistryRequestMatchersCall
)
or
// [...].authorizeRequests().requestMatchers(EndpointRequest).permitAll() or
// [...].authorizeRequests().anyRequest().permitAll()
authorizeRequestsCall.getNumArgument() = 0 and
exists(RegistryRequestMatchersCall registryRequestMatchersCall |
registryRequestMatchersCall.getQualifier() = authorizeRequestsCall and
this.getQualifier() = registryRequestMatchersCall
)
or
exists(AnyRequestCall anyRequestCall |
anyRequestCall.getQualifier() = authorizeRequestsCall and
this.getQualifier() = anyRequestCall
)
)
or
exists(AuthorizeRequestsCall authorizeRequestsCall |
// http.authorizeRequests([...]).[...]
authorizeRequestsCall.getQualifier() instanceof VarAccess
|
// [...].authorizeRequests(r -> r.requestMatchers(EndpointRequest).permitAll())
authorizeRequestsCall.getArgument(0).(LambdaExpr).getExprBody() = this and
this.getQualifier() instanceof RegistryRequestMatchersCall
or
// [...].authorizeRequests().requestMatchers(EndpointRequest).permitAll() or
authorizeRequestsCall.getNumArgument() = 0 and
exists(RegistryRequestMatchersCall registryRequestMatchersCall |
registryRequestMatchersCall.getQualifier() = authorizeRequestsCall and
this.getQualifier() = registryRequestMatchersCall
)
)
}
}
/** A call to `AbstractRequestMatcherRegistry.anyRequest` method. */
class AnyRequestCall extends MethodCall {
AnyRequestCall() {
this.getMethod().hasName("anyRequest") and
this.getMethod().getDeclaringType() instanceof TypeAbstractRequestMatcherRegistry
}
}
/**
* A call to `AbstractRequestMatcherRegistry.requestMatchers` method with an argument
* `RequestMatcher.toAnyEndpoint()`.
*/
class RegistryRequestMatchersCall extends MethodCall {
RegistryRequestMatchersCall() {
this.getMethod().hasName("requestMatchers") and
this.getMethod().getDeclaringType() instanceof TypeAbstractRequestMatcherRegistry and
this.getAnArgument() instanceof ToAnyEndpointCall
}
}

View File

@@ -1,7 +0,0 @@
| SpringBootActuators.java:6:88:6:120 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. |
| SpringBootActuators.java:10:5:10:137 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. |
| SpringBootActuators.java:14:5:14:149 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. |
| SpringBootActuators.java:18:5:18:101 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. |
| SpringBootActuators.java:22:5:22:89 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. |
| SpringBootActuators.java:26:40:26:108 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. |
| SpringBootActuators.java:30:5:30:113 | permitAll(...) | Unauthenticated access to Spring Boot actuator is allowed. |

View File

@@ -1,104 +0,0 @@
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
public class SpringBootActuators {
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests(requests -> requests.anyRequest().permitAll());
}
protected void configure2(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll();
}
protected void configure3(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll();
}
protected void configure4(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest().permitAll();
}
protected void configure5(HttpSecurity http) throws Exception {
http.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll();
}
protected void configure6(HttpSecurity http) throws Exception {
http.authorizeRequests(requests -> requests.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll());
}
protected void configure7(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest().permitAll();
}
protected void configureOk1(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint());
}
protected void configureOk2(HttpSecurity http) throws Exception {
http.requestMatchers().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOk3(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
}
protected void configureOk4(HttpSecurity http) throws Exception {
http.authorizeRequests(authz -> authz.anyRequest().permitAll());
}
protected void configureOkSafeEndpoints1(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.to("health", "info")).authorizeRequests(requests -> requests.anyRequest().permitAll());
}
protected void configureOkSafeEndpoints2(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.to("health")).authorizeRequests().requestMatchers(EndpointRequest.to("health")).permitAll();
}
protected void configureOkSafeEndpoints3(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeRequests().requestMatchers(EndpointRequest.to("health", "info")).permitAll();
}
protected void configureOkSafeEndpoints4(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.to("health", "info")).authorizeRequests().anyRequest().permitAll();
}
protected void configureOkSafeEndpoints5(HttpSecurity http) throws Exception {
http.authorizeRequests().requestMatchers(EndpointRequest.to("health", "info")).permitAll();
}
protected void configureOkSafeEndpoints6(HttpSecurity http) throws Exception {
http.authorizeRequests(requests -> requests.requestMatchers(EndpointRequest.to("health", "info")).permitAll());
}
protected void configureOkSafeEndpoints7(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeRequests().anyRequest().permitAll();
}
protected void configureOkNoPermitAll1(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests(requests -> requests.anyRequest());
}
protected void configureOkNoPermitAll2(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll3(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll4(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest();
}
protected void configureOkNoPermitAll5(HttpSecurity http) throws Exception {
http.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll6(HttpSecurity http) throws Exception {
http.authorizeRequests(requests -> requests.requestMatchers(EndpointRequest.toAnyEndpoint()));
}
protected void configureOkNoPermitAll7(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest();
}
}

View File

@@ -1 +0,0 @@
experimental/Security/CWE/CWE-016/SpringBootActuators.ql

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/lingala-zip4j-2.11.5:${testdir}/../../../stubs/software-amazon-awssdk-crt-0.20.3:${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/reactivestreams-1.0.4:${testdir}/../../../../stubs/slf4j-2.0.0
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/lingala-zip4j-2.11.5:${testdir}/../../../stubs/software-amazon-awssdk-crt-0.20.3:${testdir}/../../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/reactivestreams-1.0.4:${testdir}/../../../../stubs/slf4j-2.0.0

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../../stubs/springframework-5.3.8/:${testdir}/../../../../../../stubs/org.mybatis-3.5.4/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../../stubs/springframework-5.8.x/:${testdir}/../../../../../../stubs/org.mybatis-3.5.4/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/jython-2.7.2:${testdir}/../../../../experimental/stubs/rhino-1.7.13:${testdir}/../../../../stubs/bsh-2.0b5:${testdir}/../../../../experimental/stubs/jshell:${testdir}/../../../../experimental/stubs/apache-freemarker-2.3.31:${testdir}/../../../../experimental/stubs/jinjava-2.6.0:${testdir}/../../../../experimental/stubs/pebble-3.1.5:${testdir}/../../../../experimental/stubs/thymeleaf-3.0.14:${testdir}/../../../../experimental/stubs/apache-velocity-2.3
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/scriptengine:${testdir}/../../../../stubs/java-ee-el:${testdir}/../../../../stubs/juel-2.2:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/jython-2.7.2:${testdir}/../../../../experimental/stubs/rhino-1.7.13:${testdir}/../../../../stubs/bsh-2.0b5:${testdir}/../../../../experimental/stubs/jshell:${testdir}/../../../../experimental/stubs/apache-freemarker-2.3.31:${testdir}/../../../../experimental/stubs/jinjava-2.6.0:${testdir}/../../../../experimental/stubs/pebble-3.1.5:${testdir}/../../../../experimental/stubs/thymeleaf-3.0.14:${testdir}/../../../../experimental/stubs/apache-velocity-2.3

View File

@@ -1 +1 @@
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/jsr311-api-1.1.1:${testdir}/../../../../stubs/springframework-5.3.8
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/jsr311-api-1.1.1:${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.3.8/:${testdir}/../../../../stubs/apache-commons-lang3-3.7/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.8.x/:${testdir}/../../../../stubs/apache-commons-lang3-3.7/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/apache-http-4.4.13/:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/fastjson-1.2.74/:${testdir}/../../../../stubs/gson-2.8.6/:${testdir}/../../../../stubs/jackson-databind-2.12/:${testdir}/../../../../stubs/jackson-core-2.12:${testdir}/../../../../stubs/springframework-5.3.8/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/apache-http-4.4.13/:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/fastjson-1.2.74/:${testdir}/../../../../stubs/gson-2.8.6/:${testdir}/../../../../stubs/jackson-databind-2.12/:${testdir}/../../../../stubs/jackson-core-2.12:${testdir}/../../../../stubs/springframework-5.8.x/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.3.8/:${testdir}/../../../../stubs/google-android-9.0.0
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.8.x/:${testdir}/../../../../stubs/google-android-9.0.0

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.3.8/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.8.x/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/apache-http-4.4.13/:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/saxon-xqj-9.x/:${testdir}/../../../../stubs/springframework-5.3.8/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/apache-http-4.4.13/:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/saxon-xqj-9.x/:${testdir}/../../../../stubs/springframework-5.8.x/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/akka-2.6.x:${testdir}/../../../stubs/jwtk-jjwt-0.11.2:${testdir}/../../../stubs/jenkins:${testdir}/../../../stubs/stapler-1.263
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/akka-2.6.x:${testdir}/../../../stubs/jwtk-jjwt-0.11.2:${testdir}/../../../stubs/jenkins:${testdir}/../../../stubs/stapler-1.263

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1,2 +1,2 @@
//semmle-extractor-options: --javac-args -cp
//semmle-extractor-options: ${testdir}/../../../../stubs/springframework-5.3.8/
//semmle-extractor-options: ${testdir}/../../../../stubs/springframework-5.8.x/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../../stubs/apache-commons-logging-1.2/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x:${testdir}/../../../../stubs/apache-commons-logging-1.2/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../../stubs/javax-servlet-2.5
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x:${testdir}/../../../../stubs/javax-servlet-2.5

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../../stubs/javax-servlet-2.5
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x:${testdir}/../../../../stubs/javax-servlet-2.5

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../../stubs/javax-servlet-2.5:${testdir}/../../../../stubs/apache-commons-logging-1.2
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.8.x:${testdir}/../../../../stubs/javax-servlet-2.5:${testdir}/../../../../stubs/apache-commons-logging-1.2

View File

@@ -1 +1 @@
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/apache-commons-io-2.6:${testdir}/../../../../../stubs/cargo:${testdir}/../../../../../stubs/apache-ant-1.10.13:${testdir}/../../../../../stubs/stapler-1.263:${testdir}/../../../../../stubs/javax-servlet-2.5:${testdir}/../../../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../../../stubs/saxon-xqj-9.x:${testdir}/../../../../../stubs/apache-commons-beanutils:${testdir}/../../../../../stubs/dom4j-2.1.1:${testdir}/../../../../../stubs/apache-commons-lang:${testdir}/../../../../../stubs/jaxen-1.2.0:${testdir}/../../../../../stubs/jmh-1.3.6:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/jaxws-api-2.0:${testdir}/../../../../../stubs/apache-cxf
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/apache-commons-io-2.6:${testdir}/../../../../../stubs/cargo:${testdir}/../../../../../stubs/apache-ant-1.10.13:${testdir}/../../../../../stubs/stapler-1.263:${testdir}/../../../../../stubs/javax-servlet-2.5:${testdir}/../../../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../../../stubs/saxon-xqj-9.x:${testdir}/../../../../../stubs/apache-commons-beanutils:${testdir}/../../../../../stubs/dom4j-2.1.1:${testdir}/../../../../../stubs/apache-commons-lang:${testdir}/../../../../../stubs/jaxen-1.2.0:${testdir}/../../../../../stubs/jmh-1.3.6:${testdir}/../../../../../stubs/springframework-5.8.x:${testdir}/../../../../../stubs/jaxws-api-2.0:${testdir}/../../../../../stubs/apache-cxf

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../stubs/spring-ldap-2.3.2:${testdir}/../../../stubs/Saxon-HE-9.9.1-7:${testdir}/../../../stubs/apache-commons-logging-1.2
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../stubs/spring-ldap-2.3.2:${testdir}/../../../stubs/Saxon-HE-9.9.1-7:${testdir}/../../../stubs/apache-commons-logging-1.2

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/javax-faces-2.3/:${testdir}/../../../../../stubs/google-android-9.0.0:${testdir}/../../../../../stubs/jenkins
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.8.x:${testdir}/../../../../../stubs/javax-faces-2.3/:${testdir}/../../../../../stubs/google-android-9.0.0:${testdir}/../../../../../stubs/jenkins

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/apache-hive --release 21
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/springframework-5.8.x:${testdir}/../../../../../stubs/apache-hive --release 21

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/spring-ldap-2.3.2:${testdir}/../../../stubs/unboundid-ldap-4.0.14:${testdir}/../../../stubs/esapi-2.0.1:${testdir}/../../../stubs/apache-ldap-1.0.2
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/spring-ldap-2.3.2:${testdir}/../../../stubs/unboundid-ldap-4.0.14:${testdir}/../../../stubs/esapi-2.0.1:${testdir}/../../../stubs/apache-ldap-1.0.2

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2:${testdir}/../../../stubs/mvel2-2.4.7:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/scriptengine:${testdir}/../../../stubs/jsr223-api:${testdir}/../../../stubs/apache-freemarker-2.3.31:${testdir}/../../../stubs/jinjava-2.6.0:${testdir}/../../../stubs/pebble-3.1.5:${testdir}/../../../stubs/thymeleaf-3.0.14:${testdir}/../../../stubs/apache-velocity-2.3:${testdir}/../../..//stubs/google-android-9.0.0
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2:${testdir}/../../../stubs/mvel2-2.4.7:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/scriptengine:${testdir}/../../../stubs/jsr223-api:${testdir}/../../../stubs/apache-freemarker-2.3.31:${testdir}/../../../stubs/jinjava-2.6.0:${testdir}/../../../stubs/pebble-3.1.5:${testdir}/../../../stubs/thymeleaf-3.0.14:${testdir}/../../../stubs/apache-velocity-2.3:${testdir}/../../..//stubs/google-android-9.0.0

View File

@@ -0,0 +1,281 @@
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
public class SpringBootActuatorsTest {
// Spring security version 5.2.3 used `authorizeRequests` and `requestMatcher(s)`
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests(requests -> requests.anyRequest().permitAll()); // $ hasExposedSpringBootActuator
}
protected void configure2(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure3(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure4(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest().permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure5(HttpSecurity http) throws Exception {
http.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure6(HttpSecurity http) throws Exception {
http.authorizeRequests(requests -> requests.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()); // $ hasExposedSpringBootActuator
}
protected void configure7(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest().permitAll(); // $ hasExposedSpringBootActuator
}
protected void configureOk1(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint());
}
protected void configureOk2(HttpSecurity http) throws Exception {
http.requestMatchers().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOk3(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
}
protected void configureOk4(HttpSecurity http) throws Exception {
http.authorizeRequests(authz -> authz.anyRequest().permitAll());
}
protected void configureOkSafeEndpoints1(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.to("health", "info")).authorizeRequests(requests -> requests.anyRequest().permitAll());
}
protected void configureOkSafeEndpoints2(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.to("health")).authorizeRequests().requestMatchers(EndpointRequest.to("health")).permitAll();
}
protected void configureOkSafeEndpoints3(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeRequests().requestMatchers(EndpointRequest.to("health", "info")).permitAll();
}
protected void configureOkSafeEndpoints4(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.to("health", "info")).authorizeRequests().anyRequest().permitAll();
}
protected void configureOkSafeEndpoints5(HttpSecurity http) throws Exception {
http.authorizeRequests().requestMatchers(EndpointRequest.to("health", "info")).permitAll();
}
protected void configureOkSafeEndpoints6(HttpSecurity http) throws Exception {
http.authorizeRequests(requests -> requests.requestMatchers(EndpointRequest.to("health", "info")).permitAll());
}
protected void configureOkSafeEndpoints7(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeRequests().anyRequest().permitAll();
}
protected void configureOkNoPermitAll1(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests(requests -> requests.anyRequest());
}
protected void configureOkNoPermitAll2(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll3(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll4(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest();
}
protected void configureOkNoPermitAll5(HttpSecurity http) throws Exception {
http.authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll6(HttpSecurity http) throws Exception {
http.authorizeRequests(requests -> requests.requestMatchers(EndpointRequest.toAnyEndpoint()));
}
protected void configureOkNoPermitAll7(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeRequests().anyRequest();
}
// Spring security version 5.5.0 introduced `authorizeHttpRequests`
protected void configure_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests(requests -> requests.anyRequest().permitAll()); // $ hasExposedSpringBootActuator
}
protected void configure2_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure3_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure4_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().anyRequest().permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure5_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure6_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(requests -> requests.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()); // $ hasExposedSpringBootActuator
}
protected void configure7_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().anyRequest().permitAll(); // $ hasExposedSpringBootActuator
}
protected void configureOk3_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.authorizeHttpRequests().anyRequest().permitAll();
}
protected void configureOk4_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll());
}
protected void configureOkSafeEndpoints1_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.to("health", "info")).authorizeHttpRequests(requests -> requests.anyRequest().permitAll());
}
protected void configureOkSafeEndpoints2_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.to("health")).authorizeHttpRequests().requestMatchers(EndpointRequest.to("health")).permitAll();
}
protected void configureOkSafeEndpoints3_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeHttpRequests().requestMatchers(EndpointRequest.to("health", "info")).permitAll();
}
protected void configureOkSafeEndpoints4_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.to("health", "info")).authorizeHttpRequests().anyRequest().permitAll();
}
protected void configureOkSafeEndpoints5_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.authorizeHttpRequests().requestMatchers(EndpointRequest.to("health", "info")).permitAll();
}
protected void configureOkSafeEndpoints6_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(requests -> requests.requestMatchers(EndpointRequest.to("health", "info")).permitAll());
}
protected void configureOkSafeEndpoints7_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeHttpRequests().anyRequest().permitAll();
}
protected void configureOkNoPermitAll1_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests(requests -> requests.anyRequest());
}
protected void configureOkNoPermitAll2_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll3_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll4_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().anyRequest();
}
protected void configureOkNoPermitAll5_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll6_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(requests -> requests.requestMatchers(EndpointRequest.toAnyEndpoint()));
}
protected void configureOkNoPermitAll7_authorizeHttpRequests(HttpSecurity http) throws Exception {
http.requestMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().anyRequest();
}
// Spring security version 5.8.0 introduced `securityMatcher(s)`
protected void configure_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests(requests -> requests.anyRequest().permitAll()); // $ hasExposedSpringBootActuator
}
protected void configure2_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure3_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure4_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().anyRequest().permitAll(); // $ hasExposedSpringBootActuator
}
protected void configure7_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().anyRequest().permitAll(); // $ hasExposedSpringBootActuator
}
protected void configureOk1_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint());
}
protected void configureOk2_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatchers().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkSafeEndpoints1_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.to("health", "info")).authorizeHttpRequests(requests -> requests.anyRequest().permitAll());
}
protected void configureOkSafeEndpoints2_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.to("health")).authorizeHttpRequests().requestMatchers(EndpointRequest.to("health")).permitAll();
}
protected void configureOkSafeEndpoints3_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeHttpRequests().requestMatchers(EndpointRequest.to("health", "info")).permitAll();
}
protected void configureOkSafeEndpoints4_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.to("health", "info")).authorizeHttpRequests().anyRequest().permitAll();
}
protected void configureOkSafeEndpoints7_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatchers(matcher -> EndpointRequest.to("health", "info")).authorizeHttpRequests().anyRequest().permitAll();
}
protected void configureOkNoPermitAll1_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests(requests -> requests.anyRequest());
}
protected void configureOkNoPermitAll2_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll3_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().requestMatchers(EndpointRequest.toAnyEndpoint());
}
protected void configureOkNoPermitAll4_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().anyRequest();
}
protected void configureOkNoPermitAll7_securityMatchers(HttpSecurity http) throws Exception {
http.securityMatchers(matcher -> EndpointRequest.toAnyEndpoint()).authorizeHttpRequests().anyRequest();
}
// QHelp Bad example
public void securityFilterChain1(HttpSecurity http) throws Exception {
// BAD: Unauthenticated access to Spring Boot actuator endpoints is allowed
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll()); // $ hasExposedSpringBootActuator
}
// QHelp Good example
public void securityFilterChain2(HttpSecurity http) throws Exception {
// GOOD: only users with ENDPOINT_ADMIN role are allowed to access the actuator endpoints
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
}
}

View File

@@ -0,0 +1,19 @@
import java
import semmle.code.java.frameworks.spring.SpringSecurity
import semmle.code.java.security.SpringBootActuatorsQuery
import utils.test.InlineExpectationsTest
module SpringBootActuatorsTest implements TestSig {
string getARelevantTag() { result = "hasExposedSpringBootActuator" }
predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasExposedSpringBootActuator" and
exists(SpringPermitAllCall permitAllCall | permitsSpringBootActuators(permitAllCall) |
permitAllCall.getLocation() = location and
element = permitAllCall.toString() and
value = ""
)
}
}
import MakeTest<SpringBootActuatorsTest>

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../../stubs/springframework-5.8.x

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8/:${testdir}/../../../stubs/org.mybatis-3.5.4/:${testdir}/../../../stubs/stapler-1.263/:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/apache-commons-logging-1.2/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.8.x/:${testdir}/../../../stubs/org.mybatis-3.5.4/:${testdir}/../../../stubs/stapler-1.263/:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/apache-commons-logging-1.2/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3:${testdir}/../../../stubs/flexjson-2.1:${testdir}/../../../stubs/gson-2.8.6:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/serialkiller-4.0.0:${testdir}/../../../stubs/jms-api-1
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1:${testdir}/../../../stubs/jackson-databind-2.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3:${testdir}/../../../stubs/flexjson-2.1:${testdir}/../../../stubs/gson-2.8.6:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/serialkiller-4.0.0:${testdir}/../../../stubs/jms-api-1

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.3.8/:${testdir}/../../../stubs/javax-faces-2.3/:${testdir}/../../../stubs/undertow-io-2.2/:${testdir}/../../../stubs/jboss-vfs-3.2/:${testdir}/../../../stubs/stapler-1.263/:${testdir}/../../../stubs/apache-commons-fileupload-1.4/:${testdir}/../../../stubs/apache-commons-beanutils/:${testdir}/../../../stubs/saxon-xqj-9.x/:${testdir}/../../../stubs/apache-commons-lang/:${testdir}/../../../stubs/javax-servlet-2.5/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.8.x/:${testdir}/../../../stubs/javax-faces-2.3/:${testdir}/../../../stubs/undertow-io-2.2/:${testdir}/../../../stubs/jboss-vfs-3.2/:${testdir}/../../../stubs/stapler-1.263/:${testdir}/../../../stubs/apache-commons-fileupload-1.4/:${testdir}/../../../stubs/apache-commons-beanutils/:${testdir}/../../../stubs/saxon-xqj-9.x/:${testdir}/../../../stubs/apache-commons-lang/:${testdir}/../../../stubs/javax-servlet-2.5/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/jdom-1.1.3:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/simple-xml-2.7.1:${testdir}/../../../stubs/jaxb-api-2.3.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/apache-commons-digester3-3.2:${testdir}/../../../stubs/servlet-api-2.4/:${testdir}/../../../stubs/rundeck-api-java-client-13.2:${testdir}/../../../stubs/springframework-5.3.8/:${testdir}/../../../stubs/mdht-1.2.0/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/jdom-1.1.3:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/simple-xml-2.7.1:${testdir}/../../../stubs/jaxb-api-2.3.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/apache-commons-digester3-3.2:${testdir}/../../../stubs/servlet-api-2.4/:${testdir}/../../../stubs/rundeck-api-java-client-13.2:${testdir}/../../../stubs/springframework-5.8.x/:${testdir}/../../../stubs/mdht-1.2.0/

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/ognl-3.2.14:${testdir}/../../../stubs/struts2-core-2.5.22
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/ognl-3.2.14:${testdir}/../../../stubs/struts2-core-2.5.22

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jaxws-api-2.0:${testdir}/../../../stubs/apache-cxf
//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/springframework-5.8.x:${testdir}/../../../stubs/javax-ws-rs-api-2.1.1:${testdir}/../../../stubs/javax-ws-rs-api-3.0.0:${testdir}/../../../stubs/apache-http-4.4.13/:${testdir}/../../../stubs/projectreactor-3.4.3/:${testdir}/../../../stubs/postgresql-42.3.3/:${testdir}/../../../stubs/HikariCP-3.4.5/:${testdir}/../../../stubs/spring-jdbc-5.3.8/:${testdir}/../../../stubs/jdbi3-core-3.27.2/:${testdir}/../../../stubs/cargo:${testdir}/../../../stubs/javafx-web:${testdir}/../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../stubs/dom4j-2.1.1:${testdir}/../../../stubs/jaxen-1.2.0:${testdir}/../../../stubs/stapler-1.263:${testdir}/../../../stubs/javax-servlet-2.5:${testdir}/../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../stubs/saxon-xqj-9.x:${testdir}/../../../stubs/apache-commons-beanutils:${testdir}/../../../stubs/apache-commons-lang:${testdir}/../../../stubs/apache-http-5:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jaxws-api-2.0:${testdir}/../../../stubs/apache-cxf

Some files were not shown because too many files have changed in this diff Show More