Merge pull request #2830 from shati-patel/docs-preparation

Merge master into `docs-preparation` branch
This commit is contained in:
James Fletcher
2020-02-13 14:59:09 +00:00
committed by GitHub
153 changed files with 4452 additions and 1065 deletions

View File

@@ -19,6 +19,7 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
| Memory is never freed (`cpp/memory-never-freed`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
| Memory may not be freed (`cpp/memory-may-not-be-freed`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
| Missing return statement (`cpp/missing-return`) | Fewer false positive results | Functions containing `asm` statements are no longer highlighted by this query. |
| No space for zero terminator (`cpp/no-space-for-terminator`) | More correct results | String arguments to formatting functions are now (usually) expected to be null terminated strings. |
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | | This query is no longer run on LGTM. |
| No space for zero terminator (`cpp/no-space-for-terminator`) | Fewer false positive results | This query has been modified to be more conservative when identifying which pointers point to null-terminated strings. This approach produces fewer, more accurate results. |
| Overloaded assignment does not return 'this' (`cpp/assignment-does-not-return-this`) | Fewer false positive results | This query no longer reports incorrect results in template classes. |

View File

@@ -27,7 +27,9 @@ The following changes in version 1.24 affect C# analysis in all applications.
## Changes to code extraction
* Tuple expressions, for example `(int,bool)` in `default((int,bool))` are now extracted correctly.
* Expression nullability flow state is extracted.
* Expression nullability flow state is extracted.
* Implicitly typed `stackalloc` expressions are now extracted correctly.
* The difference between `stackalloc` array creations and normal array creations is extracted.
## Changes to libraries
@@ -38,5 +40,6 @@ The following changes in version 1.24 affect C# analysis in all applications.
* The taint tracking library now tracks flow through (implicit or explicit) conversion operator calls.
* [Code contracts](https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts) are now recognized, and are treated like any other assertion methods.
* Expression nullability flow state is given by the predicates `Expr.hasNotNullFlowState()` and `Expr.hasMaybeNullFlowState()`.
* `stackalloc` array creations are now represented by the QL class `Stackalloc`. Previously they were represented by the class `ArrayCreation`.
## Changes to autobuilder

View File

@@ -0,0 +1,37 @@
# Improvements to Python analysis
The following changes in version 1.24 affect Python analysis in all applications.
## General improvements
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
### Web framework support
The QL-library support for the web frameworks Bottle, CherryPy, Falcon, Pyramid, TurboGears, Tornado, and Twisted have
been fixed so they provide a proper HttpRequestTaintSource, instead of a TaintSource. This will enable results for the following queries:
- py/path-injection
- py/command-line-injection
- py/reflective-xss
- py/sql-injection
- py/code-injection
- py/unsafe-deserialization
- py/url-redirection
The QL-library support for the web framework Twisted have been fixed so they provide a proper
HttpResponseTaintSink, instead of a TaintSink. This will enable results for the following
queries:
- py/reflective-xss
- py/stack-trace-exposure
## Changes to libraries

View File

@@ -22,16 +22,25 @@ import semmle.code.cpp.models.interfaces.Allocation
predicate terminationProblem(AllocationExpr malloc, string msg) {
// malloc(strlen(...))
exists(StrlenCall strlen | DataFlow::localExprFlow(strlen, malloc.getSizeExpr())) and
// flows into a null-terminated string function
// flows to a call that implies this is a null-terminated string
exists(ArrayFunction af, FunctionCall fc, int arg |
DataFlow::localExprFlow(malloc, fc.getArgument(arg)) and
fc.getTarget() = af and
(
// null terminated string
// flows into null terminated string argument
af.hasArrayWithNullTerminator(arg)
or
// likely a null terminated string (such as `strcpy`, `strcat`)
// flows into likely null terminated string argument (such as `strcpy`, `strcat`)
af.hasArrayWithUnknownSize(arg)
or
// flows into string argument to a formatting function (such as `printf`)
exists(int n, FormatLiteral fl |
fc.getArgument(arg) = fc.(FormattingFunctionCall).getConversionArgument(n) and
fl = fc.(FormattingFunctionCall).getFormat() and
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
not fl.hasPrecision(n) // exclude: `%.*s`
)
)
) and
msg = "This allocation does not include space to null-terminate the string."

View File

@@ -335,6 +335,12 @@ private Element adjustedSink(DataFlow::Node sink) {
// For compatibility, send flow into a `NotExpr` even if it's part of a
// short-circuiting condition and thus might get skipped.
result.(NotExpr).getOperand() = sink.asExpr()
or
// Taint postfix and prefix crement operations when their operand is tainted.
result.(CrementOperation).getAnOperand() = sink.asExpr()
or
// Taint `e1 += e2`, `e &= e2` and friends when `e1` or `e2` is tainted.
result.(AssignOperation).getAnOperand() = sink.asExpr()
}
predicate tainted(Expr source, Element tainted) {

View File

@@ -365,10 +365,10 @@ private predicate modelFlow(Instruction iFrom, Instruction iTo) {
modelOut.isReturnValueDeref() and
iTo = call
or
exists(WriteSideEffectInstruction outNode |
modelOut.isParameterDeref(outNode.getIndex()) and
exists(int index, WriteSideEffectInstruction outNode |
modelOut.isParameterDeref(index) and
iTo = outNode and
outNode.getPrimaryInstruction() = call
outNode = getSideEffectFor(call, index)
)
// TODO: add write side effects for qualifiers
) and
@@ -380,8 +380,7 @@ private predicate modelFlow(Instruction iFrom, Instruction iTo) {
or
exists(int index, ReadSideEffectInstruction read |
modelIn.isParameterDeref(index) and
read.getIndex() = index and
read.getPrimaryInstruction() = call and
read = getSideEffectFor(call, index) and
iFrom = read.getSideEffectOperand().getAnyDef()
)
or
@@ -392,6 +391,18 @@ private predicate modelFlow(Instruction iFrom, Instruction iTo) {
)
}
/**
* Holds if the result is a side effect for instruction `call` on argument
* index `argument`. This helper predicate makes it easy to join on both of
* these columns at once, avoiding pathological join orders in case the
* argument index should get joined first.
*/
pragma[noinline]
SideEffectInstruction getSideEffectFor(CallInstruction call, int argument) {
call = result.getPrimaryInstruction() and
argument = result.(IndexedInstruction).getIndex()
}
/**
* Holds if data flows from `source` to `sink` in zero or more local
* (intra-procedural) steps.

View File

@@ -11,13 +11,19 @@ cached
private newtype TOperand =
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
(
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
or
tag instanceof UnmodeledUseOperandTag
)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap

View File

@@ -2,10 +2,10 @@ private import ValueNumberingImports
private import cpp
newtype TValueNumber =
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
variableAddressValueNumber(_, irFunc, var)
TVariableAddressValueNumber(IRFunction irFunc, Language::AST ast) {
variableAddressValueNumber(_, irFunc, ast)
} or
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
TInitializeParameterValueNumber(IRFunction irFunc, Language::AST var) {
initializeParameterValueNumber(_, irFunc, var)
} or
TInitializeThisValueNumber(IRFunction irFunc) { initializeThisValueNumber(_, irFunc) } or
@@ -100,17 +100,23 @@ private predicate numberableInstruction(Instruction instr) {
}
private predicate variableAddressValueNumber(
VariableAddressInstruction instr, IRFunction irFunc, IRVariable var
VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast
) {
instr.getEnclosingIRFunction() = irFunc and
instr.getIRVariable() = var
// The underlying AST element is used as value-numbering key instead of the
// `IRVariable` to work around a problem where a variable or expression with
// multiple types gives rise to multiple `IRVariable`s.
instr.getIRVariable().getAST() = ast
}
private predicate initializeParameterValueNumber(
InitializeParameterInstruction instr, IRFunction irFunc, IRVariable var
InitializeParameterInstruction instr, IRFunction irFunc, Language::AST var
) {
instr.getEnclosingIRFunction() = irFunc and
instr.getIRVariable() = var
// The underlying AST element is used as value-numbering key instead of the
// `IRVariable` to work around a problem where a variable or expression with
// multiple types gives rise to multiple `IRVariable`s.
instr.getIRVariable().getAST() = var
}
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
@@ -236,12 +242,12 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
exists(IRFunction irFunc |
irFunc = instr.getEnclosingIRFunction() and
(
exists(IRVariable var |
variableAddressValueNumber(instr, irFunc, var) and
result = TVariableAddressValueNumber(irFunc, var)
exists(Language::AST ast |
variableAddressValueNumber(instr, irFunc, ast) and
result = TVariableAddressValueNumber(irFunc, ast)
)
or
exists(IRVariable var |
exists(Language::AST var |
initializeParameterValueNumber(instr, irFunc, var) and
result = TInitializeParameterValueNumber(irFunc, var)
)

View File

@@ -220,9 +220,12 @@ class VariableMemoryLocation extends TVariableMemoryLocation, AllocationMemoryLo
/**
* Holds if this memory location covers the entire variable.
*/
final predicate coversEntireVariable() {
startBitOffset = 0 and
endBitOffset = var.getIRType().getByteSize() * 8
final predicate coversEntireVariable() { varIRTypeHasBitRange(startBitOffset, endBitOffset) }
pragma[noinline]
private predicate varIRTypeHasBitRange(int start, int end) {
start = 0 and
end = var.getIRType().getByteSize() * 8
}
}

View File

@@ -11,13 +11,19 @@ cached
private newtype TOperand =
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
(
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
or
tag instanceof UnmodeledUseOperandTag
)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap

View File

@@ -2,10 +2,10 @@ private import ValueNumberingImports
private import cpp
newtype TValueNumber =
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
variableAddressValueNumber(_, irFunc, var)
TVariableAddressValueNumber(IRFunction irFunc, Language::AST ast) {
variableAddressValueNumber(_, irFunc, ast)
} or
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
TInitializeParameterValueNumber(IRFunction irFunc, Language::AST var) {
initializeParameterValueNumber(_, irFunc, var)
} or
TInitializeThisValueNumber(IRFunction irFunc) { initializeThisValueNumber(_, irFunc) } or
@@ -100,17 +100,23 @@ private predicate numberableInstruction(Instruction instr) {
}
private predicate variableAddressValueNumber(
VariableAddressInstruction instr, IRFunction irFunc, IRVariable var
VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast
) {
instr.getEnclosingIRFunction() = irFunc and
instr.getIRVariable() = var
// The underlying AST element is used as value-numbering key instead of the
// `IRVariable` to work around a problem where a variable or expression with
// multiple types gives rise to multiple `IRVariable`s.
instr.getIRVariable().getAST() = ast
}
private predicate initializeParameterValueNumber(
InitializeParameterInstruction instr, IRFunction irFunc, IRVariable var
InitializeParameterInstruction instr, IRFunction irFunc, Language::AST var
) {
instr.getEnclosingIRFunction() = irFunc and
instr.getIRVariable() = var
// The underlying AST element is used as value-numbering key instead of the
// `IRVariable` to work around a problem where a variable or expression with
// multiple types gives rise to multiple `IRVariable`s.
instr.getIRVariable().getAST() = var
}
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
@@ -236,12 +242,12 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
exists(IRFunction irFunc |
irFunc = instr.getEnclosingIRFunction() and
(
exists(IRVariable var |
variableAddressValueNumber(instr, irFunc, var) and
result = TVariableAddressValueNumber(irFunc, var)
exists(Language::AST ast |
variableAddressValueNumber(instr, irFunc, ast) and
result = TVariableAddressValueNumber(irFunc, ast)
)
or
exists(IRVariable var |
exists(Language::AST var |
initializeParameterValueNumber(instr, irFunc, var) and
result = TInitializeParameterValueNumber(irFunc, var)
)

View File

@@ -11,13 +11,19 @@ cached
private newtype TOperand =
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
(
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
or
tag instanceof UnmodeledUseOperandTag
)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap

View File

@@ -2,10 +2,10 @@ private import ValueNumberingImports
private import cpp
newtype TValueNumber =
TVariableAddressValueNumber(IRFunction irFunc, IRVariable var) {
variableAddressValueNumber(_, irFunc, var)
TVariableAddressValueNumber(IRFunction irFunc, Language::AST ast) {
variableAddressValueNumber(_, irFunc, ast)
} or
TInitializeParameterValueNumber(IRFunction irFunc, IRVariable var) {
TInitializeParameterValueNumber(IRFunction irFunc, Language::AST var) {
initializeParameterValueNumber(_, irFunc, var)
} or
TInitializeThisValueNumber(IRFunction irFunc) { initializeThisValueNumber(_, irFunc) } or
@@ -100,17 +100,23 @@ private predicate numberableInstruction(Instruction instr) {
}
private predicate variableAddressValueNumber(
VariableAddressInstruction instr, IRFunction irFunc, IRVariable var
VariableAddressInstruction instr, IRFunction irFunc, Language::AST ast
) {
instr.getEnclosingIRFunction() = irFunc and
instr.getIRVariable() = var
// The underlying AST element is used as value-numbering key instead of the
// `IRVariable` to work around a problem where a variable or expression with
// multiple types gives rise to multiple `IRVariable`s.
instr.getIRVariable().getAST() = ast
}
private predicate initializeParameterValueNumber(
InitializeParameterInstruction instr, IRFunction irFunc, IRVariable var
InitializeParameterInstruction instr, IRFunction irFunc, Language::AST var
) {
instr.getEnclosingIRFunction() = irFunc and
instr.getIRVariable() = var
// The underlying AST element is used as value-numbering key instead of the
// `IRVariable` to work around a problem where a variable or expression with
// multiple types gives rise to multiple `IRVariable`s.
instr.getIRVariable().getAST() = var
}
private predicate initializeThisValueNumber(InitializeThisInstruction instr, IRFunction irFunc) {
@@ -236,12 +242,12 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
exists(IRFunction irFunc |
irFunc = instr.getEnclosingIRFunction() and
(
exists(IRVariable var |
variableAddressValueNumber(instr, irFunc, var) and
result = TVariableAddressValueNumber(irFunc, var)
exists(Language::AST ast |
variableAddressValueNumber(instr, irFunc, ast) and
result = TVariableAddressValueNumber(irFunc, ast)
)
or
exists(IRVariable var |
exists(Language::AST var |
initializeParameterValueNumber(instr, irFunc, var) and
result = TInitializeParameterValueNumber(irFunc, var)
)

View File

@@ -94,6 +94,22 @@ abstract class FunctionWithWrappers extends Function {
)
}
/**
* Whether 'func' is a (possibly nested) wrapper function that feeds a parameter at the given index
* through to an interesting parameter of 'this' function.
*
* The 'cause' gives the name of 'this' interesting function and its relevant parameter
* at the end of the call chain.
*
* If there is more than one possible 'cause', a unique one is picked (by lexicographic order).
*/
pragma[nomagic]
private string wrapperFunctionAnyDepthUnique(Function func, int paramIndex) {
result =
toCause(func, paramIndex) + ", which ends up calling " +
min(string targetCause | this.wrapperFunctionAnyDepth(func, paramIndex, targetCause))
}
/**
* Whether 'func' is a (possibly nested) wrapper function that feeds a parameter at the given index
* through to an interesting parameter of 'this' function.
@@ -114,13 +130,7 @@ abstract class FunctionWithWrappers extends Function {
)
or
not this.wrapperFunctionLimitedDepth(func, paramIndex, _, _) and
cause =
min(string targetCause, string possibleCause |
this.wrapperFunctionAnyDepth(func, paramIndex, targetCause) and
possibleCause = toCause(func, paramIndex) + ", which ends up calling " + targetCause
|
possibleCause
)
cause = wrapperFunctionAnyDepthUnique(func, paramIndex)
}
/**

View File

@@ -5,6 +5,7 @@
| test.c:49:20:49:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:24:35:24:40 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:45:28:45:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:55:28:55:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:63:28:63:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:71:28:71:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:79:28:79:33 | call to malloc | This allocation does not include space to null-terminate the string. |

View File

@@ -51,7 +51,7 @@ void decode(char *dest, char *src);
void wdecode(wchar_t *dest, wchar_t *src);
void bad4(char *str) {
// BAD -- zero-termination proved by wprintf (as parameter) [NOT DETECTED]
// BAD -- zero-termination proved by wprintf (as parameter)
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
wprintf(L"%s", buffer);
@@ -107,3 +107,19 @@ void bad9(wchar_t *wstr) {
wcscpy(wbuffer, wstr);
delete wbuffer;
}
void good3(char *str) {
// GOOD -- zero-termination not required for this printf
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
wprintf(L"%p", buffer);
free(buffer);
}
void good4(char *str) {
// GOOD -- zero-termination not required for this printf
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
wprintf(L"%.*s", strlen(str), buffer);
free(buffer);
}

View File

@@ -90,9 +90,29 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
public override InitializerExpressionSyntax Initializer => Syntax.Initializer;
protected override void PopulateExpression(TextWriter trapFile)
{
base.PopulateExpression(trapFile);
trapFile.stackalloc_array_creation(this);
}
public static Expression Create(ExpressionNodeInfo info) => new StackAllocArrayCreation(info).TryPopulate();
}
class ImplicitStackAllocArrayCreation : ArrayCreation<ImplicitStackAllocArrayCreationExpressionSyntax>
{
ImplicitStackAllocArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }
public static Expression Create(ExpressionNodeInfo info) => new ImplicitStackAllocArrayCreation(info).TryPopulate();
protected override void PopulateExpression(TextWriter trapFile)
{
ArrayInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1));
trapFile.implicitly_typed_array_creation(this);
trapFile.stackalloc_array_creation(this);
}
}
class ImplicitArrayCreation : ArrayCreation<ImplicitArrayCreationExpressionSyntax>
{
ImplicitArrayCreation(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.ARRAY_CREATION)) { }

View File

@@ -207,6 +207,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
case SyntaxKind.StackAllocArrayCreationExpression:
return StackAllocArrayCreation.Create(info);
case SyntaxKind.ImplicitStackAllocArrayCreationExpression:
return ImplicitStackAllocArrayCreation.Create(info);
case SyntaxKind.ArgListExpression:
return ArgList.Create(info);

View File

@@ -1,3 +1,4 @@
using System;
using System.IO;
using Microsoft.CodeAnalysis;
@@ -9,10 +10,12 @@ namespace Semmle.Extraction.CSharp.Entities
public override void WriteId(TextWriter trapFile)
{
trapFile.WriteSubId(Location);
trapFile.Write('_');
trapFile.Write(symbol.Name);
trapFile.Write(";localvar");
throw new InvalidOperationException();
}
public override void WriteQuotedId(TextWriter trapFile)
{
trapFile.Write('*');
}
public override void Populate(TextWriter trapFile) { }

View File

@@ -466,6 +466,11 @@ namespace Semmle.Extraction.CSharp
trapFile.WriteTuple("specific_type_parameter_nullability", constraints, baseType, nullability);
}
internal static void stackalloc_array_creation(this TextWriter trapFile, Expression array)
{
trapFile.WriteTuple("stackalloc_array_creation", array);
}
internal static void stmt_location(this TextWriter trapFile, Statement stmt, Location location)
{
trapFile.WriteTuple("stmt_location", stmt, location);

View File

@@ -53,7 +53,7 @@ namespace Semmle.Extraction
public abstract void WriteId(System.IO.TextWriter trapFile);
public void WriteQuotedId(TextWriter trapFile)
public virtual void WriteQuotedId(TextWriter trapFile)
{
trapFile.Write("@\"");
WriteId(trapFile);

View File

@@ -11,6 +11,7 @@
import semmle.code.csharp.serialization.Serialization
import semmle.code.csharp.controlflow.Guards
import semmle.code.csharp.dataflow.DataFlow
/**
* The result is a write to the field `f`, assigning it the value
@@ -29,7 +30,11 @@ GuardedExpr checkedWrite(Field f, Variable v, IfStmt check) {
Expr uncheckedWrite(Callable callable, Field f) {
result = f.getAnAssignedValue() and
result.getEnclosingCallable() = callable and
not callable.calls*(checkedWrite(f, _, _).getEnclosingCallable())
not callable.calls*(checkedWrite(f, _, _).getEnclosingCallable()) and
// Exclude object creations because they were not deserialized
not exists(Expr src | DataFlow::localExprFlow(src, result) |
src instanceof ObjectCreation or src.hasValue()
)
}
from BinarySerializableType t, Field f, IfStmt check, Expr write, Expr unsafeWrite

View File

@@ -372,6 +372,13 @@ class ArrayCreation extends Expr, @array_creation_expr {
override string toString() { result = "array creation of type " + this.getType().getName() }
}
/**
* A `stackalloc` array creation, for example `stackalloc char[] { 'x', 'y' }`.
*/
class Stackalloc extends ArrayCreation {
Stackalloc() { stackalloc_array_creation(this) }
}
/**
* An anonymous function. Either a lambda expression (`LambdaExpr`) or an
* anonymous method expression (`AnonymousMethodExpr`).

View File

@@ -11,13 +11,19 @@ cached
private newtype TOperand =
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
(
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
or
tag instanceof UnmodeledUseOperandTag
)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap

View File

@@ -11,13 +11,19 @@ cached
private newtype TOperand =
TRegisterOperand(Instruction useInstr, RegisterOperandTag tag, Instruction defInstr) {
defInstr = Construction::getRegisterOperandDefinition(useInstr, tag) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
strictcount(Construction::getRegisterOperandDefinition(useInstr, tag)) = 1
} or
TNonPhiMemoryOperand(
Instruction useInstr, MemoryOperandTag tag, Instruction defInstr, Overlap overlap
) {
defInstr = Construction::getMemoryOperandDefinition(useInstr, tag, overlap) and
not Construction::isInCycle(useInstr)
not Construction::isInCycle(useInstr) and
(
strictcount(Construction::getMemoryOperandDefinition(useInstr, tag, _)) = 1
or
tag instanceof UnmodeledUseOperandTag
)
} or
TPhiOperand(
PhiInstruction useInstr, Instruction defInstr, IRBlock predecessorBlock, Overlap overlap

View File

@@ -1084,6 +1084,9 @@ implicitly_typed_array_creation(
explicitly_sized_array_creation(
unique int id: @array_creation_expr ref);
stackalloc_array_creation(
unique int id: @array_creation_expr ref);
mutator_invocation_mode(
unique int id: @operator_invocation_expr ref,
int mode: int ref /* prefix = 1, postfix = 2*/);

View File

@@ -28440,6 +28440,17 @@
<dependencies/>
</relation>
<relation>
<name>stackalloc_array_creation</name>
<cardinality>50</cardinality>
<columnsizes>
<e>
<k>id</k>
<v>50</v>
</e>
</columnsizes>
<dependencies/>
</relation>
<relation>
<name>mutator_invocation_mode</name>
<cardinality>0</cardinality>
<columnsizes>

View File

@@ -1,6 +1,20 @@
arrayCreation
| csharp73.cs:9:20:9:49 | array creation of type Char* | 0 | csharp73.cs:9:20:9:49 | 2 |
| csharp73.cs:10:20:10:45 | array creation of type Char* | 0 | csharp73.cs:10:36:10:36 | 1 |
| csharp73.cs:11:20:11:37 | array creation of type Char[] | 0 | csharp73.cs:11:20:11:37 | 1 |
| csharp73.cs:12:20:12:38 | array creation of type Char* | 0 | csharp73.cs:12:36:12:37 | 10 |
| csharp73.cs:13:20:13:31 | array creation of type Char[] | 0 | csharp73.cs:13:29:13:30 | 10 |
| csharp73.cs:21:23:21:33 | array creation of type Int32[] | 0 | csharp73.cs:21:31:21:32 | 10 |
| csharp73.cs:22:23:22:33 | array creation of type Int32[] | 0 | csharp73.cs:22:31:22:32 | 10 |
arrayElement
| csharp73.cs:9:20:9:49 | array creation of type Char* | 0 | csharp73.cs:9:40:9:42 | x |
| csharp73.cs:9:20:9:49 | array creation of type Char* | 1 | csharp73.cs:9:45:9:47 | y |
| csharp73.cs:10:20:10:45 | array creation of type Char* | 0 | csharp73.cs:10:41:10:43 | x |
| csharp73.cs:11:20:11:37 | array creation of type Char[] | 0 | csharp73.cs:11:33:11:35 | x |
| csharp73.cs:14:20:14:43 | array creation of type Int32* | 0 | csharp73.cs:14:35:14:35 | 1 |
| csharp73.cs:14:20:14:43 | array creation of type Int32* | 1 | csharp73.cs:14:38:14:38 | 2 |
| csharp73.cs:14:20:14:43 | array creation of type Int32* | 2 | csharp73.cs:14:41:14:41 | 3 |
stackalloc
| csharp73.cs:9:20:9:49 | array creation of type Char* |
| csharp73.cs:10:20:10:45 | array creation of type Char* |
| csharp73.cs:12:20:12:38 | array creation of type Char* |
| csharp73.cs:14:20:14:43 | array creation of type Int32* |

View File

@@ -1,4 +1,11 @@
import csharp
from ArrayCreation creation, int i
select creation, i, creation.getLengthArgument(i)
query predicate arrayCreation(ArrayCreation creation, int i, Expr length) {
length = creation.getLengthArgument(i)
}
query predicate arrayElement(ArrayCreation array, int i, Expr element) {
element = array.getInitializer().getElement(i)
}
query predicate stackalloc(Stackalloc a) { any() }

View File

@@ -1,4 +0,0 @@
| csharp73.cs:9:20:9:49 | array creation of type Char* | 0 | csharp73.cs:9:40:9:42 | x |
| csharp73.cs:9:20:9:49 | array creation of type Char* | 1 | csharp73.cs:9:45:9:47 | y |
| csharp73.cs:10:20:10:45 | array creation of type Char* | 0 | csharp73.cs:10:41:10:43 | x |
| csharp73.cs:11:20:11:37 | array creation of type Char[] | 0 | csharp73.cs:11:33:11:35 | x |

View File

@@ -1,4 +0,0 @@
import csharp
from ArrayCreation array, int i
select array, i, array.getInitializer().getElement(i)

View File

@@ -11,6 +11,7 @@ class StackAllocs
var arr3 = new char[] { 'x' };
var arr4 = stackalloc char[10];
var arr5 = new char[10];
var arr6 = stackalloc[] { 1, 2, 3 };
}
}

View File

@@ -10,14 +10,14 @@ public class Test1
{
if (v == "valid")
{
f = v /* safe write */;
f = v; // GOOD
}
}
[OnDeserializing]
public void Deserialize()
{
f = "invalid" /* unsafe write */;
f = $"invalid"; // BAD
}
}
@@ -30,19 +30,19 @@ public class Test2
{
if (v == "valid")
{
f = v /* safe write */;
f = v; // GOOD
}
}
[OnDeserializing]
public void Deserialize()
{
var v = "invalid";
f = v /* unsafe write -- false negative */;
var v = $"invalid";
f = v; // BAD: False negative
if (v == "valid")
{
f = v; /* safe write */
f = v; // GOOD
}
}
}
@@ -56,25 +56,25 @@ public class Test3
{
if (v == "valid")
{
f = v /* safe write */;
f = v; // GOOD
}
}
[OnDeserializing]
public void Deserialize()
{
var v = "invalid";
f = v /* unsafe write -- false negative */;
var v = $"invalid";
f = v; // GOOD: False negative
Assign(v);
}
private void Assign(string v)
{
f = v /* unsafe write -- false negative */;
f = v; // GOOD: False negative
if (v == "valid")
{
f = v /* safe write */;
f = v; // GOOD
}
}
}
@@ -88,21 +88,21 @@ public class Test4
{
if (v == "valid")
{
f = v /* safe write */;
f = v; // GOOD
}
}
[OnDeserializing]
public void Deserialize()
{
var v = "invalid";
var v = $"invalid";
if (v == "valid")
Assign(v);
}
private void Assign(string v)
{
f = v /* safe write */;
f = v; // GOOD
}
}
@@ -115,13 +115,13 @@ public class Test5 : ISerializable
{
if (age < 0)
throw new ArgumentException(nameof(age));
Age = age /* safe write */;
Age = age; // GOOD
}
[OnDeserializing]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
Age = info.GetInt32("age"); /* unsafe write */;
Age = info.GetInt32("age"); // BAD
}
}
@@ -134,7 +134,7 @@ public class Test6 : ISerializable
{
if (age < 0)
throw new ArgumentException(nameof(age));
Age = age /* safe write */;
Age = age; // GOOD
}
[OnDeserializing]
@@ -143,7 +143,7 @@ public class Test6 : ISerializable
int age = info.GetInt32("age");
if (age < 0)
throw new SerializationException("age");
Age = age; /* safe write */;
Age = age; // GOOD
}
}
@@ -156,7 +156,7 @@ public class Test7 : ISerializable
{
if (age < 0)
throw new ArgumentException(nameof(age));
Age = age /* safe write */;
Age = age; // GOOD
}
[OnDeserializing]
@@ -165,6 +165,27 @@ public class Test7 : ISerializable
int age = info.GetInt32("age");
if (false)
throw new SerializationException("age");
Age = age; /* unsafe write */;
Age = age; // BAD
}
}
[Serializable]
public class Test8 : ISerializable
{
string Options;
public int Age;
public Test8(string options)
{
if (options == null)
throw new ArgumentNullException(nameof(options));
Options = options; // GOOD
}
[OnDeserializing]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
Options = new string(""); // GOOD: A created object
}
}

View File

@@ -1,4 +1,4 @@
| RuntimeChecksBypass.cs:20:13:20:21 | "invalid" | This write to $@ may be circumventing a $@. | RuntimeChecksBypass.cs:7:19:7:19 | f | f | RuntimeChecksBypass.cs:11:9:14:9 | if (...) ... | check |
| RuntimeChecksBypass.cs:20:13:20:22 | $"..." | This write to $@ may be circumventing a $@. | RuntimeChecksBypass.cs:7:19:7:19 | f | f | RuntimeChecksBypass.cs:11:9:14:9 | if (...) ... | check |
| RuntimeChecksBypass.cs:124:15:124:34 | call to method GetInt32 | This write to $@ may be circumventing a $@. | RuntimeChecksBypass.cs:112:16:112:18 | Age | Age | RuntimeChecksBypass.cs:116:9:117:53 | if (...) ... | check |
| RuntimeChecksBypass.cs:168:15:168:17 | access to local variable age | This write to $@ may be circumventing a $@. | RuntimeChecksBypass.cs:153:16:153:18 | Age | Age | RuntimeChecksBypass.cs:157:9:158:53 | if (...) ... | check |
| RuntimeChecksBypassBad.cs:19:15:19:34 | call to method GetInt32 | This write to $@ may be circumventing a $@. | RuntimeChecksBypassBad.cs:7:16:7:18 | Age | Age | RuntimeChecksBypassBad.cs:11:9:12:53 | if (...) ... | check |

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Adds information about `stackalloc` array creations
compatibility: backwards

View File

@@ -113,7 +113,7 @@ Then we can make the source more specific, for example an access to a public par
where
fileReader.getDeclaringType().hasQualifiedName("java.io", "FileReader") and
call.getCallee() = fileReader and
DataFlow::localFlow(DataFlow::parameterNode(p), DataFlow::exprNode(fc.getArgument(0)))
DataFlow::localFlow(DataFlow::parameterNode(p), DataFlow::exprNode(call.getArgument(0)))
select p
The following example finds calls to formatting functions where the format string is not hard-coded.

View File

@@ -502,7 +502,7 @@ Identifiers are used in following syntactic constructs:
simpleId ::= lowerId | upperId
modulename ::= simpleId
classname ::= upperId
dbasetype ::= atlowerId
dbasetype ::= atLowerId
predicateRef ::= (moduleId "::")? literalId
predicateName ::= lowerId
varname ::= simpleId
@@ -1804,7 +1804,7 @@ The complete grammar for QL is as follows:
::
ql ::= moduleBody ;
ql ::= moduleBody
module ::= annotation* "module" modulename "{" moduleBody "}"
@@ -1976,11 +1976,11 @@ The complete grammar for QL is as follows:
simpleId ::= lowerId | upperId
modulename :: = simpleId
modulename ::= simpleId
classname ::= upperId
dbasetype ::= atlowerId
dbasetype ::= atLowerId
predicateRef ::= (moduleId "::")? literalId

View File

@@ -21,7 +21,7 @@ class BottleRequestKind extends TaintKind {
}
}
private class RequestSource extends TaintSource {
private class RequestSource extends HttpRequestTaintSource {
RequestSource() { this.(ControlFlowNode).pointsTo(theBottleRequestObject()) }
override predicate isSourceOf(TaintKind kind) { kind instanceof BottleRequestKind }
@@ -69,7 +69,7 @@ class UntrustedFile extends TaintKind {
// Move UntrustedFile to shared location
//
/** Parameter to a bottle request handler function */
class BottleRequestParameter extends TaintSource {
class BottleRequestParameter extends HttpRequestTaintSource {
BottleRequestParameter() {
exists(BottleRoute route | route.getNamedArgument() = this.(ControlFlowNode).getNode())
}

View File

@@ -25,7 +25,7 @@ class CherryPyRequest extends TaintKind {
}
}
class CherryPyExposedFunctionParameter extends TaintSource {
class CherryPyExposedFunctionParameter extends HttpRequestTaintSource {
CherryPyExposedFunctionParameter() {
exists(Parameter p |
p = any(CherryPyExposedFunction f).getAnArg() and
@@ -39,7 +39,7 @@ class CherryPyExposedFunctionParameter extends TaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
}
class CherryPyRequestSource extends TaintSource {
class CherryPyRequestSource extends HttpRequestTaintSource {
CherryPyRequestSource() { this.(ControlFlowNode).pointsTo(Value::named("cherrypy.request")) }
override predicate isSourceOf(TaintKind kind) { kind instanceof CherryPyRequest }

View File

@@ -18,8 +18,8 @@ private ClassValue theDjangoHttpResponseClass() {
not result = theDjangoHttpRedirectClass()
}
/** Instantiation of a django response. */
class DjangoResponseSource extends TaintSource {
/** internal class used for tracking a django response. */
private class DjangoResponseSource extends TaintSource {
DjangoResponseSource() {
exists(ClassValue cls |
cls.getASuperType() = theDjangoHttpResponseClass() and

View File

@@ -35,7 +35,7 @@ class FalconRequest extends TaintKind {
}
}
class FalconRequestParameter extends TaintSource {
class FalconRequestParameter extends HttpRequestTaintSource {
FalconRequestParameter() {
exists(FalconHandlerFunction f | f.getRequest() = this.(ControlFlowNode).getNode())
}

View File

@@ -9,7 +9,8 @@ class FalconResponse extends TaintKind {
FalconResponse() { this = "falcon.response" }
}
class FalconResponseParameter extends TaintSource {
/** Only used internally to track the response parameter */
private class FalconResponseParameter extends TaintSource {
FalconResponseParameter() {
exists(FalconHandlerFunction f | f.getResponse() = this.(ControlFlowNode).getNode())
}

View File

@@ -47,7 +47,7 @@ class FlaskRequestArgs extends HttpRequestTaintSource {
}
/** Source of dictionary whose values are externally controlled */
class FlaskRequestJson extends TaintSource {
class FlaskRequestJson extends HttpRequestTaintSource {
FlaskRequestJson() { flask_request_attr(this, "json") }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalJsonKind }

View File

@@ -11,7 +11,7 @@ class PyramidRequest extends BaseWebobRequest {
}
/** Source of pyramid request objects */
class PyramidViewArgument extends TaintSource {
class PyramidViewArgument extends HttpRequestTaintSource {
PyramidViewArgument() {
exists(Function view_func |
is_pyramid_view_function(view_func) and

View File

@@ -13,14 +13,16 @@ import Tornado
/**
* Represents an argument to the `tornado.redirect` function.
*/
class TornadoRedirect extends HttpRedirectTaintSink {
override string toString() { result = "tornado.redirect" }
class TornadoHttpRequestHandlerRedirect extends HttpRedirectTaintSink {
override string toString() { result = "tornado.HttpRequestHandler.redirect" }
TornadoRedirect() {
TornadoHttpRequestHandlerRedirect() {
exists(CallNode call, ControlFlowNode node |
node = call.getFunction().(AttrNode).getObject("redirect") and
isTornadoRequestHandlerInstance(node) and
this = call.getAnArg()
this = call.getArg(0)
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}

View File

@@ -30,7 +30,7 @@ class TornadoRequest extends TaintKind {
}
}
class TornadoRequestSource extends TaintSource {
class TornadoRequestSource extends HttpRequestTaintSource {
TornadoRequestSource() { isTornadoRequestHandlerInstance(this.(AttrNode).getObject("request")) }
override string toString() { result = "Tornado request source" }
@@ -38,7 +38,7 @@ class TornadoRequestSource extends TaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoRequest }
}
class TornadoExternalInputSource extends TaintSource {
class TornadoExternalInputSource extends HttpRequestTaintSource {
TornadoExternalInputSource() {
exists(string name |
name = "get_argument" or
@@ -55,7 +55,7 @@ class TornadoExternalInputSource extends TaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
}
class TornadoExternalInputListSource extends TaintSource {
class TornadoExternalInputListSource extends HttpRequestTaintSource {
TornadoExternalInputListSource() {
exists(string name |
name = "get_arguments" or

View File

@@ -24,11 +24,8 @@ class TornadoConnectionWrite extends HttpResponseTaintSink {
TornadoConnectionWrite() {
exists(CallNode call, ControlFlowNode conn |
conn = call.getFunction().(AttrNode).getObject("write") and
this = call.getAnArg()
|
this = call.getAnArg() and
exists(TornadoConnection tc | tc.taints(conn))
or
isTornadoRequestHandlerInstance(conn)
)
}
@@ -36,27 +33,13 @@ class TornadoConnectionWrite extends HttpResponseTaintSink {
}
class TornadoHttpRequestHandlerWrite extends HttpResponseTaintSink {
override string toString() { result = "tornado.HttpRequesHandler.write" }
override string toString() { result = "tornado.HttpRequestHandler.write" }
TornadoHttpRequestHandlerWrite() {
exists(CallNode call, ControlFlowNode node |
node = call.getFunction().(AttrNode).getObject("write") and
isTornadoRequestHandlerInstance(node) and
this = call.getAnArg()
)
}
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}
class TornadoHttpRequestHandlerRedirect extends HttpResponseTaintSink {
override string toString() { result = "tornado.HttpRequesHandler.redirect" }
TornadoHttpRequestHandlerRedirect() {
exists(CallNode call, ControlFlowNode node |
node = call.getFunction().(AttrNode).getObject("redirect") and
isTornadoRequestHandlerInstance(node) and
this = call.getArg(0)
this = call.getAnArg() and
isTornadoRequestHandlerInstance(node)
)
}

View File

@@ -1,5 +1,6 @@
import python
import semmle.python.security.strings.Untrusted
import semmle.python.web.Http
import TurboGears
private class ValidatedMethodParameter extends Parameter {
@@ -11,7 +12,7 @@ private class ValidatedMethodParameter extends Parameter {
}
}
class UnvalidatedControllerMethodParameter extends TaintSource {
class UnvalidatedControllerMethodParameter extends HttpRequestTaintSource {
UnvalidatedControllerMethodParameter() {
exists(Parameter p |
any(TurboGearsControllerMethod m | not m.getName() = "onerror").getAnArg() = p and

View File

@@ -5,6 +5,8 @@ import semmle.python.web.Http
import TurboGears
class ControllerMethodReturnValue extends HttpResponseTaintSink {
override string toString() { result = "TurboGears ControllerMethodReturnValue" }
ControllerMethodReturnValue() {
exists(TurboGearsControllerMethod m |
m.getAReturnValueFlowNode() = this and
@@ -16,6 +18,8 @@ class ControllerMethodReturnValue extends HttpResponseTaintSink {
}
class ControllerMethodTemplatedReturnValue extends HttpResponseTaintSink {
override string toString() { result = "TurboGears ControllerMethodTemplatedReturnValue" }
ControllerMethodTemplatedReturnValue() {
exists(TurboGearsControllerMethod m |
m.getAReturnValueFlowNode() = this and

View File

@@ -26,7 +26,7 @@ class TwistedRequest extends TaintKind {
}
}
class TwistedRequestSource extends TaintSource {
class TwistedRequestSource extends HttpRequestTaintSource {
TwistedRequestSource() { isTwistedRequestInstance(this) }
override string toString() { result = "Twisted request source" }

View File

@@ -5,9 +5,9 @@ import semmle.python.security.strings.Basic
import Twisted
import Request
class TwistedResponse extends TaintSink {
class TwistedResponse extends HttpResponseTaintSink {
TwistedResponse() {
exists(PythonFunctionValue func, string name, Return ret |
exists(PythonFunctionValue func, string name |
isKnownRequestHandlerMethodName(name) and
name = func.getName() and
func = getTwistedRequestHandlerMethod(name) and

View File

@@ -1,2 +1,2 @@
semmle-extractor-options: --lang=2 --max-import-depth=3
semmle-extractor-options: --lang=2 --max-import-depth=4
optimize: true

View File

@@ -1,3 +1,9 @@
| six | Module six |
| six.moves | Module six.moves |
| six | Package six |
| six.moves | Package six.moves |
| six.moves.http_client | Module httplib |
| six.moves.http_client.HTTPConnection | class HTTPConnection |
| six.moves.range | builtin-class xrange |
| six.moves.urllib | Package six.moves.urllib |
| six.moves.urllib.parse | Module six.moves.urllib_parse |
| six.moves.urllib.parse.urlsplit | Function urlsplit |
| six.moves.zip | builtin-class itertools.izip |

View File

@@ -1,15 +1,11 @@
import python
string longname(Expr e) {
result = e.(Name).getId()
or
exists(Attribute a |
a = e |
result = longname(a.getObject()) + "." + a.getName()
)
exists(Attribute a | a = e | result = longname(a.getObject()) + "." + a.getName())
}
from Expr e, Object o
where e.refersTo(o) and e.getLocation().getFile().getShortName() = "test.py"
select longname(e), o.toString()
from Expr e, Value v
where e.pointsTo(v) and e.getLocation().getFile().getShortName() = "test.py"
select longname(e), v.toString()

View File

@@ -1,268 +0,0 @@
| Module six | BytesIO | class StringIO |
| Module six | Iterator | class Iterator |
| Module six | MAXSIZE | int() |
| Module six | PY2 | bool True |
| Module six | PY3 | bool False |
| Module six | StringIO | class StringIO |
| Module six | __author__ | str b'Benjamin Peterson <benjamin@python.org>' |
| Module six | __name__ | str b'six' |
| Module six | __version__ | str b'1.5.2' |
| Module six | _add_doc | Function _add_doc |
| Module six | _func_closure | str b'func_closure' |
| Module six | _func_code | str b'func_code' |
| Module six | _func_defaults | str b'func_defaults' |
| Module six | _func_globals | str b'func_globals' |
| Module six | _import_module | Function _import_module |
| Module six | _iteritems | str b'iteritems' |
| Module six | _iterkeys | str b'iterkeys' |
| Module six | _iterlists | str b'iterlists' |
| Module six | _itervalues | str b'itervalues' |
| Module six | _meth_func | str b'im_func' |
| Module six | _meth_self | str b'im_self' |
| Module six | add_metaclass | Function add_metaclass |
| Module six | add_move | Function add_move |
| Module six | advance_iterator | Builtin-function next |
| Module six | b | Function b |
| Module six | binary_type | builtin-class str |
| Module six | byte2int | Function byte2int |
| Module six | callable | Builtin-function callable |
| Module six | callable | Function callable |
| Module six | class_types | Tuple |
| Module six | create_bound_method | Function create_bound_method |
| Module six | exec_ | Function exec_ |
| Module six | get_function_closure | Attribute() |
| Module six | get_function_code | Attribute() |
| Module six | get_function_defaults | Attribute() |
| Module six | get_function_globals | Attribute() |
| Module six | get_method_function | Attribute() |
| Module six | get_method_self | Attribute() |
| Module six | get_unbound_function | Function get_unbound_function |
| Module six | indexbytes | Function indexbytes |
| Module six | int2byte | Builtin-function chr |
| Module six | integer_types | Tuple |
| Module six | iterbytes | Function iterbytes |
| Module six | iteritems | Function iteritems |
| Module six | iterkeys | Function iterkeys |
| Module six | iterlists | Function iterlists |
| Module six | itervalues | Function itervalues |
| Module six | moves | Module six.moves |
| Module six | next | Builtin-function next |
| Module six | operator | Module operator |
| Module six | print_ | Function print_ |
| Module six | remove_move | Function remove_move |
| Module six | reraise | Function reraise |
| Module six | string_types | Tuple |
| Module six | sys | Module sys |
| Module six | text_type | builtin-class unicode |
| Module six | types | Module types |
| Module six | u | Function u |
| Module six | unichr | Builtin-function unichr |
| Module six | with_metaclass | Function with_metaclass |
| Module six.__init__ | BytesIO | class StringIO |
| Module six.__init__ | Iterator | class Iterator |
| Module six.__init__ | MAXSIZE | int() |
| Module six.__init__ | PY2 | bool True |
| Module six.__init__ | PY3 | bool False |
| Module six.__init__ | StringIO | class StringIO |
| Module six.__init__ | __author__ | str b'Benjamin Peterson <benjamin@python.org>' |
| Module six.__init__ | __name__ | str b'six' |
| Module six.__init__ | __version__ | str b'1.5.2' |
| Module six.__init__ | _add_doc | Function _add_doc |
| Module six.__init__ | _func_closure | str b'func_closure' |
| Module six.__init__ | _func_code | str b'func_code' |
| Module six.__init__ | _func_defaults | str b'func_defaults' |
| Module six.__init__ | _func_globals | str b'func_globals' |
| Module six.__init__ | _import_module | Function _import_module |
| Module six.__init__ | _iteritems | str b'iteritems' |
| Module six.__init__ | _iterkeys | str b'iterkeys' |
| Module six.__init__ | _iterlists | str b'iterlists' |
| Module six.__init__ | _itervalues | str b'itervalues' |
| Module six.__init__ | _meth_func | str b'im_func' |
| Module six.__init__ | _meth_self | str b'im_self' |
| Module six.__init__ | add_metaclass | Function add_metaclass |
| Module six.__init__ | add_move | Function add_move |
| Module six.__init__ | advance_iterator | Builtin-function next |
| Module six.__init__ | b | Function b |
| Module six.__init__ | binary_type | builtin-class str |
| Module six.__init__ | byte2int | Function byte2int |
| Module six.__init__ | callable | Builtin-function callable |
| Module six.__init__ | callable | Function callable |
| Module six.__init__ | class_types | Tuple |
| Module six.__init__ | create_bound_method | Function create_bound_method |
| Module six.__init__ | exec_ | Function exec_ |
| Module six.__init__ | get_function_closure | Attribute() |
| Module six.__init__ | get_function_code | Attribute() |
| Module six.__init__ | get_function_defaults | Attribute() |
| Module six.__init__ | get_function_globals | Attribute() |
| Module six.__init__ | get_method_function | Attribute() |
| Module six.__init__ | get_method_self | Attribute() |
| Module six.__init__ | get_unbound_function | Function get_unbound_function |
| Module six.__init__ | indexbytes | Function indexbytes |
| Module six.__init__ | int2byte | Builtin-function chr |
| Module six.__init__ | integer_types | Tuple |
| Module six.__init__ | iterbytes | Function iterbytes |
| Module six.__init__ | iteritems | Function iteritems |
| Module six.__init__ | iterkeys | Function iterkeys |
| Module six.__init__ | iterlists | Function iterlists |
| Module six.__init__ | itervalues | Function itervalues |
| Module six.__init__ | moves | Module six.moves |
| Module six.__init__ | next | Builtin-function next |
| Module six.__init__ | operator | Module operator |
| Module six.__init__ | print_ | Function print_ |
| Module six.__init__ | remove_move | Function remove_move |
| Module six.__init__ | reraise | Function reraise |
| Module six.__init__ | string_types | Tuple |
| Module six.__init__ | sys | Module sys |
| Module six.__init__ | text_type | builtin-class unicode |
| Module six.__init__ | types | Module types |
| Module six.__init__ | u | Function u |
| Module six.__init__ | unichr | Builtin-function unichr |
| Module six.__init__ | with_metaclass | Function with_metaclass |
| Module six.moves | BaseHTTPServer | Module BaseHTTPServer |
| Module six.moves | CGIHTTPServer | Module CGIHTTPServer |
| Module six.moves | PY2 | bool True |
| Module six.moves | PY3 | bool False |
| Module six.moves | SimpleHTTPServer | Module SimpleHTTPServer |
| Module six.moves | StringIO | class StringIO |
| Module six.moves | UserDict | class UserDict |
| Module six.moves | UserList | class UserList |
| Module six.moves | UserString | class UserString |
| Module six.moves | __name__ | str b'six.moves' |
| Module six.moves | _dummy_thread | Module dummy_thread |
| Module six.moves | _thread | Module thread |
| Module six.moves | builtins | Module __builtin__ |
| Module six.moves | cPickle | Module cPickle |
| Module six.moves | cStringIO | Builtin-function StringIO |
| Module six.moves | configparser | Module ConfigParser |
| Module six.moves | copyreg | Module copy_reg |
| Module six.moves | filter | builtin-class itertools.ifilter |
| Module six.moves | filterfalse | builtin-class itertools.ifilterfalse |
| Module six.moves | html_entities | Module htmlentitydefs |
| Module six.moves | html_parser | Module HTMLParser |
| Module six.moves | http_client | Module httplib |
| Module six.moves | http_cookiejar | Module cookielib |
| Module six.moves | http_cookies | Module Cookie |
| Module six.moves | input | Builtin-function raw_input |
| Module six.moves | intern | Builtin-function intern |
| Module six.moves | map | builtin-class itertools.imap |
| Module six.moves | queue | Module Queue |
| Module six.moves | range | builtin-class xrange |
| Module six.moves | reduce | Builtin-function reduce |
| Module six.moves | reload_module | Builtin-function reload |
| Module six.moves | reprlib | Module repr |
| Module six.moves | shlex_quote | Function quote |
| Module six.moves | socketserver | Module SocketServer |
| Module six.moves | tkinter | Module Tkinter |
| Module six.moves | tkinter_colorchooser | Module tkColorChooser |
| Module six.moves | tkinter_commondialog | Module tkCommonDialog |
| Module six.moves | tkinter_constants | Module Tkconstants |
| Module six.moves | tkinter_dialog | Module Dialog |
| Module six.moves | tkinter_dnd | Module Tkdnd |
| Module six.moves | tkinter_filedialog | Module FileDialog |
| Module six.moves | tkinter_font | Module tkFont |
| Module six.moves | tkinter_messagebox | Module tkMessageBox |
| Module six.moves | tkinter_scrolledtext | Module ScrolledText |
| Module six.moves | tkinter_simpledialog | Module SimpleDialog |
| Module six.moves | tkinter_tix | Module Tix |
| Module six.moves | tkinter_tkfiledialog | Module tkFileDialog |
| Module six.moves | tkinter_tksimpledialog | Module tkSimpleDialog |
| Module six.moves | tkinter_ttk | Module ttk |
| Module six.moves | urllib | Module six.moves.urllib |
| Module six.moves | urllib_error | Module six.moves.urllib_error |
| Module six.moves | urllib_parse | Module six.moves.urllib_parse |
| Module six.moves | urllib_request | Module six.moves.urllib_request |
| Module six.moves | urllib_response | Module six.moves.urllib_response |
| Module six.moves | urllib_robotparser | Module six.moves.urllib_robotparser |
| Module six.moves | xmlrpc_client | Module xmlrpclib |
| Module six.moves | xmlrpc_server | Module SimpleXMLRPCServer |
| Module six.moves | xrange | builtin-class xrange |
| Module six.moves | zip | builtin-class itertools.izip |
| Module six.moves | zip_longest | builtin-class itertools.izip_longest |
| Module six.moves.__init__ | BaseHTTPServer | Module BaseHTTPServer |
| Module six.moves.__init__ | CGIHTTPServer | Module CGIHTTPServer |
| Module six.moves.__init__ | PY2 | bool True |
| Module six.moves.__init__ | PY3 | bool False |
| Module six.moves.__init__ | SimpleHTTPServer | Module SimpleHTTPServer |
| Module six.moves.__init__ | StringIO | class StringIO |
| Module six.moves.__init__ | UserDict | class UserDict |
| Module six.moves.__init__ | UserList | class UserList |
| Module six.moves.__init__ | UserString | class UserString |
| Module six.moves.__init__ | __name__ | str b'six.moves' |
| Module six.moves.__init__ | _dummy_thread | Module dummy_thread |
| Module six.moves.__init__ | _thread | Module thread |
| Module six.moves.__init__ | builtins | Module __builtin__ |
| Module six.moves.__init__ | cPickle | Module cPickle |
| Module six.moves.__init__ | cStringIO | Builtin-function StringIO |
| Module six.moves.__init__ | configparser | Module ConfigParser |
| Module six.moves.__init__ | copyreg | Module copy_reg |
| Module six.moves.__init__ | filter | builtin-class itertools.ifilter |
| Module six.moves.__init__ | filterfalse | builtin-class itertools.ifilterfalse |
| Module six.moves.__init__ | html_entities | Module htmlentitydefs |
| Module six.moves.__init__ | html_parser | Module HTMLParser |
| Module six.moves.__init__ | http_client | Module httplib |
| Module six.moves.__init__ | http_cookiejar | Module cookielib |
| Module six.moves.__init__ | http_cookies | Module Cookie |
| Module six.moves.__init__ | input | Builtin-function raw_input |
| Module six.moves.__init__ | intern | Builtin-function intern |
| Module six.moves.__init__ | map | builtin-class itertools.imap |
| Module six.moves.__init__ | queue | Module Queue |
| Module six.moves.__init__ | range | builtin-class xrange |
| Module six.moves.__init__ | reduce | Builtin-function reduce |
| Module six.moves.__init__ | reload_module | Builtin-function reload |
| Module six.moves.__init__ | reprlib | Module repr |
| Module six.moves.__init__ | shlex_quote | Function quote |
| Module six.moves.__init__ | socketserver | Module SocketServer |
| Module six.moves.__init__ | tkinter | Module Tkinter |
| Module six.moves.__init__ | tkinter_colorchooser | Module tkColorChooser |
| Module six.moves.__init__ | tkinter_commondialog | Module tkCommonDialog |
| Module six.moves.__init__ | tkinter_constants | Module Tkconstants |
| Module six.moves.__init__ | tkinter_dialog | Module Dialog |
| Module six.moves.__init__ | tkinter_dnd | Module Tkdnd |
| Module six.moves.__init__ | tkinter_filedialog | Module FileDialog |
| Module six.moves.__init__ | tkinter_font | Module tkFont |
| Module six.moves.__init__ | tkinter_messagebox | Module tkMessageBox |
| Module six.moves.__init__ | tkinter_scrolledtext | Module ScrolledText |
| Module six.moves.__init__ | tkinter_simpledialog | Module SimpleDialog |
| Module six.moves.__init__ | tkinter_tix | Module Tix |
| Module six.moves.__init__ | tkinter_tkfiledialog | Module tkFileDialog |
| Module six.moves.__init__ | tkinter_tksimpledialog | Module tkSimpleDialog |
| Module six.moves.__init__ | tkinter_ttk | Module ttk |
| Module six.moves.__init__ | urllib | Module six.moves.urllib |
| Module six.moves.__init__ | urllib_error | Module six.moves.urllib_error |
| Module six.moves.__init__ | urllib_parse | Module six.moves.urllib_parse |
| Module six.moves.__init__ | urllib_request | Module six.moves.urllib_request |
| Module six.moves.__init__ | urllib_response | Module six.moves.urllib_response |
| Module six.moves.__init__ | urllib_robotparser | Module six.moves.urllib_robotparser |
| Module six.moves.__init__ | xmlrpc_client | Module xmlrpclib |
| Module six.moves.__init__ | xmlrpc_server | Module SimpleXMLRPCServer |
| Module six.moves.__init__ | xrange | builtin-class xrange |
| Module six.moves.__init__ | zip | builtin-class itertools.izip |
| Module six.moves.__init__ | zip_longest | builtin-class itertools.izip_longest |
| Module six.moves.urllib | __name__ | str b'six.moves.urllib' |
| Module six.moves.urllib | error | Module six.moves.urllib_error |
| Module six.moves.urllib | parse | Module six.moves.urllib_parse |
| Module six.moves.urllib | request | Module six.moves.urllib_request |
| Module six.moves.urllib | response | Module six.moves.urllib_response |
| Module six.moves.urllib | robotparser | Module six.moves.urllib_robotparser |
| Module six.moves.urllib.__init__ | __name__ | str b'six.moves.urllib' |
| Module six.moves.urllib.__init__ | error | Module six.moves.urllib_error |
| Module six.moves.urllib.__init__ | parse | Module six.moves.urllib_parse |
| Module six.moves.urllib.__init__ | request | Module six.moves.urllib_request |
| Module six.moves.urllib.__init__ | response | Module six.moves.urllib_response |
| Module six.moves.urllib.__init__ | robotparser | Module six.moves.urllib_robotparser |
| Module six.moves.urllib_error | PY2 | bool True |
| Module six.moves.urllib_error | PY3 | bool False |
| Module six.moves.urllib_error | __name__ | str b'six.moves.urllib_error' |
| Module six.moves.urllib_parse | PY2 | bool True |
| Module six.moves.urllib_parse | PY3 | bool False |
| Module six.moves.urllib_parse | __name__ | str b'six.moves.urllib_parse' |
| Module six.moves.urllib_request | PY2 | bool True |
| Module six.moves.urllib_request | PY3 | bool False |
| Module six.moves.urllib_request | __name__ | str b'six.moves.urllib_request' |
| Module six.moves.urllib_response | PY2 | bool True |
| Module six.moves.urllib_response | PY3 | bool False |
| Module six.moves.urllib_response | __name__ | str b'six.moves.urllib_response' |
| Module six.moves.urllib_robotparser | PY2 | bool True |
| Module six.moves.urllib_robotparser | PY3 | bool False |
| Module six.moves.urllib_robotparser | RobotFileParser | class RobotFileParser |
| Module six.moves.urllib_robotparser | __name__ | str b'six.moves.urllib_robotparser' |

View File

@@ -1,5 +1,9 @@
import six
#Check that some expected attributes are visible
# Check that some expected attributes are visible -- this is the reason we added stubs in
# the first place! If this works, we're happy!
six.moves
six.moves.range
six.moves.zip
six.moves.http_client.HTTPConnection
six.moves.urllib.parse.urlsplit

View File

@@ -1,11 +0,0 @@
import python
predicate six(ModuleObject m) {
m.getName() = "six"
or
six(m.getPackage())
}
from ModuleObject mod, string name, Object obj
where mod.attributeRefersTo(name, obj, _) and six(mod)
select mod.toString(), name, obj.toString()

View File

@@ -1,2 +1,2 @@
semmle-extractor-options: --max-import-depth=3
semmle-extractor-options: --max-import-depth=4
optimize: true

View File

@@ -1,3 +1,9 @@
| six | Module six |
| six.moves | Module six.moves |
| six | Package six |
| six.moves | Package six.moves |
| six.moves.http_client | Module http.client |
| six.moves.http_client.HTTPConnection | class HTTPConnection |
| six.moves.range | builtin-class range |
| six.moves.urllib | Package six.moves.urllib |
| six.moves.urllib.parse | Module six.moves.urllib_parse |
| six.moves.urllib.parse.urlsplit | Function urlsplit |
| six.moves.zip | builtin-class zip |

View File

@@ -1,16 +1,11 @@
import python
string longname(Expr e) {
result = e.(Name).getId()
or
exists(Attribute a |
a = e |
result = longname(a.getObject()) + "." + a.getName()
)
exists(Attribute a | a = e | result = longname(a.getObject()) + "." + a.getName())
}
from Expr e, Object o
where e.refersTo(o) and e.getLocation().getFile().getShortName() = "test.py"
select longname(e), o.toString()
from Expr e, Value v
where e.pointsTo(v) and e.getLocation().getFile().getShortName() = "test.py"
select longname(e), v.toString()

View File

@@ -1,262 +0,0 @@
| Module six | BytesIO | builtin-class _io.BytesIO |
| Module six | Iterator | builtin-class object |
| Module six | MAXSIZE | int 9223372036854775807 |
| Module six | PY2 | bool False |
| Module six | PY3 | bool True |
| Module six | StringIO | builtin-class _io.StringIO |
| Module six | __author__ | str u'Benjamin Peterson <benjamin@python.org>' |
| Module six | __name__ | str u'six' |
| Module six | __version__ | str u'1.5.2' |
| Module six | _add_doc | Function _add_doc |
| Module six | _func_closure | str u'__closure__' |
| Module six | _func_code | str u'__code__' |
| Module six | _func_defaults | str u'__defaults__' |
| Module six | _func_globals | str u'__globals__' |
| Module six | _import_module | Function _import_module |
| Module six | _iteritems | str u'items' |
| Module six | _iterkeys | str u'keys' |
| Module six | _iterlists | str u'lists' |
| Module six | _itervalues | str u'values' |
| Module six | _meth_func | str u'__func__' |
| Module six | _meth_self | str u'__self__' |
| Module six | add_metaclass | Function add_metaclass |
| Module six | add_move | Function add_move |
| Module six | advance_iterator | Builtin-function next |
| Module six | b | Function b |
| Module six | binary_type | builtin-class bytes |
| Module six | byte2int | Function byte2int |
| Module six | callable | Builtin-function callable |
| Module six | callable | Function callable |
| Module six | class_types | Tuple |
| Module six | create_bound_method | builtin-class method |
| Module six | get_function_closure | Attribute() |
| Module six | get_function_code | Attribute() |
| Module six | get_function_defaults | Attribute() |
| Module six | get_function_globals | Attribute() |
| Module six | get_method_function | Attribute() |
| Module six | get_method_self | Attribute() |
| Module six | get_unbound_function | Function get_unbound_function |
| Module six | indexbytes | Builtin-function getitem |
| Module six | int2byte | Function int2byte |
| Module six | integer_types | Tuple |
| Module six | io | Module io |
| Module six | iterbytes | Builtin-function iter |
| Module six | iteritems | Function iteritems |
| Module six | iterkeys | Function iterkeys |
| Module six | iterlists | Function iterlists |
| Module six | itervalues | Function itervalues |
| Module six | moves | Module six.moves |
| Module six | next | Builtin-function next |
| Module six | operator | Module operator |
| Module six | print_ | Function print_ |
| Module six | remove_move | Function remove_move |
| Module six | reraise | Function reraise |
| Module six | string_types | Tuple |
| Module six | sys | Module sys |
| Module six | text_type | builtin-class str |
| Module six | types | Module types |
| Module six | u | Function u |
| Module six | unichr | Builtin-function chr |
| Module six | with_metaclass | Function with_metaclass |
| Module six.__init__ | BytesIO | builtin-class _io.BytesIO |
| Module six.__init__ | Iterator | builtin-class object |
| Module six.__init__ | MAXSIZE | int 9223372036854775807 |
| Module six.__init__ | PY2 | bool False |
| Module six.__init__ | PY3 | bool True |
| Module six.__init__ | StringIO | builtin-class _io.StringIO |
| Module six.__init__ | __author__ | str u'Benjamin Peterson <benjamin@python.org>' |
| Module six.__init__ | __name__ | str u'six' |
| Module six.__init__ | __version__ | str u'1.5.2' |
| Module six.__init__ | _add_doc | Function _add_doc |
| Module six.__init__ | _func_closure | str u'__closure__' |
| Module six.__init__ | _func_code | str u'__code__' |
| Module six.__init__ | _func_defaults | str u'__defaults__' |
| Module six.__init__ | _func_globals | str u'__globals__' |
| Module six.__init__ | _import_module | Function _import_module |
| Module six.__init__ | _iteritems | str u'items' |
| Module six.__init__ | _iterkeys | str u'keys' |
| Module six.__init__ | _iterlists | str u'lists' |
| Module six.__init__ | _itervalues | str u'values' |
| Module six.__init__ | _meth_func | str u'__func__' |
| Module six.__init__ | _meth_self | str u'__self__' |
| Module six.__init__ | add_metaclass | Function add_metaclass |
| Module six.__init__ | add_move | Function add_move |
| Module six.__init__ | advance_iterator | Builtin-function next |
| Module six.__init__ | b | Function b |
| Module six.__init__ | binary_type | builtin-class bytes |
| Module six.__init__ | byte2int | Function byte2int |
| Module six.__init__ | callable | Builtin-function callable |
| Module six.__init__ | callable | Function callable |
| Module six.__init__ | class_types | Tuple |
| Module six.__init__ | create_bound_method | builtin-class method |
| Module six.__init__ | get_function_closure | Attribute() |
| Module six.__init__ | get_function_code | Attribute() |
| Module six.__init__ | get_function_defaults | Attribute() |
| Module six.__init__ | get_function_globals | Attribute() |
| Module six.__init__ | get_method_function | Attribute() |
| Module six.__init__ | get_method_self | Attribute() |
| Module six.__init__ | get_unbound_function | Function get_unbound_function |
| Module six.__init__ | indexbytes | Builtin-function getitem |
| Module six.__init__ | int2byte | Function int2byte |
| Module six.__init__ | integer_types | Tuple |
| Module six.__init__ | io | Module io |
| Module six.__init__ | iterbytes | Builtin-function iter |
| Module six.__init__ | iteritems | Function iteritems |
| Module six.__init__ | iterkeys | Function iterkeys |
| Module six.__init__ | iterlists | Function iterlists |
| Module six.__init__ | itervalues | Function itervalues |
| Module six.__init__ | moves | Module six.moves |
| Module six.__init__ | next | Builtin-function next |
| Module six.__init__ | operator | Module operator |
| Module six.__init__ | print_ | Function print_ |
| Module six.__init__ | remove_move | Function remove_move |
| Module six.__init__ | reraise | Function reraise |
| Module six.__init__ | string_types | Tuple |
| Module six.__init__ | sys | Module sys |
| Module six.__init__ | text_type | builtin-class str |
| Module six.__init__ | types | Module types |
| Module six.__init__ | u | Function u |
| Module six.__init__ | unichr | Builtin-function chr |
| Module six.__init__ | with_metaclass | Function with_metaclass |
| Module six.moves | BaseHTTPServer | Module http.server |
| Module six.moves | CGIHTTPServer | Module http.server |
| Module six.moves | PY2 | bool False |
| Module six.moves | PY3 | bool True |
| Module six.moves | SimpleHTTPServer | Module http.server |
| Module six.moves | StringIO | builtin-class _io.StringIO |
| Module six.moves | UserString | class UserString |
| Module six.moves | __name__ | str u'six.moves' |
| Module six.moves | _thread | Module _thread |
| Module six.moves | builtins | Module builtins |
| Module six.moves | cPickle | Module pickle |
| Module six.moves | cStringIO | builtin-class _io.StringIO |
| Module six.moves | configparser | Module configparser |
| Module six.moves | copyreg | Module copyreg |
| Module six.moves | dbm_gnu | Module dbm.gnu |
| Module six.moves | email_mime_base | Module email.mime.base |
| Module six.moves | email_mime_multipart | Module email.mime.multipart |
| Module six.moves | email_mime_text | Module email.mime.text |
| Module six.moves | filter | builtin-class filter |
| Module six.moves | filterfalse | builtin-class itertools.filterfalse |
| Module six.moves | html_entities | Module html.entities |
| Module six.moves | html_parser | Module html.parser |
| Module six.moves | http_client | Module http.client |
| Module six.moves | http_cookiejar | Module http.cookiejar |
| Module six.moves | http_cookies | Module http.cookies |
| Module six.moves | input | Builtin-function input |
| Module six.moves | map | builtin-class map |
| Module six.moves | queue | Module queue |
| Module six.moves | range | builtin-class range |
| Module six.moves | reload_module | Function reload |
| Module six.moves | reprlib | Module reprlib |
| Module six.moves | socketserver | Module socketserver |
| Module six.moves | tkinter | Module tkinter |
| Module six.moves | tkinter_colorchooser | Module tkinter.colorchooser |
| Module six.moves | tkinter_commondialog | Module tkinter.commondialog |
| Module six.moves | tkinter_constants | Module tkinter.constants |
| Module six.moves | tkinter_dialog | Module tkinter.dialog |
| Module six.moves | tkinter_dnd | Module tkinter.dnd |
| Module six.moves | tkinter_filedialog | Module tkinter.filedialog |
| Module six.moves | tkinter_font | Module tkinter.font |
| Module six.moves | tkinter_messagebox | Module tkinter.messagebox |
| Module six.moves | tkinter_scrolledtext | Module tkinter.scrolledtext |
| Module six.moves | tkinter_simpledialog | Module tkinter.simpledialog |
| Module six.moves | tkinter_tix | Module tkinter.tix |
| Module six.moves | tkinter_tkfiledialog | Module tkinter.filedialog |
| Module six.moves | tkinter_tksimpledialog | Module tkinter.simpledialog |
| Module six.moves | tkinter_ttk | Module tkinter.ttk |
| Module six.moves | urllib | Module six.moves.urllib |
| Module six.moves | urllib_error | Module six.moves.urllib_error |
| Module six.moves | urllib_parse | Module six.moves.urllib_parse |
| Module six.moves | urllib_request | Module six.moves.urllib_request |
| Module six.moves | urllib_response | Module six.moves.urllib_response |
| Module six.moves | urllib_robotparser | Module six.moves.urllib_robotparser |
| Module six.moves | xmlrpc_client | Module xmlrpc.client |
| Module six.moves | xrange | builtin-class range |
| Module six.moves | zip | builtin-class zip |
| Module six.moves | zip_longest | builtin-class itertools.zip_longest |
| Module six.moves.__init__ | BaseHTTPServer | Module http.server |
| Module six.moves.__init__ | CGIHTTPServer | Module http.server |
| Module six.moves.__init__ | PY2 | bool False |
| Module six.moves.__init__ | PY3 | bool True |
| Module six.moves.__init__ | SimpleHTTPServer | Module http.server |
| Module six.moves.__init__ | StringIO | builtin-class _io.StringIO |
| Module six.moves.__init__ | UserString | class UserString |
| Module six.moves.__init__ | __name__ | str u'six.moves' |
| Module six.moves.__init__ | _thread | Module _thread |
| Module six.moves.__init__ | builtins | Module builtins |
| Module six.moves.__init__ | cPickle | Module pickle |
| Module six.moves.__init__ | cStringIO | builtin-class _io.StringIO |
| Module six.moves.__init__ | configparser | Module configparser |
| Module six.moves.__init__ | copyreg | Module copyreg |
| Module six.moves.__init__ | dbm_gnu | Module dbm.gnu |
| Module six.moves.__init__ | email_mime_base | Module email.mime.base |
| Module six.moves.__init__ | email_mime_multipart | Module email.mime.multipart |
| Module six.moves.__init__ | email_mime_text | Module email.mime.text |
| Module six.moves.__init__ | filter | builtin-class filter |
| Module six.moves.__init__ | filterfalse | builtin-class itertools.filterfalse |
| Module six.moves.__init__ | html_entities | Module html.entities |
| Module six.moves.__init__ | html_parser | Module html.parser |
| Module six.moves.__init__ | http_client | Module http.client |
| Module six.moves.__init__ | http_cookiejar | Module http.cookiejar |
| Module six.moves.__init__ | http_cookies | Module http.cookies |
| Module six.moves.__init__ | input | Builtin-function input |
| Module six.moves.__init__ | map | builtin-class map |
| Module six.moves.__init__ | queue | Module queue |
| Module six.moves.__init__ | range | builtin-class range |
| Module six.moves.__init__ | reload_module | Function reload |
| Module six.moves.__init__ | reprlib | Module reprlib |
| Module six.moves.__init__ | socketserver | Module socketserver |
| Module six.moves.__init__ | tkinter | Module tkinter |
| Module six.moves.__init__ | tkinter_colorchooser | Module tkinter.colorchooser |
| Module six.moves.__init__ | tkinter_commondialog | Module tkinter.commondialog |
| Module six.moves.__init__ | tkinter_constants | Module tkinter.constants |
| Module six.moves.__init__ | tkinter_dialog | Module tkinter.dialog |
| Module six.moves.__init__ | tkinter_dnd | Module tkinter.dnd |
| Module six.moves.__init__ | tkinter_filedialog | Module tkinter.filedialog |
| Module six.moves.__init__ | tkinter_font | Module tkinter.font |
| Module six.moves.__init__ | tkinter_messagebox | Module tkinter.messagebox |
| Module six.moves.__init__ | tkinter_scrolledtext | Module tkinter.scrolledtext |
| Module six.moves.__init__ | tkinter_simpledialog | Module tkinter.simpledialog |
| Module six.moves.__init__ | tkinter_tix | Module tkinter.tix |
| Module six.moves.__init__ | tkinter_tkfiledialog | Module tkinter.filedialog |
| Module six.moves.__init__ | tkinter_tksimpledialog | Module tkinter.simpledialog |
| Module six.moves.__init__ | tkinter_ttk | Module tkinter.ttk |
| Module six.moves.__init__ | urllib | Module six.moves.urllib |
| Module six.moves.__init__ | urllib_error | Module six.moves.urllib_error |
| Module six.moves.__init__ | urllib_parse | Module six.moves.urllib_parse |
| Module six.moves.__init__ | urllib_request | Module six.moves.urllib_request |
| Module six.moves.__init__ | urllib_response | Module six.moves.urllib_response |
| Module six.moves.__init__ | urllib_robotparser | Module six.moves.urllib_robotparser |
| Module six.moves.__init__ | xmlrpc_client | Module xmlrpc.client |
| Module six.moves.__init__ | xrange | builtin-class range |
| Module six.moves.__init__ | zip | builtin-class zip |
| Module six.moves.__init__ | zip_longest | builtin-class itertools.zip_longest |
| Module six.moves.urllib | __name__ | str u'six.moves.urllib' |
| Module six.moves.urllib | error | Module six.moves.urllib_error |
| Module six.moves.urllib | parse | Module six.moves.urllib_parse |
| Module six.moves.urllib | request | Module six.moves.urllib_request |
| Module six.moves.urllib | response | Module six.moves.urllib_response |
| Module six.moves.urllib | robotparser | Module six.moves.urllib_robotparser |
| Module six.moves.urllib.__init__ | __name__ | str u'six.moves.urllib' |
| Module six.moves.urllib.__init__ | error | Module six.moves.urllib_error |
| Module six.moves.urllib.__init__ | parse | Module six.moves.urllib_parse |
| Module six.moves.urllib.__init__ | request | Module six.moves.urllib_request |
| Module six.moves.urllib.__init__ | response | Module six.moves.urllib_response |
| Module six.moves.urllib.__init__ | robotparser | Module six.moves.urllib_robotparser |
| Module six.moves.urllib_error | PY2 | bool False |
| Module six.moves.urllib_error | PY3 | bool True |
| Module six.moves.urllib_error | __name__ | str u'six.moves.urllib_error' |
| Module six.moves.urllib_parse | PY2 | bool False |
| Module six.moves.urllib_parse | PY3 | bool True |
| Module six.moves.urllib_parse | __name__ | str u'six.moves.urllib_parse' |
| Module six.moves.urllib_request | PY2 | bool False |
| Module six.moves.urllib_request | PY3 | bool True |
| Module six.moves.urllib_request | __name__ | str u'six.moves.urllib_request' |
| Module six.moves.urllib_response | PY2 | bool False |
| Module six.moves.urllib_response | PY3 | bool True |
| Module six.moves.urllib_response | __name__ | str u'six.moves.urllib_response' |
| Module six.moves.urllib_robotparser | PY2 | bool False |
| Module six.moves.urllib_robotparser | PY3 | bool True |
| Module six.moves.urllib_robotparser | RobotFileParser | class RobotFileParser |
| Module six.moves.urllib_robotparser | __name__ | str u'six.moves.urllib_robotparser' |

View File

@@ -1,5 +1,9 @@
import six
#Check that some expected attributes are visible
# Check that some expected attributes are visible -- this is the reason we added stubs in
# the first place! If this works, we're happy!
six.moves
six.moves.range
six.moves.range
six.moves.zip
six.moves.http_client.HTTPConnection
six.moves.urllib.parse.urlsplit

View File

@@ -1,11 +0,0 @@
import python
predicate six(ModuleObject m) {
m.getName() = "six"
or
six(m.getPackage())
}
from ModuleObject mod, string name, Object obj
where mod.attributeRefersTo(name, obj, _) and six(mod)
select mod.toString(), name, obj.toString()

View File

@@ -0,0 +1,4 @@
| test.py:9:12:9:26 | bottle handler function result | externally controlled string |
| test.py:13:12:13:24 | bottle handler function result | externally controlled string |
| test.py:19:12:19:33 | bottle handler function result | externally controlled string |
| test.py:36:21:36:51 | Taint sink | externally controlled string |

View File

@@ -0,0 +1,7 @@
import python
import semmle.python.web.HttpResponse
import semmle.python.security.strings.Untrusted
from HttpResponseTaintSink sink, TaintKind kind
where sink.sinks(kind)
select sink, kind

View File

@@ -0,0 +1,8 @@
| ../../../query-tests/Security/lib/bottle.py:64:11:64:24 | LocalRequest() | bottle.request |
| test.py:3:35:3:41 | ImportMember | bottle.request |
| test.py:8:11:8:14 | name | externally controlled string |
| test.py:12:9:12:12 | name | externally controlled string |
| test.py:18:12:18:18 | request | bottle.request |
| test.py:27:12:27:16 | where | externally controlled string |
| test.py:32:14:32:20 | request | bottle.request |
| test.py:36:34:36:40 | request | bottle.request |

View File

@@ -0,0 +1,7 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
from HttpRequestTaintSource source, TaintKind kind
where source.isSourceOf(kind)
select source.(ControlFlowNode).getNode(), kind

View File

@@ -1,7 +1,5 @@
import python
import semmle.python.web.bottle.General
from BottleRoute route
select route.getUrl(), route.getFunction()

View File

@@ -1,4 +0,0 @@
| test.py:9 | BinaryExpr | externally controlled string |
| test.py:13 | BinaryExpr | externally controlled string |
| test.py:19 | BinaryExpr | externally controlled string |
| test.py:36 | BinaryExpr | externally controlled string |

View File

@@ -1,10 +0,0 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.web.HttpResponse
import semmle.python.security.strings.Untrusted
from TaintSink sink, TaintKind kind
where sink.sinks(kind)
select sink.getLocation().toString(), sink.(ControlFlowNode).getNode().toString(), kind

View File

@@ -1,8 +0,0 @@
| ../../../query-tests/Security/lib/bottle.py:64 | LocalRequest() | bottle.request |
| test.py:3 | ImportMember | bottle.request |
| test.py:8 | name | externally controlled string |
| test.py:12 | name | externally controlled string |
| test.py:18 | request | bottle.request |
| test.py:27 | where | externally controlled string |
| test.py:32 | request | bottle.request |
| test.py:36 | request | bottle.request |

View File

@@ -1,10 +0,0 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
from TaintSource src, TaintKind kind
where src.isSourceOf(kind) and not kind.matches("tornado%")
select src.getLocation().toString(), src.(ControlFlowNode).getNode().toString(), kind

View File

@@ -1,13 +1,7 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.web.HttpResponse
import semmle.python.security.strings.Untrusted
from TaintedNode node
select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind()

View File

@@ -0,0 +1,3 @@
| red.py:8:16:8:20 | cherrypy handler function result | externally controlled string |
| test.py:11:16:11:29 | cherrypy handler function result | externally controlled string |
| test.py:17:16:17:27 | cherrypy handler function result | externally controlled string |

View File

@@ -0,0 +1,7 @@
import python
import semmle.python.web.HttpResponse
import semmle.python.security.strings.Untrusted
from HttpResponseTaintSink sink, TaintKind kind
where sink.sinks(kind)
select sink, kind

View File

@@ -0,0 +1,3 @@
| ../../../query-tests/Security/lib/cherrypy/__init__.py:10:11:10:38 | _ThreadLocalProxy() | cherrypy.request |
| test.py:10:17:10:19 | arg | externally controlled string |
| test.py:16:17:16:19 | arg | externally controlled string |

View File

@@ -0,0 +1,7 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
from HttpRequestTaintSource source, TaintKind kind
where source.isSourceOf(kind)
select source.(ControlFlowNode).getNode(), kind

View File

@@ -1,3 +0,0 @@
| red.py:8 | Str | externally controlled string |
| test.py:11 | BinaryExpr | externally controlled string |
| test.py:17 | BinaryExpr | externally controlled string |

View File

@@ -1,10 +0,0 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.web.HttpResponse
import semmle.python.security.strings.Untrusted
from TaintSink sink, TaintKind kind
where sink.sinks(kind)
select sink.getLocation().toString(), sink.(ControlFlowNode).getNode().toString(), kind

View File

@@ -1,3 +0,0 @@
| ../../../query-tests/Security/lib/cherrypy/__init__.py:10 | _ThreadLocalProxy() | cherrypy.request |
| test.py:10 | arg | externally controlled string |
| test.py:16 | arg | externally controlled string |

View File

@@ -1,10 +0,0 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
from TaintSource src, TaintKind kind
where src.isSourceOf(kind) and not kind.matches("tornado%")
select src.getLocation().toString(), src.(ControlFlowNode).getNode().toString(), kind

View File

@@ -0,0 +1,7 @@
| views.py:7:25:7:63 | django.Response(...) | externally controlled string |
| views.py:11:25:11:52 | django.Response(...) | externally controlled string |
| views.py:15:25:15:53 | django.Response(...) | externally controlled string |
| views.py:23:29:23:60 | django.Response(...) | externally controlled string |
| views.py:29:29:29:65 | django.Response(...) | externally controlled string |
| views.py:34:25:34:63 | django.Response(...) | externally controlled string |
| views.py:38:25:38:70 | django.Response(...) | externally controlled string |

View File

@@ -0,0 +1,7 @@
import python
import semmle.python.web.HttpResponse
import semmle.python.security.strings.Untrusted
from HttpResponseTaintSink sink, TaintKind kind
where sink.sinks(kind)
select sink, kind

View File

@@ -0,0 +1,19 @@
| test.py:5:19:5:25 | request | django.request.HttpRequest |
| test.py:5:28:5:31 | path | externally controlled string |
| test.py:11:19:11:25 | request | django.request.HttpRequest |
| test.py:11:28:11:31 | path | externally controlled string |
| views.py:6:19:6:25 | request | django.request.HttpRequest |
| views.py:6:28:6:30 | foo | externally controlled string |
| views.py:6:33:6:35 | bar | externally controlled string |
| views.py:10:20:10:26 | request | django.request.HttpRequest |
| views.py:14:21:14:27 | request | django.request.HttpRequest |
| views.py:22:20:22:26 | request | django.request.HttpRequest |
| views.py:28:19:28:25 | request | django.request.HttpRequest |
| views.py:32:19:32:25 | request | django.request.HttpRequest |
| views.py:32:28:32:38 | page_number | externally controlled string |
| views.py:37:24:37:30 | request | django.request.HttpRequest |
| views.py:37:33:37:36 | arg0 | externally controlled string |
| views.py:37:39:37:42 | arg1 | externally controlled string |
| views.py:57:15:57:21 | request | django.request.HttpRequest |
| views.py:57:24:57:31 | username | externally controlled string |
| views.py:66:30:66:36 | request | django.request.HttpRequest |

View File

@@ -0,0 +1,7 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
from HttpRequestTaintSource source, TaintKind kind
where source.isSourceOf(kind)
select source.(ControlFlowNode).getNode(), kind

View File

@@ -1,16 +0,0 @@
| sql.py:13 | Str | externally controlled string |
| sql.py:14 | Str | externally controlled string |
| sql.py:17 | BinaryExpr | externally controlled string |
| sql.py:20 | BinaryExpr | externally controlled string |
| sql.py:21 | BinaryExpr | externally controlled string |
| sql.py:22 | BinaryExpr | externally controlled string |
| sql.py:36 | Str | externally controlled string |
| sql.py:42 | BinaryExpr | externally controlled string |
| sql.py:47 | BinaryExpr | externally controlled string |
| views.py:7 | Attribute() | externally controlled string |
| views.py:11 | Attribute() | externally controlled string |
| views.py:15 | Attribute() | externally controlled string |
| views.py:23 | Attribute() | externally controlled string |
| views.py:29 | Attribute() | externally controlled string |
| views.py:34 | Attribute() | externally controlled string |
| views.py:38 | Attribute() | externally controlled string |

View File

@@ -1,13 +0,0 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.web.HttpResponse
import semmle.python.web.django.Db
import semmle.python.web.django.Model
import semmle.python.security.strings.Untrusted
from TaintSink sink, TaintKind kind
where sink.sinks(kind)
select sink.getLocation().toString(), sink.(ControlFlowNode).getNode().toString(), kind

View File

@@ -1,19 +0,0 @@
| test.py:5 | path | externally controlled string |
| test.py:5 | request | django.request.HttpRequest |
| test.py:11 | path | externally controlled string |
| test.py:11 | request | django.request.HttpRequest |
| views.py:6 | bar | externally controlled string |
| views.py:6 | foo | externally controlled string |
| views.py:6 | request | django.request.HttpRequest |
| views.py:10 | request | django.request.HttpRequest |
| views.py:14 | request | django.request.HttpRequest |
| views.py:22 | request | django.request.HttpRequest |
| views.py:28 | request | django.request.HttpRequest |
| views.py:32 | page_number | externally controlled string |
| views.py:32 | request | django.request.HttpRequest |
| views.py:37 | arg0 | externally controlled string |
| views.py:37 | arg1 | externally controlled string |
| views.py:37 | request | django.request.HttpRequest |
| views.py:57 | request | django.request.HttpRequest |
| views.py:57 | username | externally controlled string |
| views.py:66 | request | django.request.HttpRequest |

View File

@@ -1,10 +0,0 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
from TaintSource src, TaintKind kind
where src.isSourceOf(kind)
select src.getLocation().toString(), src.(ControlFlowNode).getNode().toString(), kind

View File

@@ -0,0 +1,9 @@
| sql.py:13:24:13:64 | db.connection.execute | externally controlled string |
| sql.py:14:26:14:66 | django.models.QuerySet.raw(sink,...) | externally controlled string |
| sql.py:17:24:17:77 | db.connection.execute | externally controlled string |
| sql.py:20:38:20:95 | django.db.models.expressions.RawSQL(sink,...) | externally controlled string |
| sql.py:21:26:21:83 | django.models.QuerySet.raw(sink,...) | externally controlled string |
| sql.py:22:28:22:85 | django.models.QuerySet.extra(sink,...) | externally controlled string |
| sql.py:36:26:36:68 | django.models.QuerySet.raw(sink,...) | externally controlled string |
| sql.py:42:11:42:52 | django.models.QuerySet.raw(sink,...) | externally controlled string |
| sql.py:47:13:47:54 | django.models.QuerySet.extra(sink,...) | externally controlled string |

View File

@@ -0,0 +1,9 @@
import python
import semmle.python.security.injection.Sql
import semmle.python.web.django.Db
import semmle.python.web.django.Model
import semmle.python.security.strings.Untrusted
from SqlInjectionSink sink, TaintKind kind
where sink.sinks(kind)
select sink, kind

View File

@@ -0,0 +1 @@
| FIXME: temporarily disabled since it's not working |

View File

@@ -0,0 +1,8 @@
import python
import semmle.python.web.HttpResponse
import semmle.python.security.strings.Untrusted
// from HttpResponseTaintSink sink, TaintKind kind
// where sink.sinks(kind)
// select sink, kind
select "FIXME: temporarily disabled since it's not working"

View File

@@ -0,0 +1,3 @@
| test.py:9:22:9:24 | req | falcon.request |
| test.py:19:23:19:25 | req | falcon.request |
| test.py:22:25:22:27 | req | falcon.request |

View File

@@ -0,0 +1,7 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
from HttpRequestTaintSource source, TaintKind kind
where source.isSourceOf(kind)
select source.(ControlFlowNode).getNode(), kind

View File

@@ -1,8 +1,5 @@
import python
import semmle.python.web.falcon.General
from FalconRoute route, string method
select route.getUrl(), method, route.getHandlerFunction(method)

View File

@@ -1,6 +1,4 @@
import python
import semmle.python.web.HttpRequest
import semmle.python.web.HttpResponse
import semmle.python.security.strings.Untrusted

View File

@@ -1,3 +0,0 @@
| test.py:9 | req | falcon.request |
| test.py:19 | req | falcon.request |
| test.py:22 | req | falcon.request |

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