Merge remote-tracking branch 'upstream/master' into set-map-list-copy-of

This commit is contained in:
Arthur Baars
2020-07-08 15:11:13 +02:00
702 changed files with 27270 additions and 27127 deletions

View File

@@ -15,16 +15,16 @@ class Location extends @location {
/** Gets the file corresponding to this location, if any. */
File getFile() { result = this.getContainer() }
/** Gets the start line of this location. */
/** Gets the 1-based line number (inclusive) where this location starts. */
int getStartLine() { this.fullLocationInfo(_, result, _, _, _) }
/** Gets the start column of this location. */
/** Gets the 1-based column number (inclusive) where this location starts. */
int getStartColumn() { this.fullLocationInfo(_, _, result, _, _) }
/** Gets the end line of this location. */
/** Gets the 1-based line number (inclusive) where this location ends. */
int getEndLine() { this.fullLocationInfo(_, _, _, result, _) }
/** Gets the end column of this location. */
/** Gets the 1-based column number (inclusive) where this location ends. */
int getEndColumn() { this.fullLocationInfo(_, _, _, _, result) }
/**

View File

@@ -62,6 +62,8 @@
| Function | specifiers2pp.cpp:29:7:29:7 | operator= | operator= | extern |
| Function | specifiers2pp.cpp:29:7:29:7 | operator= | operator= | inline |
| Function | specifiers2pp.cpp:29:7:29:7 | operator= | operator= | inline |
| Function | specifiers2pp.cpp:29:7:29:7 | operator= | operator= | is_constexpr |
| Function | specifiers2pp.cpp:29:7:29:7 | operator= | operator= | is_constexpr |
| Function | specifiers2pp.cpp:29:7:29:7 | operator= | operator= | public |
| Function | specifiers2pp.cpp:29:7:29:7 | operator= | operator= | public |
| Function | specifiers2pp.cpp:33:5:33:18 | fun | fun | public |
@@ -69,6 +71,8 @@
| Function | specifiers2pp.cpp:35:7:35:7 | operator= | operator= | extern |
| Function | specifiers2pp.cpp:35:7:35:7 | operator= | operator= | inline |
| Function | specifiers2pp.cpp:35:7:35:7 | operator= | operator= | inline |
| Function | specifiers2pp.cpp:35:7:35:7 | operator= | operator= | is_constexpr |
| Function | specifiers2pp.cpp:35:7:35:7 | operator= | operator= | is_constexpr |
| Function | specifiers2pp.cpp:35:7:35:7 | operator= | operator= | public |
| Function | specifiers2pp.cpp:35:7:35:7 | operator= | operator= | public |
| Function | specifiers2pp.cpp:40:12:40:18 | someFun | someFun | extern |

View File

@@ -38,16 +38,16 @@ class Location extends @location {
/** Gets a textual representation of this location. */
string toString() { none() }
/** Gets the start line of this location. */
/** Gets the 1-based line number (inclusive) where this location starts. */
final int getStartLine() { this.hasLocationInfo(_, result, _, _, _) }
/** Gets the end line of this location. */
/** Gets the 1-based line number (inclusive) where this location ends. */
final int getEndLine() { this.hasLocationInfo(_, _, _, result, _) }
/** Gets the start column of this location. */
/** Gets the 1-based column number (inclusive) where this location starts. */
final int getStartColumn() { this.hasLocationInfo(_, _, result, _, _) }
/** Gets the end column of this location. */
/** Gets the 1-based column number (inclusive) where this location ends. */
final int getEndColumn() { this.hasLocationInfo(_, _, _, _, result) }
}

View File

