JavaScript: Address review comments.

This commit is contained in:
Max Schaefer
2019-07-24 15:32:13 +01:00
parent 502a7aacfc
commit 97e8b5fa99

View File

@@ -13,10 +13,10 @@ By subclassing an abstract class used by the JavaScript analysis and implementin
member predicates we can teach the analysis to handle further instances of abstract concepts it member predicates we can teach the analysis to handle further instances of abstract concepts it
already understands. For example, the standard library defines an abstract class already understands. For example, the standard library defines an abstract class
``SystemCommandExecution`` that covers various APIs for executing operating-system commands. This ``SystemCommandExecution`` that covers various APIs for executing operating-system commands. This
class is used by the command-injection analysis to identify potentially problematic flows where class is used by the command-injection analysis to identify problematic flows where input from a
input from a potentially malicious user is interpreted as the name of a system command to execute. potentially malicious user is interpreted as the name of a system command to execute. By defining
By defining additional subclasses of ``SystemCommandExecution``, we can make this analysis more additional subclasses of ``SystemCommandExecution``, we can make this analysis more powerful without
powerful without touching its implementation. touching its implementation.
By overriding a member predicate defined in the library, we can change its behavior either for all By overriding a member predicate defined in the library, we can change its behavior either for all
its receivers or only a subset. For example, the standard library predicate its receivers or only a subset. For example, the standard library predicate
@@ -28,20 +28,25 @@ analysis queries pick it up. This can be done by adding the customizing definiti
``Customizations.qll``, an initially empty library file that is imported by the default library ``Customizations.qll``, an initially empty library file that is imported by the default library
``javascript.qll``. ``javascript.qll``.
Sometimes you may want to apply the two customization mechanisms of subclassing to provide new Sometimes you may want to perform both kinds of customizations at the same time: subclass a base
implementations of an API and of overriding to selectively change the implementation of the API to class to provide new implementations of an API, and override some member predicates of the same base
the same base class. This is not always easy to do, since the former requires the base class to be class to selectively change the implementation of the API. This is not always easy to do, since the
abstract, while the latter requires it to be concrete. former requires the base class to be abstract, while the latter requires it to be concrete.
To work around this, the JavaScript library uses the so-called `range pattern`: the base class To work around this, the JavaScript library uses the so-called `range pattern`: the base class
``Base`` itself is concrete, but it has an abstract companion class called ``Base::Range`` with the ``Base`` itself is concrete, but it has an abstract companion class called ``Base::Range`` covering
same member predicates and covering the same set of values. The default implementation of all the same set of values. To change the implementation of the API, subclass ``Base`` and override its
predicates in ``Base`` simply delegates to their implementations in ``Base::Range``. To extend member predicates. To provide new implementations of the API, subclass ``Base::Range`` and implement
``Base`` with new implementations, we subclass ``Base::Range`` and implement its API. To customize its abstract member predicates.
``Base``, on the other hand, we subclass ``Base`` itself and override the predicates we want to
adjust.
Note that currently the range pattern is not yet used everywhere, so you will find some abstract For example, the class ``Base64::Encode`` in the standard library models base64-encoding libraries
using the range pattern. To add support for a new library, subclass ``Base64::Encode::Range`` and
implement the member predicates ``getInput`` and ``getOutput``. (Subclasses for many popular base64
encoders are included in the standard library.) To customize the definition of ``getInput`` or
``getOutput`` for a library that is already supported, extend ``Base64::Encode`` itself and override
the predicate you want to customize.
Note that currently the range pattern is not used everywhere yet, so you will find some abstract
classes without a concrete companion. We are planning on eventually migrating most abstract classes classes without a concrete companion. We are planning on eventually migrating most abstract classes
to use the range pattern. to use the range pattern.
@@ -130,7 +135,8 @@ Framework models
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
The libraries under ``semmle/javascript/frameworks`` model a broad range of popular JavaScript The libraries under ``semmle/javascript/frameworks`` model a broad range of popular JavaScript
libraries and frameworks, such as Express or Vue.js. libraries and frameworks, such as Express or Vue.js. Some framework modeling libraries are located
under ``semmle/javascript`` directly, for instance ``Base64``, ``EmailClients`` and ``JsonParsers``.
Global data flow and taint tracking Global data flow and taint tracking
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -163,7 +169,7 @@ It is not normally necessary to customize this layer.
Local data flow Local data flow
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
The ``DataFlow::SourceNode`` class implements the range pattern, so new kinds of source nodes can be The ``DataFlow::SourceNode`` class uses the range pattern, so new kinds of source nodes can be
added by extending ``Dataflow::SourceNode::Range``. Some of its subclasses can similarly be added by extending ``Dataflow::SourceNode::Range``. Some of its subclasses can similarly be
extended: ``DataFlow::ModuleImportNode`` models module imports, and ``DataFlow::ClassNode`` models extended: ``DataFlow::ModuleImportNode`` models module imports, and ``DataFlow::ClassNode`` models
class definitions. The former provides default implementations covering CommonJS, AMD and ECMAScript class definitions. The former provides default implementations covering CommonJS, AMD and ECMAScript
@@ -178,13 +184,13 @@ You can override ``AnalyzedNode::getAValue`` to customize the type inference. No
You can also extend the set of abstract values in one of two ways: You can also extend the set of abstract values in one of two ways:
1. To add individual abstract values that are independent of the program being analyzed, define a 1. To add individual abstract values that are independent of the program being analyzed, define a
subclass of ``CustomAbstractValueTag`` describing the new abstract value. There will then be a subclass of ``CustomAbstractValueTag`` describing the new abstract value. There will then be a
corresponding value of class ``CustomAbstractValue`` that you can use in overriding corresponding value of class ``CustomAbstractValue`` that you can use in overriding
definitions of the ``getAValue`` predicate. definitions of the ``getAValue`` predicate.
2. To add abstract values that are induced by a program element, define a subclass of 2. To add abstract values that are induced by a program element, define a subclass of
``CustomAbstractValueDefinition``, and use its corresponding ``CustomAbstractValueDefinition``, and use its corresponding
``CustomAbstractValueFromDefinition``. ``CustomAbstractValueFromDefinition``.
Call graph Call graph
~~~~~~~~~~ ~~~~~~~~~~