Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions java/jenkins/reflection/setaccessible-true.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
rules:
- id: codevigilant.java.jenkins.reflection.setaccessible.true
patterns:
- pattern-either:
- pattern: $X.setAccessible(true)
- pattern: |
$X.accessible = true
- pattern-not: $X.setAccessible(false)
message: |
Detected reflective access turned on via setAccessible(true) (or the
Groovy property-assignment form `accessible = true`) on a
Field/Method/Constructor obtained from a class. setAccessible(true)
suppresses the Java language access checks, letting plugin code reach
protected/private members of other classes. In Jenkins this is
typically used to reach into core internals, bypassing the
access-control and safety guardrails the framework places around
protected APIs (permission checks, async isolation, timeouts,
synchronization). It also breaks under the Java module system
(InaccessibleObjectException). Prefer the public API; if internals
are genuinely needed, use the supported extension points or
Restricted/NoExternalUse APIs instead of reflection.
metadata:
category: security
cwe: "CWE-284: Improper Access Control"
owasp: "A01:2021 - Broken Access Control"
technology: jenkins
confidence: MEDIUM
references:
- https://www.jenkins.io/doc/developer/security/
- https://www.jenkins.io/doc/developer/extensions/
source: independent security review
license: MIT
languages: [generic]
mode: search
severity: HIGH
11 changes: 11 additions & 0 deletions testcases/java/reflection-setaccessible-neg.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public class ReflectionNeg {
public void touch(Class<?> c) throws Exception {
java.lang.reflect.Field f = c.getDeclaredField("record");
f.setAccessible(false); // access checks stay on
java.lang.reflect.Method m = c.getDeclaredMethod("monitor", Object.class);
// goes through the public API instead of reflection
Object v = c.newInstance();
m.setAccessible(false);
Object r = m.invoke(v, new Object());
}
}
10 changes: 10 additions & 0 deletions testcases/java/reflection-setaccessible-pos.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
public class ReflectionPos {
public void touch(Class<?> c) throws Exception {
java.lang.reflect.Field f = c.getDeclaredField("record");
f.setAccessible(true);
Object v = f.get(c.newInstance());
java.lang.reflect.Method m = c.getDeclaredMethod("monitor", Object.class);
m.accessible = true; // groovy-style property assignment
Object r = m.invoke(v, new Object());
}
}