@@ -49,7 +49,7 @@ We could then write this query to find all ``@SuppressWarnings`` annotations att
anntp.hasQualifiedName("java.lang", "SuppressWarnings")
select ann, ann.getValue("value")
`See the full query in the query console on LGTM.com <https://lgtm.com/query/632150601>`__. Several of the LGTM.com demo projects use the ``@SuppressWarnings`` annotation. Looking at the ``value``\ s of the annotation element returned by the query, we can see that the *apache/activemq* project uses the ``"rawtypes"`` value described above.
`See the full query in the query console on LGTM.com <https://lgtm.com/query/1775658606775222283/>`__. Several of the LGTM.com demo projects use the ``@SuppressWarnings`` annotation. Looking at the ``value``\ s of the annotation element returned by the query, we can see that the *apache/activemq* project uses the ``"rawtypes"`` value described above.
As another example, this query finds all annotation types that only have a single annotation element, which has name ``value``:
@@ -64,7 +64,7 @@ As another example, this query finds all annotation types that only have a singl
)
select anntp
`See the full query in the query console on LGTM.com <https://lgtm.com/query/669220001>`__.
`See the full query in the query console on LGTM.com <https://lgtm.com/query/2145264152490258283/>`__.
Example: Finding missing ``@Override`` annotations
--------------------------------------------------
@@ -122,7 +122,7 @@ This makes it very easy to write our query for finding methods that override ano
not overriding.getAnAnnotation() instanceof OverrideAnnotation
select overriding, "Method overrides another method, but does not have an @Override annotation."
`See this in the query console on LGTM.com <https://lgtm.com/query/1505752756202/>`__. In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available.
`See this in the query console on LGTM.com <https://lgtm.com/query/7419756266089837339/>`__. In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available.
Example: Finding calls to deprecated methods
--------------------------------------------
@@ -192,13 +192,13 @@ For instance, consider this slightly updated example:
.. code-block:: java
class A {
@Deprecated void m() {}
@Deprecated void m() {}
@Deprecated void n() {
m();
}
@Deprecated void n() {
m();
}
@SuppressWarnings("deprecated")
@SuppressWarnings("deprecated")
void r() {
m();
}
@@ -235,7 +235,7 @@ Now we can extend our query to filter out calls in methods carrying a ``Suppress
and not call.getCaller().getAnAnnotation() instanceof SuppressDeprecationWarningAnnotation
select call, "This call invokes a deprecated method."
`See this in the query console on LGTM.com <https://lgtm.com/query/665760001>`__. It's fairly common for projects to contain calls to methods that appear to be deprecated.
`See this in the query console on LGTM.com <https://lgtm.com/query/8706367340403790260/>`__. It's fairly common for projects to contain calls to methods that appear to be deprecated.
Further reading
---------------

View File

@@ -78,7 +78,7 @@ We can use the ``Callable`` class to write a query that finds methods that are n
where not exists(Callable caller | caller.polyCalls(callee))
select callee
`See this in the query console on LGTM.com <https://lgtm.com/query/665280012/>`__. This simple query typically returns a large number of results.
`See this in the query console on LGTM.com <https://lgtm.com/query/8376915232270534450/>`__. This simple query typically returns a large number of results.
.. pull-quote::
@@ -97,7 +97,7 @@ Running this query on a typical Java project results in lots of hits in the Java
callee.getCompilationUnit().fromSource()
select callee, "Not called."
`See this in the query console on LGTM.com <https://lgtm.com/query/668510015/>`__. This change reduces the number of results returned for most projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/8711624074465690976/>`__. This change reduces the number of results returned for most projects.
We might also notice several unused methods with the somewhat strange name ``<clinit>``: these are class initializers; while they are not explicitly called anywhere in the code, they are called implicitly whenever the surrounding class is loaded. Hence it makes sense to exclude them from our query. While we are at it, we can also exclude finalizers, which are similarly invoked implicitly:
@@ -111,7 +111,7 @@ We might also notice several unused methods with the somewhat strange name ``<cl
not callee.hasName("<clinit>") and not callee.hasName("finalize")
select callee, "Not called."
`See this in the query console on LGTM.com <https://lgtm.com/query/672230002/>`__. This also reduces the number of results returned by most projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/925473733866047471/>`__. This also reduces the number of results returned by most projects.
We may also want to exclude public methods from our query, since they may be external API entry points:
@@ -126,7 +126,7 @@ We may also want to exclude public methods from our query, since they may be ext
not callee.isPublic()
select callee, "Not called."
`See this in the query console on LGTM.com <https://lgtm.com/query/667290016/>`__. This should have a more noticeable effect on the number of results returned.
`See this in the query console on LGTM.com <https://lgtm.com/query/6284320987237954610/>`__. This should have a more noticeable effect on the number of results returned.
A further special case is non-public default constructors: in the singleton pattern, for example, a class is provided with private empty default constructor to prevent it from being instantiated. Since the very purpose of such constructors is their not being called, they should not be flagged up:
@@ -142,7 +142,7 @@ A further special case is non-public default constructors: in the singleton patt
not callee.(Constructor).getNumberOfParameters() = 0
select callee, "Not called."
`See this in the query console on LGTM.com <https://lgtm.com/query/673060008/>`__. This change has a large effect on the results for some projects but little effect on the results for others. Use of this pattern varies widely between different projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/2625028545869146918/>`__. This change has a large effect on the results for some projects but little effect on the results for others. Use of this pattern varies widely between different projects.
Finally, on many Java projects there are methods that are invoked indirectly by reflection. So, while there are no calls invoking these methods, they are, in fact, used. It is in general very hard to identify such methods. A very common special case, however, is JUnit test methods, which are reflectively invoked by a test runner. The CodeQL library for Java has support for recognizing test classes of JUnit and other testing frameworks, which we can employ to filter out methods defined in such classes:
@@ -159,7 +159,7 @@ Finally, on many Java projects there are methods that are invoked indirectly by
not callee.getDeclaringType() instanceof TestClass
select callee, "Not called."
`See this in the query console on LGTM.com <https://lgtm.com/query/665760002/>`__. This should give a further reduction in the number of results returned.
`See this in the query console on LGTM.com <https://lgtm.com/query/2055862421970264112/>`__. This should give a further reduction in the number of results returned.
Further reading
---------------

View File

@@ -42,7 +42,7 @@ We'll start by writing a query that finds less-than expressions (CodeQL class ``
expr.getRightOperand().getType().hasName("long")
select expr
`See this in the query console on LGTM.com <https://lgtm.com/query/672320008/>`__. This query usually finds results on most projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/490866529746563234/>`__. This query usually finds results on most projects.
Notice that we use the predicate ``getType`` (available on all subclasses of ``Expr``) to determine the type of the operands. Types, in turn, define the ``hasName`` predicate, which allows us to identify the primitive types ``int`` and ``long``. As it stands, this query finds *all* less-than expressions comparing ``int`` and ``long``, but in fact we are only interested in comparisons that are part of a loop condition. Also, we want to filter out comparisons where either operand is constant, since these are less likely to be real bugs. The revised query looks like this:
@@ -57,7 +57,7 @@ Notice that we use the predicate ``getType`` (available on all subclasses of ``E
not expr.getAnOperand().isCompileTimeConstant()
select expr
`See this in the query console on LGTM.com <https://lgtm.com/query/690010001/>`__. Notice that fewer results are found.
`See this in the query console on LGTM.com <https://lgtm.com/query/4315986481180063825/>`__. Notice that fewer results are found.
The class ``LoopStmt`` is a common superclass of all loops, including, in particular, ``for`` loops as in our example above. While different kinds of loops have different syntax, they all have a loop condition, which can be accessed through predicate ``getCondition``. We use the reflexive transitive closure operator ``*`` applied to the ``getAChildExpr`` predicate to express the requirement that ``expr`` should be nested inside the loop condition. In particular, it can be the loop condition itself.
@@ -120,7 +120,7 @@ Now we rewrite our query to make use of these new classes:
not expr.getAnOperand().isCompileTimeConstant()
select expr
`See the full query in the query console on LGTM.com <https://lgtm.com/query/1951710018/lang:java/>`__.
`See the full query in the query console on LGTM.com <https://lgtm.com/query/506868054626167462/>`__.
Further reading
---------------

View File

@@ -49,7 +49,7 @@ Types
Class ``Type`` has a number of subclasses for representing different kinds of types:
- ``PrimitiveType`` represents a `primitive type <http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html>`__, that is, one of ``boolean``, ``byte``, ``char``, ``double``, ``float``, ``int``, ``long``, ``short``; QL also classifies ``void`` and ``<nulltype>`` (the type of the ``null`` literal) as primitive types.
- ``PrimitiveType`` represents a `primitive type <https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html>`__, that is, one of ``boolean``, ``byte``, ``char``, ``double``, ``float``, ``int``, ``long``, ``short``; QL also classifies ``void`` and ``<nulltype>`` (the type of the ``null`` literal) as primitive types.
- ``RefType`` represents a reference (that is, non-primitive) type; it in turn has several subclasses:
- ``Class`` represents a Java class.
@@ -68,7 +68,7 @@ For example, the following query finds all variables of type ``int`` in the prog
pt.hasName("int")
select v
`See this in the query console on LGTM.com <https://lgtm.com/query/660700018/>`__. You're likely to get many results when you run this query because most projects contain many variables of type ``int``.
`See this in the query console on LGTM.com <https://lgtm.com/query/860076406167044435/>`__. You're likely to get many results when you run this query because most projects contain many variables of type ``int``.
Reference types are also categorized according to their declaration scope:
@@ -85,15 +85,15 @@ For instance, this query finds all top-level types whose name is not the same as
where tl.getName() != tl.getCompilationUnit().getName()
select tl
`See this in the query console on LGTM.com <https://lgtm.com/query/674620002/>`__. This pattern is seen in many projects. When we ran it on the LGTM.com demo projects, most of the projects had at least one instance of this problem in the source code. There were many more instances in the files referenced by the source code.
`See this in the query console on LGTM.com <https://lgtm.com/query/4340983612585284460/>`__. This pattern is seen in many projects. When we ran it on the LGTM.com demo projects, most of the projects had at least one instance of this problem in the source code. There were many more instances in the files referenced by the source code.
Several more specialized classes are available as well:
- ``TopLevelClass`` represents a class declared at the top-level of a compilation unit.
- ``NestedClass`` represents `a class declared inside another type <http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html>`__, such as:
- ``NestedClass`` represents `a class declared inside another type <https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html>`__, such as:
- A ``LocalClass``, which is `a class declared inside a method or constructor <http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html>`__.
- An ``AnonymousClass``, which is an `anonymous class <http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html>`__.
- A ``LocalClass``, which is `a class declared inside a method or constructor <https://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html>`__.
- An ``AnonymousClass``, which is an `anonymous class <https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html>`__.
Finally, the library also has a number of singleton classes that wrap frequently used Java standard library classes: ``TypeObject``, ``TypeCloneable``, ``TypeRuntime``, ``TypeSerializable``, ``TypeString``, ``TypeSystem`` and ``TypeClass``. Each CodeQL class represents the standard Java class suggested by its name.
@@ -107,7 +107,7 @@ As an example, we can write a query that finds all nested classes that directly
where nc.getASupertype() instanceof TypeObject
select nc
`See this in the query console on LGTM.com <https://lgtm.com/query/672230026/>`__. You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly.
`See this in the query console on LGTM.com <https://lgtm.com/query/8482509736206423238/>`__. You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly.
Generics
~~~~~~~~
@@ -141,7 +141,7 @@ For instance, we could use the following query to find all parameterized instanc
pt.getSourceDeclaration() = map
select pt
`See this in the query console on LGTM.com <https://lgtm.com/query/660700019/>`__. None of the LGTM.com demo projects contain parameterized instances of ``java.util.Map`` in their source code, but they all have results in reference files.
`See this in the query console on LGTM.com <https://lgtm.com/query/7863873821043873550/>`__. None of the LGTM.com demo projects contain parameterized instances of ``java.util.Map`` in their source code, but they all have results in reference files.
In general, generic types may restrict which types a type parameter can be bound to. For instance, a type of maps from strings to numbers could be declared as follows:
@@ -164,7 +164,7 @@ As an example, the following query finds all type variables with type bound ``Nu
tb.getType().hasQualifiedName("java.lang", "Number")
select tv
`See this in the query console on LGTM.com <https://lgtm.com/query/690010016/>`__. When we ran it on the LGTM.com demo projects, the *neo4j/neo4j*, *gradle/gradle* and *hibernate/hibernate-orm* projects all contained examples of this pattern.
`See this in the query console on LGTM.com <https://lgtm.com/query/6740696080876162817/>`__. When we ran it on the LGTM.com demo projects, the *neo4j/neo4j*, *hibernate/hibernate-orm* and *apache/hadoop* projects all contained examples of this pattern.
For dealing with legacy code that is unaware of generics, every generic type has a "raw" version without any type parameters. In the CodeQL libraries, raw types are represented using class ``RawType``, which has the expected subclasses ``RawClass`` and ``RawInterface``. Again, there is a predicate ``getSourceDeclaration`` for obtaining the corresponding generic type. As an example, we can find variables of (raw) type ``Map``:
@@ -177,7 +177,7 @@ For dealing with legacy code that is unaware of generics, every generic type has
rt.getSourceDeclaration().hasQualifiedName("java.util", "Map")
select v
`See this in the query console on LGTM.com <https://lgtm.com/query/686320008/>`__. Many projects have variables of raw type ``Map``.
`See this in the query console on LGTM.com <https://lgtm.com/query/4032913402499547882/>`__. Many projects have variables of raw type ``Map``.
For example, in the following code snippet this query would find ``m1``, but not ``m2``:
@@ -186,7 +186,7 @@ For example, in the following code snippet this query would find ``m1``, but not
Map m1 = new HashMap();
Map<String, String> m2 = new HashMap<String, String>();
Finally, variables can be declared to be of a `wildcard type <http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html>`__:
Finally, variables can be declared to be of a `wildcard type <https://docs.oracle.com/javase/tutorial/java/generics/wildcards.html>`__:
.. code-block:: java
@@ -201,7 +201,7 @@ For more information on working with types, see the :doc:`article on Java types
Variables
~~~~~~~~~
Class ``Variable`` represents a variable `in the Java sense <http://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html>`__, which is either a member field of a class (whether static or not), or a local variable, or a parameter. Consequently, there are three subclasses catering to these special cases:
Class ``Variable`` represents a variable `in the Java sense <https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html>`__, which is either a member field of a class (whether static or not), or a local variable, or a parameter. Consequently, there are three subclasses catering to these special cases:
- ``Field`` represents a Java field.
- ``LocalVariableDecl`` represents a local variable.
@@ -228,7 +228,7 @@ For example, the following query finds all expressions whose parents are ``retur
where e.getParent() instanceof ReturnStmt
select e
`See this in the query console on LGTM.com <https://lgtm.com/query/668700463/>`__. Many projects have examples of ``return`` statements with child statements.
`See this in the query console on LGTM.com <https://lgtm.com/query/1947757851560375919/>`__. Many projects have examples of ``return`` statements with child expressions.
Therefore, if the program contains a return statement ``return x + y;``, this query will return ``x + y``.
@@ -242,7 +242,7 @@ As another example, the following query finds statements whose parent is an ``if
where s.getParent() instanceof IfStmt
select s
`See this in the query console on LGTM.com <https://lgtm.com/query/670720173/>`__. Many projects have examples of ``if`` statements with child statements.
`See this in the query console on LGTM.com <https://lgtm.com/query/1989464153689219612/>`__. Many projects have examples of ``if`` statements with child statements.
This query will find both ``then`` branches and ``else`` branches of all ``if`` statements in the program.
@@ -256,7 +256,7 @@ Finally, here is a query that finds method bodies:
where s.getParent() instanceof Method
select s
`See this in the query console on LGTM.com <https://lgtm.com/query/663740023/>`__. Most projects have many method bodies.
`See this in the query console on LGTM.com <https://lgtm.com/query/1016821702972128245/>`__. Most projects have many method bodies.
As these examples show, the parent node of an expression is not always an expression: it may also be a statement, for example, an ``IfStmt``. Similarly, the parent node of a statement is not always a statement: it may also be a method or a constructor. To capture this, the QL Java library provides two abstract class ``ExprParent`` and ``StmtParent``, the former representing any node that may be the parent node of an expression, and the latter any node that may be the parent node of a statement.
@@ -265,7 +265,7 @@ For more information on working with AST classes, see the :doc:`article on overf
Metadata
--------
Java programs have several kinds of metadata, in addition to the program code proper. In particular, there are `annotations <http://docs.oracle.com/javase/tutorial/java/annotations/>`__ and `Javadoc <http://en.wikipedia.org/wiki/Javadoc>`__ comments. Since this metadata is interesting both for enhancing code analysis and as an analysis subject in its own right, the QL library defines classes for accessing it.
Java programs have several kinds of metadata, in addition to the program code proper. In particular, there are `annotations <https://docs.oracle.com/javase/tutorial/java/annotations/>`__ and `Javadoc <https://en.wikipedia.org/wiki/Javadoc>`__ comments. Since this metadata is interesting both for enhancing code analysis and as an analysis subject in its own right, the QL library defines classes for accessing it.
For annotations, class ``Annotatable`` is a superclass of all program elements that can be annotated. This includes packages, reference types, fields, methods, constructors, and local variable declarations. For every such element, its predicate ``getAnAnnotation`` allows you to retrieve any annotations the element may have. For example, the following query finds all annotations on constructors:
@@ -276,7 +276,7 @@ For annotations, class ``Annotatable`` is a superclass of all program elements t
from Constructor c
select c.getAnAnnotation()
`See this in the query console on LGTM.com <https://lgtm.com/query/665620008/>`__. The LGTM.com demo projects all use annotations, you can see examples where they are used to suppress warnings and mark code as deprecated.
`See this in the query console on LGTM.com <https://lgtm.com/query/3206112561297137365/>`__. The LGTM.com demo projects all use annotations, you can see examples where they are used to suppress warnings and mark code as deprecated.
These annotations are represented by class ``Annotation``. An annotation is simply an expression whose type is an ``AnnotationType``. For example, you can amend this query so that it only reports deprecated constructors:
@@ -290,7 +290,7 @@ These annotations are represented by class ``Annotation``. An annotation is simp
anntp.hasQualifiedName("java.lang", "Deprecated")
select ann
`See this in the query console on LGTM.com <https://lgtm.com/query/659662167/>`__. Only constructors with the ``@deprecated`` annotation are reported this time.
`See this in the query console on LGTM.com <https://lgtm.com/query/5393027107459215059/>`__. Only constructors with the ``@Deprecated`` annotation are reported this time.
For more information on working with annotations, see the :doc:`article on annotations <annotations>`.
@@ -305,7 +305,7 @@ For Javadoc, class ``Element`` has a member predicate ``getDoc`` that returns a
jdoc = f.getDoc().getJavadoc()
select jdoc
`See this in the query console on LGTM.com <https://lgtm.com/query/663330296/>`__. You can see this pattern in many projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/6022769142134600659/>`__. You can see this pattern in many projects.
Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocElement`` nodes, which can be traversed using member predicates ``getAChild`` and ``getParent``. For instance, you could edit the query so that it finds all ``@author`` tags in Javadoc comments on private fields:
@@ -319,7 +319,7 @@ Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocEle
at.getParent+() = jdoc
select at
`See this in the query console on LGTM.com <https://lgtm.com/query/670490015/>`__. None of the LGTM.com demo projects uses the ``@author`` tag on private fields.
`See this in the query console on LGTM.com <https://lgtm.com/query/2510220694395289111/>`__. None of the LGTM.com demo projects uses the ``@author`` tag on private fields.
.. pull-quote::
@@ -336,7 +336,7 @@ The standard QL Java library provides extensive support for computing metrics on
Altogether, there are six such classes: ``MetricElement``, ``MetricPackage``, ``MetricRefType``, ``MetricField``, ``MetricCallable``, and ``MetricStmt``. The corresponding element classes each provide a member predicate ``getMetrics`` that can be used to obtain an instance of the delegate class, on which metric computations can then be performed.
For example, the following query finds methods with a `cyclomatic complexity <http://en.wikipedia.org/wiki/Cyclomatic_complexity>`__ greater than 40:
For example, the following query finds methods with a `cyclomatic complexity <https://en.wikipedia.org/wiki/Cyclomatic_complexity>`__ greater than 40:
.. code-block:: ql
@@ -347,7 +347,7 @@ For example, the following query finds methods with a `cyclomatic complexity <ht
mc.getCyclomaticComplexity() > 40
select m
`See this in the query console on LGTM.com <https://lgtm.com/query/670720174/>`__. Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test.
`See this in the query console on LGTM.com <https://lgtm.com/query/6566950741051181919/>`__. Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test.
Call graph
----------
@@ -367,7 +367,7 @@ We can use predicate ``Call.getCallee`` to find out which method or constructor
m.hasName("println")
select c
`See this in the query console on LGTM.com <https://lgtm.com/query/669220009/>`__. The LGTM.com demo projects all include many calls to methods of this name.
`See this in the query console on LGTM.com <https://lgtm.com/query/5861255162551917595/>`__. The LGTM.com demo projects all include many calls to methods of this name.
Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So we can find methods and constructors that are never called using this query:
@@ -379,7 +379,7 @@ Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So
where not exists(c.getAReference())
select c
`See this in the query console on LGTM.com <https://lgtm.com/query/666680036/>`__. The LGTM.com demo projects all appear to have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see :doc:`Navigating the call graph <call-graph>`.
`See this in the query console on LGTM.com <https://lgtm.com/query/7261739919657747703/>`__. The LGTM.com demo projects all appear to have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see :doc:`Navigating the call graph <call-graph>`.
For more information about callables and calls, see the :doc:`article on the call graph <call-graph>`.

View File

@@ -147,7 +147,7 @@ Now we can write a query for finding all callables ``c`` and ``@throws`` tags ``
not mayThrow(c, exn)
select tt, "Spurious @throws tag."
`See this in the query console on LGTM.com <https://lgtm.com/query/1505752646058/>`__. This finds several results in the LGTM.com demo projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/1258570917227966396/>`__. This finds several results in the LGTM.com demo projects.
Improvements
~~~~~~~~~~~~
@@ -214,7 +214,7 @@ The first case can be covered by changing ``getDocumentedException`` to use the
(result.hasName(tt.getExceptionName()) and visibleIn(tt.getFile(), result))
}
`See this in the query console on LGTM.com <https://lgtm.com/query/1505751136101/>`__. This finds many fewer, more interesting results in the LGTM.com demo projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/8016848987103345329/>`__. This finds many fewer, more interesting results in the LGTM.com demo projects.
Currently, ``visibleIn`` only considers single-type imports, but you could extend it with support for other kinds of imports.

View File

@@ -54,17 +54,17 @@ In our example, the expression statement starts at line 5, column 3 (the first t
Class ``File`` defines these member predicates:
- ``getFullName`` returns the fully qualified name of the file.
- ``getAbsolutePath`` returns the fully qualified name of the file.
- ``getRelativePath`` returns the path of the file relative to the base directory of the source code.
- ``getExtension`` returns the extension of the file.
- ``getShortName`` returns the base name of the file, without its extension.
- ``getStem`` returns the base name of the file, without its extension.
In our example, assume file ``A.java`` is located in directory ``/home/testuser/code/pkg``, where ``/home/testuser/code`` is the base directory of the program being analyzed. Then, a ``File`` object for ``A.java`` returns:
- ``getFullName`` is ``/home/testuser/code/pkg/A.java``.
- ``getAbsolutePath`` is ``/home/testuser/code/pkg/A.java``.
- ``getRelativePath`` is ``pkg/A.java``.
- ``getExtension`` is ``java``.
- ``getShortName`` is ``A``.
- ``getStem`` is ``A``.
Determining white space around an operator
------------------------------------------
@@ -110,7 +110,7 @@ Here's a first version of our query:
wsinner > wsouter
select outer, "Whitespace around nested operators contradicts precedence."
`See this in the query console on LGTM.com <https://lgtm.com/query/672230027/>`__. This query is likely to find results on most projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/8141155897270480914/>`__. This query is likely to find results on most projects.
The first conjunct of the ``where`` clause restricts ``inner`` to be an operand of ``outer``, the second conjunct binds ``wsinner`` and ``wsouter``, while the last conjunct selects the suspicious cases.
@@ -141,9 +141,9 @@ Note that our predicate ``operatorWS`` computes the **total** amount of white sp
wsinner > wsouter
select outer, "Whitespace around nested operators contradicts precedence."
`See this in the query console on LGTM.com <https://lgtm.com/query/665761067/>`__. Any results will be refined by our changes to the query.
`See this in the query console on LGTM.com <https://lgtm.com/query/3151720037708691205/>`__. Any results will be refined by our changes to the query.
Another source of false positives are associative operators: in an expression of the form ``x + y+z``, the first plus is syntactically nested inside the second, since + in Java associates to the left; hence the expression is flagged as suspicious. But since + is associative to begin with, it does not matter which way around the operators are nested, so this is a false positive.To exclude these cases, let us define a new class identifying binary expressions with an associative operator:
Another source of false positives are associative operators: in an expression of the form ``x + y+z``, the first plus is syntactically nested inside the second, since + in Java associates to the left; hence the expression is flagged as suspicious. But since + is associative to begin with, it does not matter which way around the operators are nested, so this is a false positive. To exclude these cases, let us define a new class identifying binary expressions with an associative operator:
.. code-block:: ql
@@ -173,9 +173,9 @@ Now we can extend our query to discard results where the outer and the inner exp
wsinner > wsouter
select outer, "Whitespace around nested operators contradicts precedence."
`See this in the query console on LGTM.com <https://lgtm.com/query/659662169/>`__.
`See this in the query console on LGTM.com <https://lgtm.com/query/5714614966569401039/>`__.
Notice that we again use ``getOp``, this time to determine whether two binary expressions have the same operator. Running our improved query now finds the Java standard library bug described in the Overview. It also flags up the following suspicious code in `Hadoop HBase <http://hbase.apache.org/>`__:
Notice that we again use ``getOp``, this time to determine whether two binary expressions have the same operator. Running our improved query now finds the Java standard library bug described in the Overview. It also flags up the following suspicious code in `Hadoop HBase <https://hbase.apache.org/>`__:
.. code-block:: java

View File

@@ -32,7 +32,7 @@ To determine ancestor types (including immediate super types, and also *their* s
where B.hasName("B")
select B.getASupertype+()
`See this in the query console on LGTM.com <https://lgtm.com/query/674620010/>`__. If this query were run on the example snippet above, the query would return ``A``, ``I``, and ``java.lang.Object``.
`See this in the query console on LGTM.com <https://lgtm.com/query/1506430738755934285/>`__. If this query were run on the example snippet above, the query would return ``A``, ``I``, and ``java.lang.Object``.
.. pull-quote::
@@ -78,7 +78,7 @@ This recipe is not too difficult to translate into a query:
target.getElementType().(RefType).getASupertype+() = source.getElementType()
select ce, "Potentially problematic array downcast."
`See this in the query console on LGTM.com <https://lgtm.com/query/666680038/>`__. Many projects return results for this query.
`See this in the query console on LGTM.com <https://lgtm.com/query/8378564667548381869/>`__. Many projects return results for this query.
Note that by casting ``target.getElementType()`` to a ``RefType``, we eliminate all cases where the element type is a primitive type, that is, ``target`` is an array of primitive type: the problem we are looking for cannot arise in that case. Unlike in Java, a cast in QL never fails: if an expression cannot be cast to the desired type, it is simply excluded from the query results, which is exactly what we want.
@@ -97,7 +97,7 @@ In code that does not use generics, this method is often used in the following w
Here, ``l`` has the raw type ``List``, so ``l.toArray`` has return type ``Object[]``, independent of the type of its argument array. Hence the cast goes from ``Object[]`` to ``A[]`` and will be flagged as problematic by our query, although at runtime this cast can never go wrong.
To identify these cases, we can create two CodeQL classes that represent, respectively, the ``Collection.toArray`` class, and calls to this method or any method that overrides it:
To identify these cases, we can create two CodeQL classes that represent, respectively, the ``Collection.toArray`` method, and calls to this method or any method that overrides it:
.. code-block:: ql
@@ -148,7 +148,7 @@ Example: Finding mismatched contains checks
We'll now develop a query that finds uses of ``Collection.contains`` where the type of the queried element is unrelated to the element type of the collection, which guarantees that the test will always return ``false``.
For example, `Apache Zookeeper <http://zookeeper.apache.org/>`__ used to have a snippet of code similar to the following in class ``QuorumPeerConfig``:
For example, `Apache Zookeeper <https://zookeeper.apache.org/>`__ used to have a snippet of code similar to the following in class ``QuorumPeerConfig``:
.. code-block:: java
@@ -267,7 +267,7 @@ Now we are ready to write a first version of our query:
not haveCommonDescendant(collEltType, argType)
select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType
`See this in the query console on LGTM.com <https://lgtm.com/query/1505750556420/>`__.
`See this in the query console on LGTM.com <https://lgtm.com/query/7947831380785106258/>`__.
Improvements
~~~~~~~~~~~~
@@ -294,7 +294,7 @@ Adding these three improvements, our final query becomes:
not argType.hasName("<nulltype>")
select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType
`See the full query in the query console on LGTM.com <https://lgtm.com/query/1505753056300/>`__.
`See the full query in the query console on LGTM.com <https://lgtm.com/query/8846334903769538099/>`__.
Further reading
---------------

View File

@@ -90,16 +90,16 @@ class Top extends @top {
/** A location maps language elements to positions in source files. */
class Location extends @location {
/** Gets the line number where this location starts. */
/** Gets the 1-based line number (inclusive) where this location starts. */
int getStartLine() { locations_default(this, _, result, _, _, _) }
/** Gets the column number where this location starts. */
/** Gets the 1-based column number (inclusive) where this location starts. */
int getStartColumn() { locations_default(this, _, _, result, _, _) }
/** Gets the line number where this location ends. */
/** Gets the 1-based line number (inclusive) where this location ends. */
int getEndLine() { locations_default(this, _, _, _, result, _) }
/** Gets the column number where this location ends. */
/** Gets the 1-based column number (inclusive) where this location ends. */
int getEndColumn() { locations_default(this, _, _, _, _, result) }
/**

View File

@@ -60,6 +60,12 @@ class Expr extends ExprParent, @expr {
/** Gets the statement containing this expression, if any. */
Stmt getEnclosingStmt() { statementEnclosingExpr(this, result) }
/**
* Gets a statement that directly or transitively contains this expression, if any.
* This is equivalent to `this.getEnclosingStmt().getEnclosingStmt*()`.
*/
Stmt getAnEnclosingStmt() { result = this.getEnclosingStmt().getEnclosingStmt*() }
/** Gets a child of this expression. */
Expr getAChildExpr() { exprs(result, _, _, this, _) }
@@ -1237,7 +1243,7 @@ class VariableAssign extends VariableUpdate {
}
/**
* Gets the source of this assignment, if any.
* Gets the source (right-hand side) of this assignment, if any.
*
* An initialization in a `CatchClause` or `EnhancedForStmt` is implicit and
* does not have a source.

View File

@@ -79,7 +79,7 @@ abstract class JavadocElement extends @javadocElement, Top {
abstract string getText();
}
/** A Javadoc tag. */
/** A Javadoc block tag. This does not include inline tags. */
class JavadocTag extends JavadocElement, JavadocParent, @javadocTag {
/** Gets the name of this Javadoc tag. */
string getTagName() { javadocTag(this, result, _, _) }

View File

@@ -196,6 +196,12 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
method.hasName("entry") and
arg = 1
)
or
method.getDeclaringType().hasQualifiedName("java.util", "Arrays") and
(
method.hasName(["copyOf", "copyOfRange", "spliterator", "stream"]) and
arg = 0
)
}
/**
@@ -223,6 +229,13 @@ private predicate taintPreservingArgToArg(Method method, int input, int output)
or
method.hasName("replaceAll") and input = 2 and output = 0
)
or
method.getDeclaringType().hasQualifiedName("java.util", "Arrays") and
(
method.hasName("fill") and
output = 0 and
input = method.getNumberOfParameters() - 1
)
}
private predicate argToQualifierStep(Expr tracked, Expr sink) {
@@ -236,9 +249,18 @@ private predicate argToQualifierStep(Expr tracked, Expr sink) {
/** Access to a method that passes taint from an argument. */
private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
exists(int i |
taintPreservingArgumentToMethod(sink.getMethod(), i) and
tracked = sink.getArgument(i)
exists(Method m |
m = sink.getMethod() and
(
exists(int i |
taintPreservingArgumentToMethod(m, i) and
tracked = sink.getArgument(i)
)
or
m.getDeclaringType().hasQualifiedName("java.util", "Arrays") and
m.hasName("asList") and
tracked = sink.getAnArgument()
)
)
or
taintPreservingArgumentToMethod(sink.getMethod()) and

View File

@@ -9,9 +9,9 @@ private predicate fileRead(VarAccess fileAccess, Expr fileReadingExpr) {
cie = fileReadingExpr and
cie.getArgument(0) = fileAccess
|
cie.getConstructedType().hasQualifiedName("java.io", "RandomAccessFile") or
cie.getConstructedType().hasQualifiedName("java.io", "FileReader") or
cie.getConstructedType().hasQualifiedName("java.io", "FileInputStream")
cie
.getConstructedType()
.hasQualifiedName("java.io", ["RandomAccessFile", "FileReader", "FileInputStream"])
)
or
exists(MethodAccess ma, Method filesMethod |
@@ -22,13 +22,9 @@ private predicate fileRead(VarAccess fileAccess, Expr fileReadingExpr) {
// represented by the first argument.
filesMethod.getDeclaringType().hasQualifiedName("java.nio.file", "Files") and
fileAccess = ma.getArgument(0) and
(
filesMethod.hasName("readAllBytes") or
filesMethod.hasName("readAllLines") or
filesMethod.hasName("newBufferedReader") or
filesMethod.hasName("newInputReader") or
filesMethod.hasName("newByteChannel")
)
filesMethod
.hasName(["readAllBytes", "readAllLines", "readString", "lines", "newBufferedReader",
"newInputStream", "newByteChannel"])
)
)
or

View File

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

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../stubs/spring-ldap-2.3.2
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../../stubs/spring-ldap-2.3.2

View File

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

View File

@@ -1,4 +0,0 @@
package org.springframework.ldap.core;
public interface ContextMapper<T> {
}

View File

@@ -1,4 +0,0 @@
package org.springframework.ldap.core;
public interface DirContextOperations {
}

View File

@@ -1,76 +0,0 @@
package org.springframework.ldap.core;
import org.springframework.beans.factory.InitializingBean;
import java.util.*;
import javax.naming.Name;
import javax.naming.directory.SearchControls;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.query.LdapQuery;
public class LdapTemplate implements LdapOperations, InitializingBean {
public void authenticate(LdapQuery query, String password) { }
public boolean authenticate(Name base, String filter, String password) { return true; }
public <T> List<T> find(Name base, Filter filter, SearchControls searchControls, final Class<T> clazz) { return null; }
public <T> List<T> find(LdapQuery query, Class<T> clazz) { return null; }
public <T> T findOne(LdapQuery query, Class<T> clazz) { return null; }
public void search(String base, String filter, int searchScope, boolean returningObjFlag, NameClassPairCallbackHandler handler) { }
public void search(final String base, final String filter, final SearchControls controls, NameClassPairCallbackHandler handler) {}
public void search(final String base, final String filter, final SearchControls controls, NameClassPairCallbackHandler handler, DirContextProcessor processor) {}
public void search(String base, String filter, NameClassPairCallbackHandler handler) {}
public <T> List<T> search(String base, String filter, int searchScope, String[] attrs, AttributesMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, int searchScope, AttributesMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, AttributesMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, int searchScope, String[] attrs, ContextMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, int searchScope, ContextMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, ContextMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, SearchControls controls, ContextMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, SearchControls controls, AttributesMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, SearchControls controls, AttributesMapper<T> mapper, DirContextProcessor processor) { return null; }
public <T> List<T> search(String base, String filter, SearchControls controls, ContextMapper<T> mapper, DirContextProcessor processor) { return null; }
public DirContextOperations searchForContext(LdapQuery query) { return null; }
public <T> T searchForObject(Name base, String filter, ContextMapper<T> mapper) { return null; }
public <T> T searchForObject(String base, String filter, ContextMapper<T> mapper) { return null; }
public <T> T searchForObject(String base, String filter, SearchControls searchControls, ContextMapper<T> mapper) { return null; }
public Object lookup(final String dn) { return new Object(); }
public DirContextOperations lookupContext(String dn) { return null; }
public <T> T findByDn(Name dn, final Class<T> clazz) { return null; }
public void rename(final Name oldDn, final Name newDn) {}
public List<String> list(final Name base) { return null; }
public List<String> listBindings(final Name base) { return null; }
public void unbind(final String dn) {}
public void unbind(final String dn, boolean recursive) {}
}

View File

@@ -1,3 +0,0 @@
package org.springframework.ldap.core;
public interface NameClassPairCallbackHandler { }

View File

@@ -1,5 +0,0 @@
package org.springframework.ldap.filter;
public class EqualsFilter implements Filter {
public EqualsFilter(String attribute, String value) { }
}

View File

@@ -1,4 +0,0 @@
package org.springframework.ldap.filter;
public interface Filter {
}

View File

@@ -1,7 +0,0 @@
package org.springframework.ldap.filter;
public class HardcodedFilter implements Filter {
public HardcodedFilter(String filter) { }
public StringBuffer encode(StringBuffer buff) { return buff; }
public String toString() { return ""; }
}

View File

@@ -1,5 +0,0 @@
package org.springframework.ldap.query;
public interface ConditionCriteria {
ContainerCriteria is(String value);
}

View File

@@ -1,4 +0,0 @@
package org.springframework.ldap.query;
public interface ContainerCriteria extends LdapQuery {
}

View File

@@ -1,4 +0,0 @@
package org.springframework.ldap.query;
public interface LdapQuery {
}

View File

@@ -1,14 +0,0 @@
package org.springframework.ldap.query;
import javax.naming.Name;
import org.springframework.ldap.filter.Filter;
public class LdapQueryBuilder {
public static LdapQueryBuilder query() { return null; }
public LdapQuery filter(String hardcodedFilter) { return null; }
public LdapQuery filter(Filter filter) { return null; }
public LdapQuery filter(String filterFormat, Object... params) { return null; }
public LdapQueryBuilder base(String baseDn) { return this; }
public Name base() { return null; }
public ConditionCriteria where(String attribute) { return null; }
}

View File

@@ -1,5 +0,0 @@
package org.springframework.ldap.support;
public class LdapEncoder {
public static String filterEncode(String value) { return null; }
}

View File

@@ -1,12 +0,0 @@
package org.springframework.ldap.support;
import javax.naming.ldap.LdapName;
public class LdapNameBuilder {
public static LdapNameBuilder newInstance() { return null; }
public static LdapNameBuilder newInstance(String name) { return null; }
public LdapNameBuilder add(String name) { return null; }
public LdapNameBuilder add(String key, Object value) { return null; }
public LdapName build() { return null; }
}

View File

@@ -1,7 +0,0 @@
package org.springframework.ldap.support;
import javax.naming.ldap.LdapName;
public class LdapUtils {
public static LdapName newLdapName(String distinguishedName) { return null; }
}

View File

@@ -1,8 +0,0 @@
package org.springframework.web.bind.annotation;
import java.lang.annotation.*;
@Target(value=ElementType.PARAMETER)
@Retention(value=RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam { }

View File

@@ -0,0 +1,23 @@
import java.util.Arrays;
import java.util.List;
class ArraysTest {
public static void taintSteps(String[] source) {
Arrays.asList();
Arrays.asList("one");
Arrays.asList("two", "three");
Arrays.copyOf(source, 10);
Arrays.copyOfRange(source, 0, 10);
Arrays.deepToString(source);
Arrays.spliterator(source);
Arrays.stream(source);
Arrays.toString(source);
Arrays.fill(source, "value");
Arrays.fill(source, 0, 10, "data");
Arrays.parallelPrefix(source, (x, y) -> x + y);
Arrays.parallelPrefix(source, 0, 10, (x, y) -> x + y);
Arrays.parallelSetAll(source, x -> Integer.toString(x));
Arrays.setAll(source, x -> Integer.toString(x));
}
}

View File

@@ -1,3 +1,23 @@
| ArraysTest.java:7:17:7:21 | "one" | ArraysTest.java:7:3:7:22 | asList(...) |
| ArraysTest.java:7:17:7:21 | "one" | ArraysTest.java:7:3:7:22 | new ..[] { .. } |
| ArraysTest.java:8:17:8:21 | "two" | ArraysTest.java:8:3:8:31 | asList(...) |
| ArraysTest.java:8:17:8:21 | "two" | ArraysTest.java:8:3:8:31 | new ..[] { .. } |
| ArraysTest.java:8:24:8:30 | "three" | ArraysTest.java:8:3:8:31 | asList(...) |
| ArraysTest.java:8:24:8:30 | "three" | ArraysTest.java:8:3:8:31 | new ..[] { .. } |
| ArraysTest.java:9:17:9:22 | source | ArraysTest.java:9:3:9:27 | copyOf(...) |
| ArraysTest.java:10:22:10:27 | source | ArraysTest.java:10:3:10:35 | copyOfRange(...) |
| ArraysTest.java:12:22:12:27 | source | ArraysTest.java:12:3:12:28 | spliterator(...) |
| ArraysTest.java:13:17:13:22 | source | ArraysTest.java:13:3:13:23 | stream(...) |
| ArraysTest.java:15:23:15:29 | "value" | ArraysTest.java:15:15:15:20 | source [post update] |
| ArraysTest.java:16:30:16:35 | "data" | ArraysTest.java:16:15:16:20 | source [post update] |
| ArraysTest.java:17:43:17:43 | x | ArraysTest.java:17:43:17:47 | ... + ... |
| ArraysTest.java:17:47:17:47 | y | ArraysTest.java:17:43:17:47 | ... + ... |
| ArraysTest.java:18:50:18:50 | x | ArraysTest.java:18:50:18:54 | ... + ... |
| ArraysTest.java:18:54:18:54 | y | ArraysTest.java:18:50:18:54 | ... + ... |
| ArraysTest.java:19:38:19:44 | Integer | ArraysTest.java:19:38:19:56 | toString(...) |
| ArraysTest.java:19:55:19:55 | x | ArraysTest.java:19:38:19:56 | toString(...) |
| ArraysTest.java:20:30:20:36 | Integer | ArraysTest.java:20:30:20:48 | toString(...) |
| ArraysTest.java:20:47:20:47 | x | ArraysTest.java:20:30:20:48 | toString(...) |
| CollectionsTest.java:10:28:10:32 | "one" | CollectionsTest.java:10:3:10:33 | new ..[] { .. } |
| CollectionsTest.java:10:28:10:32 | "one" | CollectionsTest.java:10:22:10:25 | list [post update] |
| CollectionsTest.java:11:28:11:32 | "two" | CollectionsTest.java:11:3:11:42 | new ..[] { .. } |

View File

@@ -1,5 +1,7 @@
package org.springframework.ldap.core;
import org.springframework.beans.factory.InitializingBean;
import java.util.*;
import javax.naming.Name;
@@ -9,7 +11,7 @@ import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.query.LdapQuery;
public class LdapTemplate {
public class LdapTemplate implements LdapOperations, InitializingBean {
public void authenticate(LdapQuery query, String password) { }
public boolean authenticate(Name base, String filter, String password) { return true; }
@@ -22,7 +24,53 @@ public class LdapTemplate {
public void search(String base, String filter, int searchScope, boolean returningObjFlag, NameClassPairCallbackHandler handler) { }
public void search(final String base, final String filter, final SearchControls controls, NameClassPairCallbackHandler handler) {}
public void search(final String base, final String filter, final SearchControls controls, NameClassPairCallbackHandler handler, DirContextProcessor processor) {}
public void search(String base, String filter, NameClassPairCallbackHandler handler) {}
public <T> List<T> search(String base, String filter, int searchScope, String[] attrs, AttributesMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, int searchScope, AttributesMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, AttributesMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, int searchScope, String[] attrs, ContextMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, int searchScope, ContextMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, ContextMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, SearchControls controls, ContextMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, SearchControls controls, AttributesMapper<T> mapper) { return null; }
public <T> List<T> search(String base, String filter, SearchControls controls, AttributesMapper<T> mapper, DirContextProcessor processor) { return null; }
public <T> List<T> search(String base, String filter, SearchControls controls, ContextMapper<T> mapper, DirContextProcessor processor) { return null; }
public DirContextOperations searchForContext(LdapQuery query) { return null; }
public <T> T searchForObject(Name base, String filter, ContextMapper<T> mapper) { return null; }
public <T> T searchForObject(String base, String filter, ContextMapper<T> mapper) { return null; }
public <T> T searchForObject(String base, String filter, SearchControls searchControls, ContextMapper<T> mapper) { return null; }
public Object lookup(final String dn) { return new Object(); }
public DirContextOperations lookupContext(String dn) { return null; }
public <T> T findByDn(Name dn, final Class<T> clazz) { return null; }
public void rename(final Name oldDn, final Name newDn) {}
public List<String> list(final Name base) { return null; }
public List<String> listBindings(final Name base) { return null; }
public void unbind(final String dn) {}
public void unbind(final String dn, boolean recursive) {}
}

View File

@@ -18,6 +18,6 @@ import DataFlow::PathGraph
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode
where cfg.hasFlowPath(source, sink) and sinkNode = sink.getNode()
select sinkNode.getAlertLocation(), source, sink, "$@ based on libary input is later used in $@.",
select sinkNode.getAlertLocation(), source, sink, "$@ based on library input is later used in $@.",
sinkNode.getAlertLocation(), sinkNode.getSinkType(), sinkNode.getCommandExecution(),
"shell command"

View File

@@ -1,3 +1,3 @@
<img alt="
<div alt="
<x" title="></x" >
<img src=url404 onerror=alert(1)>"/>

View File

@@ -12,16 +12,16 @@ class Location extends @location {
/** Gets the file for this location. */
File getFile() { locations_default(this, result, _, _, _, _) }
/** Gets the start line of this location. */
/** Gets the 1-based line number (inclusive) where this location starts. */
int getStartLine() { locations_default(this, _, result, _, _, _) }
/** Gets the start column of this location. */
/** Gets the 1-based column number (inclusive) where this location starts. */
int getStartColumn() { locations_default(this, _, _, result, _, _) }
/** Gets the end line of this location. */
/** Gets the 1-based line number (inclusive) where this location ends. */
int getEndLine() { locations_default(this, _, _, _, result, _) }
/** Gets the end column of this location. */
/** Gets the 1-based column number (inclusive) where this location ends. */
int getEndColumn() { locations_default(this, _, _, _, _, result) }
/** Gets the number of lines covered by this location. */

View File

@@ -463,6 +463,26 @@ module Express {
override RequestSource src;
}
/**
* Gets a reference to the "query" object from a request-object originating from route-handler `rh`.
*/
DataFlow::SourceNode getAQueryObjectReference(DataFlow::TypeTracker t, RouteHandler rh) {
t.startInProp("query") and
result = rh.getARequestSource()
or
exists(DataFlow::TypeTracker t2 | result = getAQueryObjectReference(t2, rh).track(t2, t))
}
/**
* Gets a reference to the "params" object from a request-object originating from route-handler `rh`.
*/
DataFlow::SourceNode getAParamsObjectReference(DataFlow::TypeTracker t, RouteHandler rh) {
t.startInProp("params") and
result = rh.getARequestSource()
or
exists(DataFlow::TypeTracker t2 | result = getAParamsObjectReference(t2, rh).track(t2, t))
}
/**
* An access to a user-controlled Express request input.
*/
@@ -471,13 +491,14 @@ module Express {
string kind;
RequestInputAccess() {
kind = "parameter" and
this =
[getAQueryObjectReference(DataFlow::TypeTracker::end(), rh),
getAParamsObjectReference(DataFlow::TypeTracker::end(), rh)].getAPropertyRead()
or
exists(DataFlow::SourceNode request | request = rh.getARequestSource().ref() |
kind = "parameter" and
(
this = request.getAMethodCall("param")
or
this = request.getAPropertyRead(["params", "query"]).getAPropertyRead()
)
this = request.getAMethodCall("param")
or
// `req.originalUrl`
kind = "url" and
@@ -518,13 +539,11 @@ module Express {
kind = "parameter" and
exists(DataFlow::Node request | request = DataFlow::valueNode(rh.getARequestExpr()) |
this.(DataFlow::MethodCallNode).calls(request, "param")
or
exists(DataFlow::PropRead base |
// `req.query.name`
base.accesses(request, "query") and
this = base.getAPropertyReference(_)
)
)
or
// `req.query.name`
kind = "parameter" and
this = getAQueryObjectReference(DataFlow::TypeTracker::end(), rh).getAPropertyRead()
}
}

View File

@@ -50,5 +50,9 @@ module ClientSideUrlRedirect {
g instanceof DocumentUrl and
succ.(DataFlow::PropRead).accesses(pred, "href")
}
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
guard instanceof HostnameSanitizerGuard
}
}
}

View File

@@ -6,7 +6,7 @@
import javascript
import semmle.javascript.security.dataflow.RemoteFlowSources
import UrlConcatenation
private import UrlConcatenation
module ClientSideUrlRedirect {
private import Xss::DomBasedXss as DomBasedXss

View File

@@ -34,7 +34,8 @@ module ServerSideUrlRedirect {
}
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
guard instanceof LocalUrlSanitizingGuard
guard instanceof LocalUrlSanitizingGuard or
guard instanceof HostnameSanitizerGuard
}
}
}

View File

@@ -6,7 +6,7 @@
import javascript
import RemoteFlowSources
import UrlConcatenation
private import UrlConcatenation
module ServerSideUrlRedirect {
/**

View File

@@ -96,3 +96,15 @@ predicate hostnameSanitizingPrefixEdge(DataFlow::Node source, DataFlow::Node sin
hasHostnameSanitizingSubstring(StringConcatenation::getOperand(operator, [0 .. n - 1]))
)
}
/**
* A check that sanitizes the hostname of a URL.
*/
class HostnameSanitizerGuard extends TaintTracking::SanitizerGuardNode, StringOps::StartsWith {
HostnameSanitizerGuard() { hasHostnameSanitizingSubstring(getSubstring()) }
override predicate sanitizes(boolean outcome, Expr e) {
outcome = getPolarity() and
e = getBaseString().asExpr()
}
}

View File

@@ -389,55 +389,55 @@ edges
| lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name |
| lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name |
#select
| lib/lib2.js:4:10:4:25 | "rm -rf " + name | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | $@ based on libary input is later used in $@. | lib/lib2.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/lib2.js:4:2:4:26 | cp.exec ... + name) | shell command |
| lib/lib2.js:8:10:8:25 | "rm -rf " + name | lib/lib2.js:7:32:7:35 | name | lib/lib2.js:8:22:8:25 | name | $@ based on libary input is later used in $@. | lib/lib2.js:8:10:8:25 | "rm -rf " + name | String concatenation | lib/lib2.js:8:2:8:26 | cp.exec ... + name) | shell command |
| lib/lib.js:4:10:4:25 | "rm -rf " + name | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:22:4:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/lib.js:4:2:4:26 | cp.exec ... + name) | shell command |
| lib/lib.js:11:10:11:25 | "rm -rf " + name | lib/lib.js:10:32:10:35 | name | lib/lib.js:11:22:11:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:11:10:11:25 | "rm -rf " + name | String concatenation | lib/lib.js:11:2:11:26 | cp.exec ... + name) | shell command |
| lib/lib.js:15:10:15:25 | "rm -rf " + name | lib/lib.js:14:36:14:39 | name | lib/lib.js:15:22:15:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:15:10:15:25 | "rm -rf " + name | String concatenation | lib/lib.js:15:2:15:26 | cp.exec ... + name) | shell command |
| lib/lib.js:20:10:20:25 | "rm -rf " + name | lib/lib.js:19:34:19:37 | name | lib/lib.js:20:22:20:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:20:10:20:25 | "rm -rf " + name | String concatenation | lib/lib.js:20:2:20:26 | cp.exec ... + name) | shell command |
| lib/lib.js:27:10:27:25 | "rm -rf " + name | lib/lib.js:26:35:26:38 | name | lib/lib.js:27:22:27:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:27:10:27:25 | "rm -rf " + name | String concatenation | lib/lib.js:27:2:27:26 | cp.exec ... + name) | shell command |
| lib/lib.js:35:11:35:26 | "rm -rf " + name | lib/lib.js:34:14:34:17 | name | lib/lib.js:35:23:35:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:35:11:35:26 | "rm -rf " + name | String concatenation | lib/lib.js:35:3:35:27 | cp.exec ... + name) | shell command |
| lib/lib.js:38:11:38:26 | "rm -rf " + name | lib/lib.js:37:13:37:16 | name | lib/lib.js:38:23:38:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:38:11:38:26 | "rm -rf " + name | String concatenation | lib/lib.js:38:3:38:27 | cp.exec ... + name) | shell command |
| lib/lib.js:41:11:41:26 | "rm -rf " + name | lib/lib.js:40:6:40:9 | name | lib/lib.js:41:23:41:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:41:11:41:26 | "rm -rf " + name | String concatenation | lib/lib.js:41:3:41:27 | cp.exec ... + name) | shell command |
| lib/lib.js:50:35:50:50 | "rm -rf " + name | lib/lib.js:49:31:49:34 | name | lib/lib.js:50:47:50:50 | name | $@ based on libary input is later used in $@. | lib/lib.js:50:35:50:50 | "rm -rf " + name | String concatenation | lib/lib.js:50:2:50:51 | require ... + name) | shell command |
| lib/lib.js:54:13:54:28 | "rm -rf " + name | lib/lib.js:53:33:53:36 | name | lib/lib.js:54:25:54:28 | name | $@ based on libary input is later used in $@. | lib/lib.js:54:13:54:28 | "rm -rf " + name | String concatenation | lib/lib.js:55:2:55:14 | cp.exec(cmd1) | shell command |
| lib/lib.js:57:13:57:28 | "rm -rf " + name | lib/lib.js:53:33:53:36 | name | lib/lib.js:57:25:57:28 | name | $@ based on libary input is later used in $@. | lib/lib.js:57:13:57:28 | "rm -rf " + name | String concatenation | lib/lib.js:59:3:59:14 | cp.exec(cmd) | shell command |
| lib/lib.js:65:10:65:25 | "rm -rf " + name | lib/lib.js:64:41:64:44 | name | lib/lib.js:65:22:65:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:65:10:65:25 | "rm -rf " + name | String concatenation | lib/lib.js:65:2:65:26 | cp.exec ... + name) | shell command |
| lib/lib.js:71:10:71:31 | "cat /f ... + name | lib/lib.js:64:41:64:44 | name | lib/lib.js:71:28:71:31 | name | $@ based on libary input is later used in $@. | lib/lib.js:71:10:71:31 | "cat /f ... + name | String concatenation | lib/lib.js:71:2:71:32 | cp.exec ... + name) | shell command |
| lib/lib.js:73:10:73:31 | "cat \\" ... + "\\"" | lib/lib.js:64:41:64:44 | name | lib/lib.js:73:21:73:24 | name | $@ based on libary input is later used in $@. | lib/lib.js:73:10:73:31 | "cat \\" ... + "\\"" | String concatenation | lib/lib.js:73:2:73:32 | cp.exec ... + "\\"") | shell command |
| lib/lib.js:75:10:75:29 | "cat '" + name + "'" | lib/lib.js:64:41:64:44 | name | lib/lib.js:75:20:75:23 | name | $@ based on libary input is later used in $@. | lib/lib.js:75:10:75:29 | "cat '" + name + "'" | String concatenation | lib/lib.js:75:2:75:30 | cp.exec ... + "'") | shell command |
| lib/lib.js:77:10:77:37 | "cat '/ ... e + "'" | lib/lib.js:64:41:64:44 | name | lib/lib.js:77:28:77:31 | name | $@ based on libary input is later used in $@. | lib/lib.js:77:10:77:37 | "cat '/ ... e + "'" | String concatenation | lib/lib.js:77:2:77:38 | cp.exec ... + "'") | shell command |
| lib/lib.js:83:10:83:25 | "rm -rf " + name | lib/lib.js:82:35:82:38 | name | lib/lib.js:83:22:83:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:83:10:83:25 | "rm -rf " + name | String concatenation | lib/lib.js:83:2:83:26 | cp.exec ... + name) | shell command |
| lib/lib.js:86:13:86:16 | name | lib/lib.js:82:35:82:38 | name | lib/lib.js:86:13:86:16 | name | $@ based on libary input is later used in $@. | lib/lib.js:86:13:86:16 | name | Array element | lib/lib.js:87:2:87:25 | cp.exec ... n(" ")) | shell command |
| lib/lib.js:89:21:89:24 | name | lib/lib.js:82:35:82:38 | name | lib/lib.js:89:21:89:24 | name | $@ based on libary input is later used in $@. | lib/lib.js:89:21:89:24 | name | Array element | lib/lib.js:89:2:89:36 | cp.exec ... n(" ")) | shell command |
| lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | lib/lib.js:82:35:82:38 | name | lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | $@ based on libary input is later used in $@. | lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | Array element | lib/lib.js:91:2:91:50 | cp.exec ... n(" ")) | shell command |
| lib/lib.js:98:35:98:38 | name | lib/lib.js:97:35:97:38 | name | lib/lib.js:98:35:98:38 | name | $@ based on libary input is later used in $@. | lib/lib.js:98:35:98:38 | name | Formatted string | lib/lib.js:98:2:98:40 | cp.exec ... name)) | shell command |
| lib/lib.js:100:37:100:40 | name | lib/lib.js:97:35:97:38 | name | lib/lib.js:100:37:100:40 | name | $@ based on libary input is later used in $@. | lib/lib.js:100:37:100:40 | name | Formatted string | lib/lib.js:100:2:100:42 | cp.exec ... name)) | shell command |
| lib/lib.js:102:46:102:49 | name | lib/lib.js:97:35:97:38 | name | lib/lib.js:102:46:102:49 | name | $@ based on libary input is later used in $@. | lib/lib.js:102:46:102:49 | name | Formatted string | lib/lib.js:102:2:102:51 | cp.exec ... name)) | shell command |
| lib/lib.js:108:41:108:44 | name | lib/lib.js:97:35:97:38 | name | lib/lib.js:108:41:108:44 | name | $@ based on libary input is later used in $@. | lib/lib.js:108:41:108:44 | name | Formatted string | lib/lib.js:108:2:108:46 | cp.exec ... name)) | shell command |
| lib/lib.js:112:10:112:25 | "rm -rf " + name | lib/lib.js:111:34:111:37 | name | lib/lib.js:112:22:112:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:112:10:112:25 | "rm -rf " + name | String concatenation | lib/lib.js:112:2:112:26 | cp.exec ... + name) | shell command |
| lib/lib.js:121:10:121:25 | "rm -rf " + name | lib/lib.js:120:33:120:36 | name | lib/lib.js:121:22:121:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:121:10:121:25 | "rm -rf " + name | String concatenation | lib/lib.js:121:2:121:26 | cp.exec ... + name) | shell command |
| lib/lib.js:131:11:131:26 | "rm -rf " + name | lib/lib.js:130:6:130:9 | name | lib/lib.js:131:23:131:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:131:11:131:26 | "rm -rf " + name | String concatenation | lib/lib.js:131:3:131:27 | cp.exec ... + name) | shell command |
| lib/lib.js:149:12:149:27 | "rm -rf " + name | lib/lib.js:148:37:148:40 | name | lib/lib.js:149:24:149:27 | name | $@ based on libary input is later used in $@. | lib/lib.js:149:12:149:27 | "rm -rf " + name | String concatenation | lib/lib.js:152:2:152:23 | cp.spaw ... gs, cb) | shell command |
| lib/lib.js:161:13:161:28 | "rm -rf " + name | lib/lib.js:155:38:155:41 | name | lib/lib.js:161:25:161:28 | name | $@ based on libary input is later used in $@. | lib/lib.js:161:13:161:28 | "rm -rf " + name | String concatenation | lib/lib.js:163:2:167:2 | cp.spaw ... t' }\\n\\t) | shell command |
| lib/lib.js:173:10:173:23 | "fo \| " + name | lib/lib.js:170:41:170:44 | name | lib/lib.js:173:20:173:23 | name | $@ based on libary input is later used in $@. | lib/lib.js:173:10:173:23 | "fo \| " + name | String concatenation | lib/lib.js:173:2:173:24 | cp.exec ... + name) | shell command |
| lib/lib.js:182:10:182:27 | "rm -rf " + broken | lib/lib.js:177:38:177:41 | name | lib/lib.js:182:22:182:27 | broken | $@ based on libary input is later used in $@. | lib/lib.js:182:10:182:27 | "rm -rf " + broken | String concatenation | lib/lib.js:182:2:182:28 | cp.exec ... broken) | shell command |
| lib/lib.js:187:10:187:25 | "rm -rf " + name | lib/lib.js:186:34:186:37 | name | lib/lib.js:187:22:187:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:187:10:187:25 | "rm -rf " + name | String concatenation | lib/lib.js:187:2:187:26 | cp.exec ... + name) | shell command |
| lib/lib.js:190:11:190:26 | "rm -rf " + name | lib/lib.js:186:34:186:37 | name | lib/lib.js:190:23:190:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:190:11:190:26 | "rm -rf " + name | String concatenation | lib/lib.js:190:3:190:27 | cp.exec ... + name) | shell command |
| lib/lib.js:197:10:197:25 | "rm -rf " + name | lib/lib.js:196:45:196:48 | name | lib/lib.js:197:22:197:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:197:10:197:25 | "rm -rf " + name | String concatenation | lib/lib.js:197:2:197:26 | cp.exec ... + name) | shell command |
| lib/lib.js:200:11:200:26 | "rm -rf " + name | lib/lib.js:196:45:196:48 | name | lib/lib.js:200:23:200:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:200:11:200:26 | "rm -rf " + name | String concatenation | lib/lib.js:200:3:200:27 | cp.exec ... + name) | shell command |
| lib/lib.js:207:10:207:25 | "rm -rf " + name | lib/lib.js:206:45:206:48 | name | lib/lib.js:207:22:207:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:207:10:207:25 | "rm -rf " + name | String concatenation | lib/lib.js:207:2:207:26 | cp.exec ... + name) | shell command |
| lib/lib.js:212:11:212:26 | "rm -rf " + name | lib/lib.js:206:45:206:48 | name | lib/lib.js:212:23:212:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:212:11:212:26 | "rm -rf " + name | String concatenation | lib/lib.js:212:3:212:27 | cp.exec ... + name) | shell command |
| lib/lib.js:217:10:217:25 | "rm -rf " + name | lib/lib.js:216:39:216:42 | name | lib/lib.js:217:22:217:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:217:10:217:25 | "rm -rf " + name | String concatenation | lib/lib.js:217:2:217:26 | cp.exec ... + name) | shell command |
| lib/lib.js:220:11:220:26 | "rm -rf " + name | lib/lib.js:216:39:216:42 | name | lib/lib.js:220:23:220:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:220:11:220:26 | "rm -rf " + name | String concatenation | lib/lib.js:220:3:220:27 | cp.exec ... + name) | shell command |
| lib/lib.js:224:10:224:25 | "rm -rf " + name | lib/lib.js:216:39:216:42 | name | lib/lib.js:224:22:224:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:224:10:224:25 | "rm -rf " + name | String concatenation | lib/lib.js:224:2:224:26 | cp.exec ... + name) | shell command |
| lib/lib.js:228:10:228:25 | "rm -rf " + name | lib/lib.js:227:39:227:42 | name | lib/lib.js:228:22:228:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:228:10:228:25 | "rm -rf " + name | String concatenation | lib/lib.js:228:2:228:26 | cp.exec ... + name) | shell command |
| lib/lib.js:236:10:236:25 | "rm -rf " + name | lib/lib.js:227:39:227:42 | name | lib/lib.js:236:22:236:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:236:10:236:25 | "rm -rf " + name | String concatenation | lib/lib.js:236:2:236:26 | cp.exec ... + name) | shell command |
| lib/lib.js:249:10:249:25 | "rm -rf " + name | lib/lib.js:248:42:248:45 | name | lib/lib.js:249:22:249:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:249:10:249:25 | "rm -rf " + name | String concatenation | lib/lib.js:249:2:249:26 | cp.exec ... + name) | shell command |
| lib/lib.js:258:10:258:25 | "rm -rf " + name | lib/lib.js:257:35:257:38 | name | lib/lib.js:258:22:258:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:258:10:258:25 | "rm -rf " + name | String concatenation | lib/lib.js:258:2:258:26 | cp.exec ... + name) | shell command |
| lib/lib.js:261:11:261:33 | "rm -rf ... + name | lib/lib.js:257:35:257:38 | name | lib/lib.js:261:30:261:33 | name | $@ based on libary input is later used in $@. | lib/lib.js:261:11:261:33 | "rm -rf ... + name | String concatenation | lib/lib.js:261:3:261:34 | cp.exec ... + name) | shell command |
| lib/lib.js:268:10:268:32 | "rm -rf ... version | lib/lib.js:267:46:267:48 | obj | lib/lib.js:268:22:268:32 | obj.version | $@ based on libary input is later used in $@. | lib/lib.js:268:10:268:32 | "rm -rf ... version | String concatenation | lib/lib.js:268:2:268:33 | cp.exec ... ersion) | shell command |
| lib/lib.js:277:11:277:30 | "rm -rf " + opts.bla | lib/lib.js:276:8:276:11 | opts | lib/lib.js:277:23:277:30 | opts.bla | $@ based on libary input is later used in $@. | lib/lib.js:277:11:277:30 | "rm -rf " + opts.bla | String concatenation | lib/lib.js:277:3:277:31 | cp.exec ... ts.bla) | shell command |
| lib/lib.js:308:11:308:26 | "rm -rf " + name | lib/lib.js:307:39:307:42 | name | lib/lib.js:308:23:308:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:308:11:308:26 | "rm -rf " + name | String concatenation | lib/lib.js:308:3:308:27 | cp.exec ... + name) | shell command |
| lib/lib.js:315:10:315:25 | "rm -rf " + name | lib/lib.js:314:40:314:43 | name | lib/lib.js:315:22:315:25 | name | $@ based on libary input is later used in $@. | lib/lib.js:315:10:315:25 | "rm -rf " + name | String concatenation | lib/lib.js:315:2:315:26 | cp.exec ... + name) | shell command |
| lib/lib.js:320:11:320:26 | "rm -rf " + name | lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | $@ based on libary input is later used in $@. | lib/lib.js:320:11:320:26 | "rm -rf " + name | String concatenation | lib/lib.js:320:3:320:27 | cp.exec ... + name) | shell command |
| lib/lib2.js:4:10:4:25 | "rm -rf " + name | lib/lib2.js:3:28:3:31 | name | lib/lib2.js:4:22:4:25 | name | $@ based on library input is later used in $@. | lib/lib2.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/lib2.js:4:2:4:26 | cp.exec ... + name) | shell command |
| lib/lib2.js:8:10:8:25 | "rm -rf " + name | lib/lib2.js:7:32:7:35 | name | lib/lib2.js:8:22:8:25 | name | $@ based on library input is later used in $@. | lib/lib2.js:8:10:8:25 | "rm -rf " + name | String concatenation | lib/lib2.js:8:2:8:26 | cp.exec ... + name) | shell command |
| lib/lib.js:4:10:4:25 | "rm -rf " + name | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:22:4:25 | name | $@ based on library input is later used in $@. | lib/lib.js:4:10:4:25 | "rm -rf " + name | String concatenation | lib/lib.js:4:2:4:26 | cp.exec ... + name) | shell command |
| lib/lib.js:11:10:11:25 | "rm -rf " + name | lib/lib.js:10:32:10:35 | name | lib/lib.js:11:22:11:25 | name | $@ based on library input is later used in $@. | lib/lib.js:11:10:11:25 | "rm -rf " + name | String concatenation | lib/lib.js:11:2:11:26 | cp.exec ... + name) | shell command |
| lib/lib.js:15:10:15:25 | "rm -rf " + name | lib/lib.js:14:36:14:39 | name | lib/lib.js:15:22:15:25 | name | $@ based on library input is later used in $@. | lib/lib.js:15:10:15:25 | "rm -rf " + name | String concatenation | lib/lib.js:15:2:15:26 | cp.exec ... + name) | shell command |
| lib/lib.js:20:10:20:25 | "rm -rf " + name | lib/lib.js:19:34:19:37 | name | lib/lib.js:20:22:20:25 | name | $@ based on library input is later used in $@. | lib/lib.js:20:10:20:25 | "rm -rf " + name | String concatenation | lib/lib.js:20:2:20:26 | cp.exec ... + name) | shell command |
| lib/lib.js:27:10:27:25 | "rm -rf " + name | lib/lib.js:26:35:26:38 | name | lib/lib.js:27:22:27:25 | name | $@ based on library input is later used in $@. | lib/lib.js:27:10:27:25 | "rm -rf " + name | String concatenation | lib/lib.js:27:2:27:26 | cp.exec ... + name) | shell command |
| lib/lib.js:35:11:35:26 | "rm -rf " + name | lib/lib.js:34:14:34:17 | name | lib/lib.js:35:23:35:26 | name | $@ based on library input is later used in $@. | lib/lib.js:35:11:35:26 | "rm -rf " + name | String concatenation | lib/lib.js:35:3:35:27 | cp.exec ... + name) | shell command |
| lib/lib.js:38:11:38:26 | "rm -rf " + name | lib/lib.js:37:13:37:16 | name | lib/lib.js:38:23:38:26 | name | $@ based on library input is later used in $@. | lib/lib.js:38:11:38:26 | "rm -rf " + name | String concatenation | lib/lib.js:38:3:38:27 | cp.exec ... + name) | shell command |
| lib/lib.js:41:11:41:26 | "rm -rf " + name | lib/lib.js:40:6:40:9 | name | lib/lib.js:41:23:41:26 | name | $@ based on library input is later used in $@. | lib/lib.js:41:11:41:26 | "rm -rf " + name | String concatenation | lib/lib.js:41:3:41:27 | cp.exec ... + name) | shell command |
| lib/lib.js:50:35:50:50 | "rm -rf " + name | lib/lib.js:49:31:49:34 | name | lib/lib.js:50:47:50:50 | name | $@ based on library input is later used in $@. | lib/lib.js:50:35:50:50 | "rm -rf " + name | String concatenation | lib/lib.js:50:2:50:51 | require ... + name) | shell command |
| lib/lib.js:54:13:54:28 | "rm -rf " + name | lib/lib.js:53:33:53:36 | name | lib/lib.js:54:25:54:28 | name | $@ based on library input is later used in $@. | lib/lib.js:54:13:54:28 | "rm -rf " + name | String concatenation | lib/lib.js:55:2:55:14 | cp.exec(cmd1) | shell command |
| lib/lib.js:57:13:57:28 | "rm -rf " + name | lib/lib.js:53:33:53:36 | name | lib/lib.js:57:25:57:28 | name | $@ based on library input is later used in $@. | lib/lib.js:57:13:57:28 | "rm -rf " + name | String concatenation | lib/lib.js:59:3:59:14 | cp.exec(cmd) | shell command |
| lib/lib.js:65:10:65:25 | "rm -rf " + name | lib/lib.js:64:41:64:44 | name | lib/lib.js:65:22:65:25 | name | $@ based on library input is later used in $@. | lib/lib.js:65:10:65:25 | "rm -rf " + name | String concatenation | lib/lib.js:65:2:65:26 | cp.exec ... + name) | shell command |
| lib/lib.js:71:10:71:31 | "cat /f ... + name | lib/lib.js:64:41:64:44 | name | lib/lib.js:71:28:71:31 | name | $@ based on library input is later used in $@. | lib/lib.js:71:10:71:31 | "cat /f ... + name | String concatenation | lib/lib.js:71:2:71:32 | cp.exec ... + name) | shell command |
| lib/lib.js:73:10:73:31 | "cat \\" ... + "\\"" | lib/lib.js:64:41:64:44 | name | lib/lib.js:73:21:73:24 | name | $@ based on library input is later used in $@. | lib/lib.js:73:10:73:31 | "cat \\" ... + "\\"" | String concatenation | lib/lib.js:73:2:73:32 | cp.exec ... + "\\"") | shell command |
| lib/lib.js:75:10:75:29 | "cat '" + name + "'" | lib/lib.js:64:41:64:44 | name | lib/lib.js:75:20:75:23 | name | $@ based on library input is later used in $@. | lib/lib.js:75:10:75:29 | "cat '" + name + "'" | String concatenation | lib/lib.js:75:2:75:30 | cp.exec ... + "'") | shell command |
| lib/lib.js:77:10:77:37 | "cat '/ ... e + "'" | lib/lib.js:64:41:64:44 | name | lib/lib.js:77:28:77:31 | name | $@ based on library input is later used in $@. | lib/lib.js:77:10:77:37 | "cat '/ ... e + "'" | String concatenation | lib/lib.js:77:2:77:38 | cp.exec ... + "'") | shell command |
| lib/lib.js:83:10:83:25 | "rm -rf " + name | lib/lib.js:82:35:82:38 | name | lib/lib.js:83:22:83:25 | name | $@ based on library input is later used in $@. | lib/lib.js:83:10:83:25 | "rm -rf " + name | String concatenation | lib/lib.js:83:2:83:26 | cp.exec ... + name) | shell command |
| lib/lib.js:86:13:86:16 | name | lib/lib.js:82:35:82:38 | name | lib/lib.js:86:13:86:16 | name | $@ based on library input is later used in $@. | lib/lib.js:86:13:86:16 | name | Array element | lib/lib.js:87:2:87:25 | cp.exec ... n(" ")) | shell command |
| lib/lib.js:89:21:89:24 | name | lib/lib.js:82:35:82:38 | name | lib/lib.js:89:21:89:24 | name | $@ based on library input is later used in $@. | lib/lib.js:89:21:89:24 | name | Array element | lib/lib.js:89:2:89:36 | cp.exec ... n(" ")) | shell command |
| lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | lib/lib.js:82:35:82:38 | name | lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | $@ based on library input is later used in $@. | lib/lib.js:91:21:91:38 | "\\"" + name + "\\"" | Array element | lib/lib.js:91:2:91:50 | cp.exec ... n(" ")) | shell command |
| lib/lib.js:98:35:98:38 | name | lib/lib.js:97:35:97:38 | name | lib/lib.js:98:35:98:38 | name | $@ based on library input is later used in $@. | lib/lib.js:98:35:98:38 | name | Formatted string | lib/lib.js:98:2:98:40 | cp.exec ... name)) | shell command |
| lib/lib.js:100:37:100:40 | name | lib/lib.js:97:35:97:38 | name | lib/lib.js:100:37:100:40 | name | $@ based on library input is later used in $@. | lib/lib.js:100:37:100:40 | name | Formatted string | lib/lib.js:100:2:100:42 | cp.exec ... name)) | shell command |
| lib/lib.js:102:46:102:49 | name | lib/lib.js:97:35:97:38 | name | lib/lib.js:102:46:102:49 | name | $@ based on library input is later used in $@. | lib/lib.js:102:46:102:49 | name | Formatted string | lib/lib.js:102:2:102:51 | cp.exec ... name)) | shell command |
| lib/lib.js:108:41:108:44 | name | lib/lib.js:97:35:97:38 | name | lib/lib.js:108:41:108:44 | name | $@ based on library input is later used in $@. | lib/lib.js:108:41:108:44 | name | Formatted string | lib/lib.js:108:2:108:46 | cp.exec ... name)) | shell command |
| lib/lib.js:112:10:112:25 | "rm -rf " + name | lib/lib.js:111:34:111:37 | name | lib/lib.js:112:22:112:25 | name | $@ based on library input is later used in $@. | lib/lib.js:112:10:112:25 | "rm -rf " + name | String concatenation | lib/lib.js:112:2:112:26 | cp.exec ... + name) | shell command |
| lib/lib.js:121:10:121:25 | "rm -rf " + name | lib/lib.js:120:33:120:36 | name | lib/lib.js:121:22:121:25 | name | $@ based on library input is later used in $@. | lib/lib.js:121:10:121:25 | "rm -rf " + name | String concatenation | lib/lib.js:121:2:121:26 | cp.exec ... + name) | shell command |
| lib/lib.js:131:11:131:26 | "rm -rf " + name | lib/lib.js:130:6:130:9 | name | lib/lib.js:131:23:131:26 | name | $@ based on library input is later used in $@. | lib/lib.js:131:11:131:26 | "rm -rf " + name | String concatenation | lib/lib.js:131:3:131:27 | cp.exec ... + name) | shell command |
| lib/lib.js:149:12:149:27 | "rm -rf " + name | lib/lib.js:148:37:148:40 | name | lib/lib.js:149:24:149:27 | name | $@ based on library input is later used in $@. | lib/lib.js:149:12:149:27 | "rm -rf " + name | String concatenation | lib/lib.js:152:2:152:23 | cp.spaw ... gs, cb) | shell command |
| lib/lib.js:161:13:161:28 | "rm -rf " + name | lib/lib.js:155:38:155:41 | name | lib/lib.js:161:25:161:28 | name | $@ based on library input is later used in $@. | lib/lib.js:161:13:161:28 | "rm -rf " + name | String concatenation | lib/lib.js:163:2:167:2 | cp.spaw ... t' }\\n\\t) | shell command |
| lib/lib.js:173:10:173:23 | "fo \| " + name | lib/lib.js:170:41:170:44 | name | lib/lib.js:173:20:173:23 | name | $@ based on library input is later used in $@. | lib/lib.js:173:10:173:23 | "fo \| " + name | String concatenation | lib/lib.js:173:2:173:24 | cp.exec ... + name) | shell command |
| lib/lib.js:182:10:182:27 | "rm -rf " + broken | lib/lib.js:177:38:177:41 | name | lib/lib.js:182:22:182:27 | broken | $@ based on library input is later used in $@. | lib/lib.js:182:10:182:27 | "rm -rf " + broken | String concatenation | lib/lib.js:182:2:182:28 | cp.exec ... broken) | shell command |
| lib/lib.js:187:10:187:25 | "rm -rf " + name | lib/lib.js:186:34:186:37 | name | lib/lib.js:187:22:187:25 | name | $@ based on library input is later used in $@. | lib/lib.js:187:10:187:25 | "rm -rf " + name | String concatenation | lib/lib.js:187:2:187:26 | cp.exec ... + name) | shell command |
| lib/lib.js:190:11:190:26 | "rm -rf " + name | lib/lib.js:186:34:186:37 | name | lib/lib.js:190:23:190:26 | name | $@ based on library input is later used in $@. | lib/lib.js:190:11:190:26 | "rm -rf " + name | String concatenation | lib/lib.js:190:3:190:27 | cp.exec ... + name) | shell command |
| lib/lib.js:197:10:197:25 | "rm -rf " + name | lib/lib.js:196:45:196:48 | name | lib/lib.js:197:22:197:25 | name | $@ based on library input is later used in $@. | lib/lib.js:197:10:197:25 | "rm -rf " + name | String concatenation | lib/lib.js:197:2:197:26 | cp.exec ... + name) | shell command |
| lib/lib.js:200:11:200:26 | "rm -rf " + name | lib/lib.js:196:45:196:48 | name | lib/lib.js:200:23:200:26 | name | $@ based on library input is later used in $@. | lib/lib.js:200:11:200:26 | "rm -rf " + name | String concatenation | lib/lib.js:200:3:200:27 | cp.exec ... + name) | shell command |
| lib/lib.js:207:10:207:25 | "rm -rf " + name | lib/lib.js:206:45:206:48 | name | lib/lib.js:207:22:207:25 | name | $@ based on library input is later used in $@. | lib/lib.js:207:10:207:25 | "rm -rf " + name | String concatenation | lib/lib.js:207:2:207:26 | cp.exec ... + name) | shell command |
| lib/lib.js:212:11:212:26 | "rm -rf " + name | lib/lib.js:206:45:206:48 | name | lib/lib.js:212:23:212:26 | name | $@ based on library input is later used in $@. | lib/lib.js:212:11:212:26 | "rm -rf " + name | String concatenation | lib/lib.js:212:3:212:27 | cp.exec ... + name) | shell command |
| lib/lib.js:217:10:217:25 | "rm -rf " + name | lib/lib.js:216:39:216:42 | name | lib/lib.js:217:22:217:25 | name | $@ based on library input is later used in $@. | lib/lib.js:217:10:217:25 | "rm -rf " + name | String concatenation | lib/lib.js:217:2:217:26 | cp.exec ... + name) | shell command |
| lib/lib.js:220:11:220:26 | "rm -rf " + name | lib/lib.js:216:39:216:42 | name | lib/lib.js:220:23:220:26 | name | $@ based on library input is later used in $@. | lib/lib.js:220:11:220:26 | "rm -rf " + name | String concatenation | lib/lib.js:220:3:220:27 | cp.exec ... + name) | shell command |
| lib/lib.js:224:10:224:25 | "rm -rf " + name | lib/lib.js:216:39:216:42 | name | lib/lib.js:224:22:224:25 | name | $@ based on library input is later used in $@. | lib/lib.js:224:10:224:25 | "rm -rf " + name | String concatenation | lib/lib.js:224:2:224:26 | cp.exec ... + name) | shell command |
| lib/lib.js:228:10:228:25 | "rm -rf " + name | lib/lib.js:227:39:227:42 | name | lib/lib.js:228:22:228:25 | name | $@ based on library input is later used in $@. | lib/lib.js:228:10:228:25 | "rm -rf " + name | String concatenation | lib/lib.js:228:2:228:26 | cp.exec ... + name) | shell command |
| lib/lib.js:236:10:236:25 | "rm -rf " + name | lib/lib.js:227:39:227:42 | name | lib/lib.js:236:22:236:25 | name | $@ based on library input is later used in $@. | lib/lib.js:236:10:236:25 | "rm -rf " + name | String concatenation | lib/lib.js:236:2:236:26 | cp.exec ... + name) | shell command |
| lib/lib.js:249:10:249:25 | "rm -rf " + name | lib/lib.js:248:42:248:45 | name | lib/lib.js:249:22:249:25 | name | $@ based on library input is later used in $@. | lib/lib.js:249:10:249:25 | "rm -rf " + name | String concatenation | lib/lib.js:249:2:249:26 | cp.exec ... + name) | shell command |
| lib/lib.js:258:10:258:25 | "rm -rf " + name | lib/lib.js:257:35:257:38 | name | lib/lib.js:258:22:258:25 | name | $@ based on library input is later used in $@. | lib/lib.js:258:10:258:25 | "rm -rf " + name | String concatenation | lib/lib.js:258:2:258:26 | cp.exec ... + name) | shell command |
| lib/lib.js:261:11:261:33 | "rm -rf ... + name | lib/lib.js:257:35:257:38 | name | lib/lib.js:261:30:261:33 | name | $@ based on library input is later used in $@. | lib/lib.js:261:11:261:33 | "rm -rf ... + name | String concatenation | lib/lib.js:261:3:261:34 | cp.exec ... + name) | shell command |
| lib/lib.js:268:10:268:32 | "rm -rf ... version | lib/lib.js:267:46:267:48 | obj | lib/lib.js:268:22:268:32 | obj.version | $@ based on library input is later used in $@. | lib/lib.js:268:10:268:32 | "rm -rf ... version | String concatenation | lib/lib.js:268:2:268:33 | cp.exec ... ersion) | shell command |
| lib/lib.js:277:11:277:30 | "rm -rf " + opts.bla | lib/lib.js:276:8:276:11 | opts | lib/lib.js:277:23:277:30 | opts.bla | $@ based on library input is later used in $@. | lib/lib.js:277:11:277:30 | "rm -rf " + opts.bla | String concatenation | lib/lib.js:277:3:277:31 | cp.exec ... ts.bla) | shell command |
| lib/lib.js:308:11:308:26 | "rm -rf " + name | lib/lib.js:307:39:307:42 | name | lib/lib.js:308:23:308:26 | name | $@ based on library input is later used in $@. | lib/lib.js:308:11:308:26 | "rm -rf " + name | String concatenation | lib/lib.js:308:3:308:27 | cp.exec ... + name) | shell command |
| lib/lib.js:315:10:315:25 | "rm -rf " + name | lib/lib.js:314:40:314:43 | name | lib/lib.js:315:22:315:25 | name | $@ based on library input is later used in $@. | lib/lib.js:315:10:315:25 | "rm -rf " + name | String concatenation | lib/lib.js:315:2:315:26 | cp.exec ... + name) | shell command |
| lib/lib.js:320:11:320:26 | "rm -rf " + name | lib/lib.js:314:40:314:43 | name | lib/lib.js:320:23:320:26 | name | $@ based on library input is later used in $@. | lib/lib.js:320:11:320:26 | "rm -rf " + name | String concatenation | lib/lib.js:320:3:320:27 | cp.exec ... + name) | shell command |

