Skip to content

Commit 9cc614a

Browse files
committed
Allow jax-rs path annotation inheritance
1 parent de1b374 commit 9cc614a

File tree

7 files changed

+64
-50
lines changed

7 files changed

+64
-50
lines changed

java/ql/lib/semmle/code/java/frameworks/JaxWS.qll

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,20 @@ private predicate hasPathAnnotation(Annotatable annotatable) {
147147
)
148148
}
149149

150+
/**
151+
* Holds if the class inherites the JaxRs `@Path` annotation.
152+
*/
153+
private predicate hasOrInheritsPathAnnotation(Class c) {
154+
hasPathAnnotation(c)
155+
or
156+
// Note that by the JAX-RS spec, JAX-RS annotations on classes and interfaces
157+
// are not inherited, but some implementations, like Apache CXF, do inherit
158+
// them. I think this only applies if there are no JaxRS annotations on the
159+
// class itself.
160+
hasPathAnnotation(c.getAnAncestor()) and
161+
not exists(c.getAnAnnotation().(JaxRSAnnotation))
162+
}
163+
150164
/**
151165
* A method which is annotated with one or more JaxRS resource type annotations e.g. `@GET`, `@POST` etc.
152166
*/
@@ -191,7 +205,7 @@ class JaxRsResourceMethod extends Method {
191205
class JaxRsResourceClass extends Class {
192206
JaxRsResourceClass() {
193207
// A root resource class has a @Path annotation on the class.
194-
hasPathAnnotation(this)
208+
hasOrInheritsPathAnnotation(this)
195209
or
196210
// A sub-resource
197211
exists(JaxRsResourceClass resourceClass, Method method |
@@ -227,7 +241,7 @@ class JaxRsResourceClass extends Class {
227241
/**
228242
* Holds if this class is a "root resource" class
229243
*/
230-
predicate isRootResource() { hasPathAnnotation(this) }
244+
predicate isRootResource() { hasOrInheritsPathAnnotation(this) }
231245

232246
/**
233247
* Gets a `Constructor` that may be called by a JaxRS container to construct this class reflectively.

java/ql/test/library-tests/frameworks/JaxWs/JakartaRs1.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,12 @@ class NotAResourceClass1Jakarta {
156156
class NotAResourceClass2Jakarta {
157157
}
158158

159-
class ExtendsJakartaRs1 extends JakartaRs1 {
159+
class ExtendsJakartaRs1 extends JakartaRs1 { // $ RootResourceClass
160160
@Override
161161
int Get() { // $ ResourceMethod
162162
return 1;
163163
}
164-
164+
165165
@Override
166166
@QueryParam("") // $ InjectionAnnotation
167167
void Post() {
@@ -189,12 +189,12 @@ void Head() {
189189
}
190190

191191
@Produces(MediaType.TEXT_XML) // $ ProducesAnnotation=text/xml
192-
class ExtendsJakartaRs1WithProducesAnnotation extends JakartaRs1 {
192+
class ExtendsJakartaRs1WithProducesAnnotation extends JakartaRs1 { // Not a root resource class because it has a JAX-RS annotation
193193
@Override
194194
int Get() { // $ ResourceMethod=text/xml
195195
return 2;
196196
}
197-
197+
198198
@Override
199199
@QueryParam("") // $ InjectionAnnotation
200200
void Post() {
@@ -212,4 +212,4 @@ void Put() { // $ ResourceMethod=text/html
212212
@Override
213213
void Options() { // $ ResourceMethod=text/xml
214214
}
215-
}
215+
}

java/ql/test/library-tests/frameworks/JaxWs/JakartaRs3.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import jakarta.ws.rs.core.Response;
2525
import jakarta.ws.rs.ext.MessageBodyReader;
2626

27-
class ExtendsJakartaRs3 extends JakartaRs3 {
27+
class ExtendsJakartaRs3 extends JakartaRs3 { // $ RootResourceClass
2828
@Override
2929
public int Get() { // $ ResourceMethod
3030
return 1;
@@ -57,7 +57,7 @@ public void Head() { // not a resource method because it has a jax-rs annotation
5757
}
5858

5959
@Produces(MediaType.TEXT_XML) // $ ProducesAnnotation=text/xml
60-
class ExtendsJakartaRs3WithProducesAnnotation extends JakartaRs3 {
60+
class ExtendsJakartaRs3WithProducesAnnotation extends JakartaRs3 { // Not a root resource class because it has a JAX-RS annotation
6161
@Override
6262
public int Get() { // $ ResourceMethod=text/xml
6363
return 2;

java/ql/test/library-tests/frameworks/JaxWs/JakartaRs4.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@
2727
// This is not a resource class because it doesn't have a @Path annotation.
2828
// Note that inheritance of class or interface annotations is not supported in
2929
// JAX-RS.
30-
public class JakartaRs4 implements JakartaRsInterface {
31-
public JakartaRs4() {
30+
public class JakartaRs4 implements JakartaRsInterface { // $ RootResourceClass
31+
public JakartaRs4() { // $ InjectableConstructor
3232
}
3333

3434
@Override
35-
public int Get() { // $ ResourceMethod
36-
return 1;
35+
public int Get() { // $ ResourceMethod ResourceMethodOnResourceClass
36+
return 1; // $ XssSink
3737
}
3838

3939
@Override
40-
public void Post() { // $ ResourceMethod
40+
public void Post() { // $ ResourceMethod ResourceMethodOnResourceClass
4141
}
4242

4343
@Produces("application/json") // $ ProducesAnnotation=application/json
@@ -52,11 +52,11 @@ public void Put() { // not a resource method because it has a jax-rs annotation,
5252
}
5353

5454
@Override
55-
public void Options() { // $ ResourceMethod
55+
public void Options() { // $ ResourceMethod ResourceMethodOnResourceClass
5656
}
5757

5858
@Override
59-
public void Head() { // $ ResourceMethod
59+
public void Head() { // $ ResourceMethod ResourceMethod ResourceMethodOnResourceClass
6060
}
6161

6262

@@ -65,21 +65,21 @@ NonRootResourceClassJakarta subResourceLocator() {
6565
return null;
6666
}
6767

68-
public class NonRootResourceClassJakarta {
68+
public class NonRootResourceClassJakarta { // $ NonRootResourceClass
6969
@GET
70-
int Get() { // $ ResourceMethod
71-
return 0;
70+
int Get() { // $ ResourceMethod ResourceMethodOnResourceClass
71+
return 0; // $ XssSink
7272
}
7373

7474
@Produces("text/html") // $ ProducesAnnotation=text/html
7575
@POST
76-
boolean Post() { // $ ResourceMethod=text/html
77-
return false;
76+
boolean Post() { // $ ResourceMethod=text/html ResourceMethodOnResourceClass
77+
return false; // $ XssSink
7878
}
7979

8080
@Produces(MediaType.TEXT_PLAIN) // $ ProducesAnnotation=text/plain
8181
@DELETE
82-
double Delete() { // $ ResourceMethod=text/plain
82+
double Delete() { // $ ResourceMethod=text/plain ResourceMethodOnResourceClass
8383
return 0.0;
8484
}
8585

@@ -90,13 +90,13 @@ AnotherNonRootResourceClassJakarta subResourceLocator1() { // $ SubResourceLocat
9090

9191
@GET
9292
@Path("")
93-
NotAResourceClass1Jakarta NotASubResourceLocator1() { // $ ResourceMethod
94-
return null; //
93+
NotAResourceClass1Jakarta NotASubResourceLocator1() { // $ ResourceMethod ResourceMethodOnResourceClass
94+
return null; // $ XssSink
9595
}
9696

9797
@GET
98-
NotAResourceClass2Jakarta NotASubResourceLocator2() { // $ ResourceMethod
99-
return null; //
98+
NotAResourceClass2Jakarta NotASubResourceLocator2() { // $ ResourceMethod ResourceMethodOnResourceClass
99+
return null; // $ XssSink
100100
}
101101

102102
NotAResourceClass2Jakarta NotASubResourceLocator3() {

java/ql/test/library-tests/frameworks/JaxWs/JaxRs1.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,12 @@ class NotAResourceClass1 {
156156
class NotAResourceClass2 {
157157
}
158158

159-
class ExtendsJaxRs1 extends JaxRs1 {
159+
class ExtendsJaxRs1 extends JaxRs1 { // $ RootResourceClass
160160
@Override
161161
int Get() { // $ ResourceMethod
162162
return 1;
163163
}
164-
164+
165165
@Override
166166
@QueryParam("") // $ InjectionAnnotation
167167
void Post() {
@@ -189,12 +189,12 @@ void Head() {
189189
}
190190

191191
@Produces(MediaType.TEXT_XML) // $ ProducesAnnotation=text/xml
192-
class ExtendsJaxRs1WithProducesAnnotation extends JaxRs1 {
192+
class ExtendsJaxRs1WithProducesAnnotation extends JaxRs1 { // Not a root resource class because it has a JAX-RS annotation
193193
@Override
194194
int Get() { // $ ResourceMethod=text/xml
195195
return 2;
196196
}
197-
197+
198198
@Override
199199
@QueryParam("") // $ InjectionAnnotation
200200
void Post() {
@@ -212,4 +212,4 @@ void Put() { // $ ResourceMethod=text/html
212212
@Override
213213
void Options() { // $ ResourceMethod=text/xml
214214
}
215-
}
215+
}

java/ql/test/library-tests/frameworks/JaxWs/JaxRs3.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import javax.ws.rs.core.Response;
2525
import javax.ws.rs.ext.MessageBodyReader;
2626

27-
class ExtendsJaxRs3 extends JaxRs3 {
27+
class ExtendsJaxRs3 extends JaxRs3 { // $ RootResourceClass
2828
@Override
2929
public int Get() { // $ ResourceMethod
3030
return 1;
@@ -57,7 +57,7 @@ public void Head() { // not a resource method because it has a jax-rs annotation
5757
}
5858

5959
@Produces(MediaType.TEXT_XML) // $ ProducesAnnotation=text/xml
60-
class ExtendsJaxRs3WithProducesAnnotation extends JaxRs3 {
60+
class ExtendsJaxRs3WithProducesAnnotation extends JaxRs3 { // Not a root resource class because it has a JAX-RS annotation
6161
@Override
6262
public int Get() { // $ ResourceMethod=text/xml
6363
return 2;

java/ql/test/library-tests/frameworks/JaxWs/JaxRs4.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,17 @@
2727
// This is not a resource class because it doesn't have a @Path annotation.
2828
// Note that inheritance of class or interface annotations is not supported in
2929
// JAX-RS.
30-
public class JaxRs4 implements JaxRsInterface {
31-
public JaxRs4() {
30+
public class JaxRs4 implements JaxRsInterface { // $ RootResourceClass
31+
public JaxRs4() { // $ InjectableConstructor
3232
}
3333

3434
@Override
35-
public int Get() { // $ ResourceMethod
36-
return 1;
35+
public int Get() { // $ ResourceMethod ResourceMethodOnResourceClass
36+
return 1; // $ XssSink
3737
}
3838

3939
@Override
40-
public void Post() { // $ ResourceMethod
40+
public void Post() { // $ ResourceMethod ResourceMethodOnResourceClass
4141
}
4242

4343
@Produces("application/json") // $ ProducesAnnotation=application/json
@@ -52,11 +52,11 @@ public void Put() { // not a resource method because it has a jax-rs annotation,
5252
}
5353

5454
@Override
55-
public void Options() { // $ ResourceMethod
55+
public void Options() { // $ ResourceMethod ResourceMethodOnResourceClass
5656
}
5757

5858
@Override
59-
public void Head() { // $ ResourceMethod
59+
public void Head() { // $ ResourceMethod ResourceMethodOnResourceClass
6060
}
6161

6262

@@ -65,21 +65,21 @@ NonRootResourceClass subResourceLocator() {
6565
return null;
6666
}
6767

68-
public class NonRootResourceClass {
68+
public class NonRootResourceClass { // $ NonRootResourceClass
6969
@GET
70-
int Get() { // $ ResourceMethod
71-
return 0;
70+
int Get() { // $ ResourceMethod ResourceMethodOnResourceClass
71+
return 0; // $ XssSink
7272
}
7373

7474
@Produces("text/html") // $ ProducesAnnotation=text/html
7575
@POST
76-
boolean Post() { // $ ResourceMethod=text/html
77-
return false;
76+
boolean Post() { // $ ResourceMethod=text/html ResourceMethodOnResourceClass
77+
return false; // $ XssSink
7878
}
7979

8080
@Produces(MediaType.TEXT_PLAIN) // $ ProducesAnnotation=text/plain
8181
@DELETE
82-
double Delete() { // $ ResourceMethod=text/plain
82+
double Delete() { // $ ResourceMethod=text/plain ResourceMethodOnResourceClass
8383
return 0.0;
8484
}
8585

@@ -90,13 +90,13 @@ AnotherNonRootResourceClass subResourceLocator1() { // $ SubResourceLocator
9090

9191
@GET
9292
@Path("")
93-
NotAResourceClass1 NotASubResourceLocator1() { // $ ResourceMethod
94-
return null; //
93+
NotAResourceClass1 NotASubResourceLocator1() { // $ ResourceMethod ResourceMethodOnResourceClass
94+
return null; // $ XssSink
9595
}
9696

9797
@GET
98-
NotAResourceClass2 NotASubResourceLocator2() { // $ ResourceMethod
99-
return null; //
98+
NotAResourceClass2 NotASubResourceLocator2() { // $ ResourceMethod ResourceMethodOnResourceClass
99+
return null; // $ XssSink
100100
}
101101

102102
NotAResourceClass2 NotASubResourceLocator3() {

0 commit comments

Comments
 (0)