From eafd46221bc0262ccd3757a2ed59511e41e71e08 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 30 Jul 2019 18:06:27 +0100 Subject: [PATCH] JS: Add data flow cheat sheet --- .../javascript/dataflow-cheat-sheet.rst | 175 ++++++++++++++++++ .../learn-ql/javascript/ql-for-javascript.rst | 3 + 2 files changed, 178 insertions(+) create mode 100644 docs/ql-documentation/learn-ql/javascript/dataflow-cheat-sheet.rst diff --git a/docs/ql-documentation/learn-ql/javascript/dataflow-cheat-sheet.rst b/docs/ql-documentation/learn-ql/javascript/dataflow-cheat-sheet.rst new file mode 100644 index 00000000000..a503b578ade --- /dev/null +++ b/docs/ql-documentation/learn-ql/javascript/dataflow-cheat-sheet.rst @@ -0,0 +1,175 @@ +Data flow cheat sheet +===================== + +This page describes parts of the JavaScript QL libraries commonly used for variant analysis and in data flow queries. + +Taint tracking path queries +--------------------------- + +Use the following template to create a taint tracking path query: + +.. code-block:: ql + + /** + * @kind path-problem + */ + import javascript + import DataFlow + import DataFlow::PathGraph + + class MyConfig extends TaintTracking::Configuration { + MyConfig() { this = "MyConfig" } + override predicate isSource(Node node) { ... } + override predicate isSink(Node node) { ... } + override predicate isAdditionalTaintStep(Node pred, Node succ) { ... } + } + + from MyConfig cfg, PathNode source, PathNode sink + where cfg.hasFlowPath(source, sink) + select sink.getNode(), source, sink, "taint from $@.", source.getNode(), "here" + +This query reports flow paths which: + +- Begin at a node matched by `isSource `__. +- Step through variables, function calls, properties, strings, arrays, promises, exceptions, and steps added by `isAdditionalTaintStep `__. +- End at a node matched by `isSink `__. + +See also: `Global data flow `__ and :doc:`Constructing path queries <../writing-queries/path-queries>`. + +DataFlow module +--------------- + +Use data flow nodes to match program elements independently of syntax. See also: :doc:`Analyzing data flow in JavaScript/TypeScript `. + +Predicates in the ``DataFlow::`` module: + +- `moduleImport `__ -- finds uses of a module +- `moduleMember `__ -- finds uses of a module member +- `globalVarRef `__ -- finds uses of a global variable + +Classes and member predicates in the ``DataFlow::`` module: + +- `Node `__ -- something that can have a value, such as an expression, declaration, or SSA variable + - `getALocalSource `__ -- find the node that this came from + - `getTopLevel `__ -- top-level scope enclosing this node + - `getFile `__ -- file containing this node + - `getIntValue `__ -- value of this node if it's is an integer constant + - `getStringValue `__ -- value of this node if it's is a string constant + - `mayHaveBooleanValue `__ -- check if the value is ``true`` or ``false`` +- `SourceNode `__ extends `Node `__ -- function call, parameter, object creation, or reference to a property or global variable + - `getACall `__ -- find calls with this as the callee + - `getAnInstantiation `__ -- find ``new``-calls with this as the callee + - `getAnInvocation `__ -- find calls or ``new``-calls with this as the callee + - `getAMethodCall `__ -- find method calls with this as the receiver + - `getAMemberCall `__ -- find calls with a member of this as the receiver + - `getAPropertyRead `__ -- find property reads with this as the base + - `getAPropertyWrite `__ -- find property writes with this as the base + - `getAPropertySource `__ -- find nodes flowing into a property of this node +- `InvokeNode `__, `NewNode `__, `CallNode `__, `MethodCallNode `__ extends `SourceNode `__ -- call to a function or constructor + - `getArgument `__ -- an argument to the call + - `getCalleeNode `__ -- node being invoked as a function + - `getCalleeName `__ -- name of the variable or property being called + - `getOptionArgument `__ -- a "named argument" passed in through an object literal + - `getCallback `__ -- a function passed as a callback + - `getACallee `__ - a function being called here + - (MethodCallNode).\ `getMethodName `__ -- name of the method being invoked + - (MethodCallNode).\ `getReceiver `__ -- receiver of the method call +- `FunctionNode `__ extends `SourceNode `__ -- definition of a function, including closures, methods, and class constructors + - `getName `__ -- name of the function, derived from a variable or property name + - `getParameter `__ -- a parameter of the function + - `getReceiver `__ -- the node representing the value of ``this`` + - `getAReturn `__ -- get a returned expression +- `ParameterNode `__ extends `SourceNode `__ -- parameter of a function + - `getName `__ -- the parameter name, if it has one +- `ClassNode `__ extends `SourceNode `__ -- class declaration or function that acts as a class + - `getName `__ -- name of the class, derived from a variable or property name + - `getConstructor `__ -- the constructor function + - `getInstanceMethod `__ -- get an instance method by name + - `getStaticMethod `__ -- get a static method by name + - `getAnInstanceReference `__ -- find references to an instance of the class + - `getAClassReference `__ -- find references to the class itself +- `ObjectLiteralNode `__ extends `SourceNode `__ -- object literal + - `getAPropertyWrite `__ -- a property in the object literal + - `getAPropertySource `__ -- value flowing into a property +- `ArrayCreationNode `__ extends `SourceNode `__ -- array literal or call to ``Array`` constructor + - `getElement `__ -- an element of the array +- `PropRef `__, `PropRead `__, `PropWrite `__ -- read or write of a property + - `getPropertyName `__ -- name of the property, if it is constant + - `getPropertyNameExpr `__ -- expression holding the name of the property + - `getBase `__ -- object whose property is accessed + - (PropWrite).\ `getRhs `__ -- right-hand side of the property assignment + + +StringOps module +---------------- + +- StringOps::`Concatenation `__ -- string concatenation, using a plus operator, template literal, or array join call +- StringOps::`StartsWith `__ -- check if a string starts with something +- StringOps::`EndsWith `__ -- check if a string ends with something +- StringOps::`Includes `__ -- check if a string contains something + +Utility +-------- + +- `ExtendCall `__ -- call that copies properties from one object to another +- `JsonParserCall `__ -- call that deserializes a JSON string +- `PropertyProjection `__ -- call that extracts nested properties by name + +System and Network +------------------ + +- `ClientRequest `__ -- outgoing network request +- `DatabaseAccess `__ -- query being submitted to a database +- `FileNameSource `__ -- reference to a filename +- `FileSystemAccess `__ -- file system operation + - `FileSystemReadAccess `__ -- reading the contents of a file + - `FileSystemWriteAccess `__ -- writing to the contents of a file +- `PersistentReadAccess `__ -- reading from persistent storage, like cookies +- `PersistentWriteAccess `__ -- writing to persistent storage +- `RemoteFlowSource `__ -- source of untrusted user input +- `SystemCommandExecution `__ -- execution of a system command + +Files +----- + +- `File `__, + `Folder `__ extends + `Container `__ -- file or folder in the snapshot + + - `getBaseName `__ -- the name of the file or folder + - `getRelativePath `__ -- path relative to the snapshot root + +AST nodes +--------- + +See also: :doc:`AST class reference `. + +Conversion between DataFlow and AST nodes: + +- `Node.asExpr() `__ -- convert node to an expression, if possible +- `Expr.flow() `__ -- convert expression to a node (always possible) +- `DataFlow::valueNode `__ -- convert expression or declaration to a node +- `DataFlow::parameterNode `__ -- convert a parameter to a node +- `DataFlow::thisNode `__ -- get the receiver node of a function + +String matching +--------------- + +- x.\ `matches `__\ ("escape%") -- holds if x starts with "escape" +- x.\ `regexpMatch `__\ ("escape.*") -- holds if x starts with "escape" +- x.\ `regexpMatch `__\ ("(?i).*escape.*") -- holds if x contains + "escape" (case insensitive) + +Troubleshooting +--------------- + +- Using a call node as as sink? Try using `getArgument `__ + to get an *argument* of the call node instead. +- Trying to use `moduleImport `__ + or `moduleMember `__ + as a call node? + Try using `getACall `__ + to get a *call* to the imported function, instead of the function itself. +- Compilation fails due to incompatible types? Make sure AST nodes and + DataFlow nodes are not mixed up. Use `asExpr() `__ or + `flow() `__ to convert. diff --git a/docs/ql-documentation/learn-ql/javascript/ql-for-javascript.rst b/docs/ql-documentation/learn-ql/javascript/ql-for-javascript.rst index c9a491052e3..e6aa540b33e 100644 --- a/docs/ql-documentation/learn-ql/javascript/ql-for-javascript.rst +++ b/docs/ql-documentation/learn-ql/javascript/ql-for-javascript.rst @@ -9,6 +9,7 @@ QL for JavaScript introduce-libraries-ts dataflow ast-class-reference + dataflow-cheat-sheet These documents provide an overview of the QL JavaScript and TypeScript standard libraries and show examples of how to use them. @@ -22,6 +23,8 @@ These documents provide an overview of the QL JavaScript and TypeScript standard - :doc:`AST class reference `: an overview of all AST classes in the QL standard library for JavaScript. +- :doc:`Data flow cheat sheet `: bits of QL commonly used for variant analysis and in data flow queries. + Other resources ---------------