View File

@@ -3,6 +3,10 @@ nodes
| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
| ReflectedXss.js:8:33:8:45 | req.params.id |
| ReflectedXss.js:8:33:8:45 | req.params.id |
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
| ReflectedXss.js:17:31:17:39 | params.id |
| ReflectedXss.js:17:31:17:39 | params.id |
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id |
@@ -95,6 +99,10 @@ edges
| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id |
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
| ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id |
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
| ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id |
@@ -173,6 +181,7 @@ edges
| tst2.js:14:9:14:9 | p | tst2.js:14:7:14:24 | p |
#select
| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value |
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:17:31:17:39 | params.id | user-provided value |
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | user-provided value |
| ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | user-provided value |
| ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | user-provided value |

View File

@@ -3,10 +3,16 @@ var express = require('express');
var app = express();
app.get('/user/:id', function(req, res) {
if (!isValidUserId(req.params.id))
if (!isValidUserId(req.params.id)) {
// BAD: a request parameter is incorporated without validation into the response
res.send("Unknown user: " + req.params.id);
else
moreBadStuff(req.params, res);
} else {
// TODO: do something exciting
;
}
});
function moreBadStuff(params, res) {
res.send("Unknown user: " + params.id); // NOT OK
}

View File

@@ -1,4 +1,5 @@
| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value |
| ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:17:31:17:39 | params.id | user-provided value |
| ReflectedXssContentTypes.js:10:14:10:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:10:24:10:36 | req.params.id | user-provided value |
| ReflectedXssContentTypes.js:20:14:20:36 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:20:24:20:36 | req.params.id | user-provided value |
| ReflectedXssContentTypes.js:39:13:39:35 | "FOO: " ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXssContentTypes.js:39:23:39:35 | req.params.id | user-provided value |

View File

@@ -11,6 +11,8 @@
| mongodb.js:65:3:65:17 | doc.find(query) |
| mongodb.js:73:5:77:27 | client\\n ... tag }) |
| mongodb.js:81:3:85:25 | importe ... tag }) |
| mongodb.js:98:5:98:19 | doc.find(query) |
| mongodb.js:112:5:112:19 | doc.find(query) |
| mongodb_bodySafe.js:18:7:18:21 | doc.find(query) |
| mongodb_bodySafe.js:29:7:29:21 | doc.find(query) |
| mongoose.js:63:2:63:34 | Documen ... then(X) |

View File

@@ -56,6 +56,12 @@ nodes
| mongodb.js:85:12:85:24 | { tags: tag } |
| mongodb.js:85:12:85:24 | { tags: tag } |
| mongodb.js:85:20:85:22 | tag |
| mongodb.js:106:9:106:18 | query |
| mongodb.js:106:17:106:18 | {} |
| mongodb.js:107:17:107:29 | queries.title |
| mongodb.js:107:17:107:29 | queries.title |
| mongodb.js:112:14:112:18 | query |
| mongodb.js:112:14:112:18 | query |
| mongodb_bodySafe.js:23:11:23:20 | query |
| mongodb_bodySafe.js:23:19:23:20 | {} |
| mongodb_bodySafe.js:24:19:24:33 | req.query.title |
@@ -244,6 +250,17 @@ edges
| mongodb.js:77:22:77:24 | tag | mongodb.js:77:14:77:26 | { tags: tag } |
| mongodb.js:85:20:85:22 | tag | mongodb.js:85:12:85:24 | { tags: tag } |
| mongodb.js:85:20:85:22 | tag | mongodb.js:85:12:85:24 | { tags: tag } |
| mongodb.js:106:9:106:18 | query | mongodb.js:112:14:112:18 | query |
| mongodb.js:106:9:106:18 | query | mongodb.js:112:14:112:18 | query |
| mongodb.js:106:17:106:18 | {} | mongodb.js:106:9:106:18 | query |
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:9:106:18 | query |
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:9:106:18 | query |
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:17:106:18 | {} |
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:106:17:106:18 | {} |
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query |
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query |
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query |
| mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query |
| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:29:16:29:20 | query |
| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:29:16:29:20 | query |
| mongodb_bodySafe.js:23:19:23:20 | {} | mongodb_bodySafe.js:23:11:23:20 | query |
@@ -428,6 +445,7 @@ edges
| mongodb.js:65:12:65:16 | query | mongodb.js:60:16:60:30 | req.query.title | mongodb.js:65:12:65:16 | query | This query depends on $@. | mongodb.js:60:16:60:30 | req.query.title | a user-provided value |
| mongodb.js:77:14:77:26 | { tags: tag } | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:77:14:77:26 | { tags: tag } | This query depends on $@. | mongodb.js:70:13:70:25 | req.query.tag | a user-provided value |
| mongodb.js:85:12:85:24 | { tags: tag } | mongodb.js:70:13:70:25 | req.query.tag | mongodb.js:85:12:85:24 | { tags: tag } | This query depends on $@. | mongodb.js:70:13:70:25 | req.query.tag | a user-provided value |
| mongodb.js:112:14:112:18 | query | mongodb.js:107:17:107:29 | queries.title | mongodb.js:112:14:112:18 | query | This query depends on $@. | mongodb.js:107:17:107:29 | queries.title | a user-provided value |
| mongodb_bodySafe.js:29:16:29:20 | query | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | This query depends on $@. | mongodb_bodySafe.js:24:19:24:33 | req.query.title | a user-provided value |
| mongoose.js:24:24:24:30 | [query] | mongoose.js:21:19:21:26 | req.body | mongoose.js:24:24:24:30 | [query] | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:27:20:27:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:27:20:27:24 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |

View File

@@ -84,3 +84,31 @@ app.post("/logs/count-by-tag", (req, res) => {
// NOT OK: query is tainted by user-provided object value
.count({ tags: tag });
});
app.get('/:id', (req, res) => {
useParams(req.param);
});
function useParams(params) {
let query = { id: params.id };
MongoClient.connect('mongodb://localhost:27017/test', (err, db) => {
let doc = db.collection('doc');
// OK: query is tainted, but only by string value
doc.find(query);
});
}
app.post('/documents/find', (req, res) => {
useQuery(req.query);
});
function useQuery(queries) {
const query = {};
query.title = queries.title;
MongoClient.connect('mongodb://localhost:27017/test', (err, db) => {
let doc = db.collection('doc');
// NOT OK: query is tainted by user-provided object value
doc.find(query);
});
}

View File

@@ -1,4 +1,23 @@
nodes
| sanitizer.js:2:9:2:25 | url |
| sanitizer.js:2:15:2:25 | window.name |
| sanitizer.js:2:15:2:25 | window.name |
| sanitizer.js:4:27:4:29 | url |
| sanitizer.js:4:27:4:29 | url |
| sanitizer.js:16:27:16:29 | url |
| sanitizer.js:16:27:16:29 | url |
| sanitizer.js:19:27:19:29 | url |
| sanitizer.js:19:27:19:29 | url |
| sanitizer.js:22:27:22:29 | url |
| sanitizer.js:22:27:22:29 | url |
| sanitizer.js:25:27:25:29 | url |
| sanitizer.js:25:27:25:29 | url |
| sanitizer.js:28:27:28:29 | url |
| sanitizer.js:28:27:28:29 | url |
| sanitizer.js:31:27:31:29 | url |
| sanitizer.js:31:27:31:29 | url |
| sanitizer.js:37:27:37:29 | url |
| sanitizer.js:37:27:37:29 | url |
| tst2.js:2:7:2:33 | href |
| tst2.js:2:7:2:33 | href |
| tst2.js:2:14:2:28 | window.location |
@@ -80,6 +99,24 @@ nodes
| tst.js:6:34:6:50 | document.location |
| tst.js:6:34:6:55 | documen ... on.href |
edges
| sanitizer.js:2:9:2:25 | url | sanitizer.js:4:27:4:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:4:27:4:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:16:27:16:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:16:27:16:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:19:27:19:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:19:27:19:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:22:27:22:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:22:27:22:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:25:27:25:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:25:27:25:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:28:27:28:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:28:27:28:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:31:27:31:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:31:27:31:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:37:27:37:29 | url |
| sanitizer.js:2:9:2:25 | url | sanitizer.js:37:27:37:29 | url |
| sanitizer.js:2:15:2:25 | window.name | sanitizer.js:2:9:2:25 | url |
| sanitizer.js:2:15:2:25 | window.name | sanitizer.js:2:9:2:25 | url |
| tst2.js:2:7:2:33 | href | tst2.js:4:21:4:24 | href |
| tst2.js:2:7:2:33 | href | tst2.js:4:21:4:24 | href |
| tst2.js:2:14:2:28 | window.location | tst2.js:2:14:2:33 | window.location.href |
@@ -155,6 +192,14 @@ edges
| tst.js:6:34:6:50 | document.location | tst.js:6:34:6:55 | documen ... on.href |
| tst.js:6:34:6:55 | documen ... on.href | tst.js:6:20:6:56 | indirec ... n.href) |
#select
| sanitizer.js:4:27:4:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:4:27:4:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| sanitizer.js:16:27:16:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:16:27:16:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| sanitizer.js:19:27:19:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:19:27:19:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| sanitizer.js:22:27:22:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:22:27:22:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| sanitizer.js:25:27:25:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:25:27:25:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| sanitizer.js:28:27:28:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:28:27:28:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| sanitizer.js:31:27:31:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:31:27:31:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| sanitizer.js:37:27:37:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:37:27:37:29 | url | Untrusted URL redirection due to $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value |
| tst2.js:4:21:4:55 | href.su ... '?')+1) | tst2.js:2:14:2:28 | window.location | tst2.js:4:21:4:55 | href.su ... '?')+1) | Untrusted URL redirection due to $@. | tst2.js:2:14:2:28 | window.location | user-provided value |
| tst6.js:4:21:4:28 | redirect | tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:4:21:4:28 | redirect | Untrusted URL redirection due to $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value |
| tst6.js:6:17:6:24 | redirect | tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:6:17:6:24 | redirect | Untrusted URL redirection due to $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value |

View File

@@ -0,0 +1,43 @@
function f() {
let url = window.name;
if (url.startsWith('https://example.com')) {
window.location = url; // NOT OK - can be example.com.evil.com
}
if (url.startsWith('https://example.com/')) {
window.location = url; // OK
}
if (url.startsWith('https://example.com//')) {
window.location = url; // OK
}
if (url.startsWith('https://example.com/foo')) {
window.location = url; // OK
}
if (url.startsWith('https://')) {
window.location = url; // NOT OK - does not restrict hostname
}
if (url.startsWith('https:/')) {
window.location = url; // NOT OK - does not restrict hostname
}
if (url.startsWith('https:')) {
window.location = url; // NOT OK - does not restrict hostname
}
if (url.startsWith('/')) {
window.location = url; // NOT OK - can be //evil.com
}
if (url.startsWith('//')) {
window.location = url; // NOT OK - can be //evil.com
}
if (url.startsWith('//example.com')) {
window.location = url; // NOT OK - can be //example.com.evil.com
}
if (url.startsWith('//example.com/')) {
window.location = url; // OK
}
if (url.endsWith('https://example.com/')) {
window.location = url; // NOT OK - could be evil.com?x=https://example.com/
}
let basedir = whatever() ? 'foo' : 'bar';
if (url.startsWith('https://example.com/' + basedir)) {
window.location = url; // OK - the whole prefix is not known, but enough to restrict hostname
}
}

View File

@@ -13,4 +13,6 @@
- security
- exclude:
deprecated: //
- exclude:
query path: /^experimental\/.*/

View File

@@ -21,3 +21,5 @@
- file-classifier
- exclude:
deprecated: //
- exclude:
query path: /^experimental\/.*/

View File

@@ -16,3 +16,6 @@
- warning
- exclude:
deprecated: //
- exclude:
query path: /^experimental\/.*/

View File

@@ -21,4 +21,6 @@
- security
- exclude:
deprecated: //
- exclude:
query path: /^experimental\/.*/

View File

@@ -11,6 +11,6 @@ import python
from ExceptStmt ex, ClassValue cls
where
cls.getName() = "MyExceptionClass" and
ex.getType().pointsTo(cls)
cls.getName() = "MyExceptionClass" and
ex.getType().pointsTo(cls)
select ex

View File

@@ -12,7 +12,7 @@ import python
from IfExp e, ClassObject cls1, ClassObject cls2
where
e.getBody().refersTo(_, cls1, _) and
e.getOrelse().refersTo(_, cls2, _) and
cls1 != cls2
e.getBody().refersTo(_, cls1, _) and
e.getOrelse().refersTo(_, cls2, _) and
cls1 != cls2
select e

View File

@@ -14,8 +14,8 @@ import python
from If i
where
not exists(Stmt s |
i.getStmt(_) = s and
not s instanceof Pass
)
not exists(Stmt s |
i.getStmt(_) = s and
not s instanceof Pass
)
select i

View File

@@ -14,6 +14,6 @@ import python
from ClassObject sub, ClassObject base
where
base.getName() = "MyClass" and
sub.getABaseType() = base
base.getName() = "MyClass" and
sub.getABaseType() = base
select sub

View File

@@ -10,6 +10,6 @@ import python
from AstNode call, PythonFunctionValue method
where
method.getQualifiedName() = "MyClass.methodName" and
method.getACall().getNode() = call
method.getQualifiedName() = "MyClass.methodName" and
method.getACall().getNode() = call
select call

View File

@@ -11,6 +11,6 @@ import python
from Call new, ClassValue cls
where
cls.getName() = "MyClass" and
new.getFunc().pointsTo(cls)
cls.getName() = "MyClass" and
new.getFunc().pointsTo(cls)
select new

View File

@@ -10,6 +10,6 @@ import python
from FunctionObject override, FunctionObject base
where
base.getQualifiedName() = "MyClass.methodName" and
override.overrides(base)
base.getQualifiedName() = "MyClass.methodName" and
override.overrides(base)
select override

View File

@@ -9,9 +9,9 @@ import python
from AstNode print
where
/* Python 2 without `from __future__ import print_function` */
print instanceof Print
or
/* Python 3 or with `from __future__ import print_function` */
print.(Call).getFunc().pointsTo(Value::named("print"))
/* Python 2 without `from __future__ import print_function` */
print instanceof Print
or
/* Python 3 or with `from __future__ import print_function` */
print.(Call).getFunc().pointsTo(Value::named("print"))
select print

View File

@@ -9,12 +9,12 @@
import python
predicate is_private(Attribute a) {
a.getName().matches("\\_%") and
not a.getName().matches("\\_\\_%\\_\\_")
a.getName().matches("\\_%") and
not a.getName().matches("\\_\\_%\\_\\_")
}
from Attribute access
where
is_private(access) and
not access.getObject().(Name).getId() = "self"
is_private(access) and
not access.getObject().(Name).getId() = "self"
select access

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