Merge branch 'main' into dataflow-improvements

This commit is contained in:
Rasmus Wriedt Larsen
2022-02-21 14:49:40 +01:00
1163 changed files with 242133 additions and 41837 deletions

View File

@@ -0,0 +1,994 @@
/*
* This dbscheme is auto-generated by 'semmle/dbscheme_gen.py'.
* WARNING: Any modifications to this file will be lost.
* Relations can be changed by modifying master.py or
* by adding rules to dbscheme.template
*/
/* This is a dummy line to alter the dbscheme, so we can make a database upgrade
* without actually changing any of the dbscheme predicates. It contains a date
* to allow for such updates in the future as well.
*
* 2020-07-02
*
* DO NOT remove this comment carelessly, since it can revert the dbscheme back to a
* previously seen state (matching a previously seen SHA), which would make the upgrade
* mechanism not work properly.
*/
/*
* External artifacts
*/
externalDefects(
unique int id : @externalDefect,
varchar(900) queryPath : string ref,
int location : @location ref,
varchar(900) message : string ref,
float severity : float ref
);
externalMetrics(
unique int id : @externalMetric,
varchar(900) queryPath : string ref,
int location : @location ref,
float value : float ref
);
externalData(
int id : @externalDataElement,
varchar(900) queryPath : string ref,
int column: int ref,
varchar(900) data : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
/*
* Duplicate code
*/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/*
* Line metrics
*/
py_codelines(int id : @py_scope ref,
int count : int ref);
py_commentlines(int id : @py_scope ref,
int count : int ref);
py_docstringlines(int id : @py_scope ref,
int count : int ref);
py_alllines(int id : @py_scope ref,
int count : int ref);
/*
* Version history
*/
svnentries(
int id : @svnentry,
varchar(500) revision : string ref,
varchar(500) author : string ref,
date revisionDate : date ref,
int changeSize : int ref
)
svnaffectedfiles(
int id : @svnentry ref,
int file : @file ref,
varchar(500) action : string ref
)
svnentrymsg(
int id : @svnentry ref,
varchar(500) message : string ref
)
svnchurn(
int commit : @svnentry ref,
int file : @file ref,
int addedLines : int ref,
int deletedLines : int ref
)
/****************************
Python dbscheme
****************************/
files(unique int id: @file,
varchar(900) name: string ref);
folders(unique int id: @folder,
varchar(900) name: string ref);
@container = @folder | @file;
containerparent(int parent: @container ref,
unique int child: @container ref);
@sourceline = @file | @py_Module | @xmllocatable;
numlines(int element_id: @sourceline ref,
int num_lines: int ref,
int num_code: int ref,
int num_comment: int ref
);
@location = @location_ast | @location_default ;
locations_default(unique int id: @location_default,
int file: @file ref,
int beginLine: int ref,
int beginColumn: int ref,
int endLine: int ref,
int endColumn: int ref);
locations_ast(unique int id: @location_ast,
int module: @py_Module ref,
int beginLine: int ref,
int beginColumn: int ref,
int endLine: int ref,
int endColumn: int ref);
file_contents(unique int file: @file ref, string contents: string ref);
py_module_path(int module: @py_Module ref, int file: @container ref);
variable(unique int id : @py_variable,
int scope : @py_scope ref,
varchar(1) name : string ref);
py_line_lengths(unique int id : @py_line,
int file: @py_Module ref,
int line : int ref,
int length : int ref);
py_extracted_version(int module : @py_Module ref,
varchar(1) version : string ref);
/* AUTO GENERATED PART STARTS HERE */
/* <Field> AnnAssign.location = 0, location */
/* <Field> AnnAssign.value = 1, expr */
/* <Field> AnnAssign.annotation = 2, expr */
/* <Field> AnnAssign.target = 3, expr */
/* <Field> Assert.location = 0, location */
/* <Field> Assert.test = 1, expr */
/* <Field> Assert.msg = 2, expr */
/* <Field> Assign.location = 0, location */
/* <Field> Assign.value = 1, expr */
/* <Field> Assign.targets = 2, expr_list */
/* <Field> AssignExpr.location = 0, location */
/* <Field> AssignExpr.parenthesised = 1, bool */
/* <Field> AssignExpr.value = 2, expr */
/* <Field> AssignExpr.target = 3, expr */
/* <Field> Attribute.location = 0, location */
/* <Field> Attribute.parenthesised = 1, bool */
/* <Field> Attribute.value = 2, expr */
/* <Field> Attribute.attr = 3, str */
/* <Field> Attribute.ctx = 4, expr_context */
/* <Field> AugAssign.location = 0, location */
/* <Field> AugAssign.operation = 1, BinOp */
/* <Field> Await.location = 0, location */
/* <Field> Await.parenthesised = 1, bool */
/* <Field> Await.value = 2, expr */
/* <Field> BinaryExpr.location = 0, location */
/* <Field> BinaryExpr.parenthesised = 1, bool */
/* <Field> BinaryExpr.left = 2, expr */
/* <Field> BinaryExpr.op = 3, operator */
/* <Field> BinaryExpr.right = 4, expr */
/* <Parent> BinaryExpr = AugAssign */
/* <Field> BoolExpr.location = 0, location */
/* <Field> BoolExpr.parenthesised = 1, bool */
/* <Field> BoolExpr.op = 2, boolop */
/* <Field> BoolExpr.values = 3, expr_list */
/* <Field> Break.location = 0, location */
/* <Field> Bytes.location = 0, location */
/* <Field> Bytes.parenthesised = 1, bool */
/* <Field> Bytes.s = 2, bytes */
/* <Field> Bytes.prefix = 3, bytes */
/* <Field> Bytes.implicitly_concatenated_parts = 4, StringPart_list */
/* <Field> Call.location = 0, location */
/* <Field> Call.parenthesised = 1, bool */
/* <Field> Call.func = 2, expr */
/* <Field> Call.positional_args = 3, expr_list */
/* <Field> Call.named_args = 4, dict_item_list */
/* <Field> Class.name = 0, str */
/* <Field> Class.body = 1, stmt_list */
/* <Parent> Class = ClassExpr */
/* <Field> ClassExpr.location = 0, location */
/* <Field> ClassExpr.parenthesised = 1, bool */
/* <Field> ClassExpr.name = 2, str */
/* <Field> ClassExpr.bases = 3, expr_list */
/* <Field> ClassExpr.keywords = 4, dict_item_list */
/* <Field> ClassExpr.inner_scope = 5, Class */
/* <Field> Compare.location = 0, location */
/* <Field> Compare.parenthesised = 1, bool */
/* <Field> Compare.left = 2, expr */
/* <Field> Compare.ops = 3, cmpop_list */
/* <Field> Compare.comparators = 4, expr_list */
/* <Field> Continue.location = 0, location */
/* <Field> Delete.location = 0, location */
/* <Field> Delete.targets = 1, expr_list */
/* <Field> Dict.location = 0, location */
/* <Field> Dict.parenthesised = 1, bool */
/* <Field> Dict.items = 2, dict_item_list */
/* <Field> DictComp.location = 0, location */
/* <Field> DictComp.parenthesised = 1, bool */
/* <Field> DictComp.function = 2, Function */
/* <Field> DictComp.iterable = 3, expr */
/* <Field> DictUnpacking.location = 0, location */
/* <Field> DictUnpacking.value = 1, expr */
/* <Field> Ellipsis.location = 0, location */
/* <Field> Ellipsis.parenthesised = 1, bool */
/* <Field> ExceptStmt.location = 0, location */
/* <Field> ExceptStmt.type = 1, expr */
/* <Field> ExceptStmt.name = 2, expr */
/* <Field> ExceptStmt.body = 3, stmt_list */
/* <Field> Exec.location = 0, location */
/* <Field> Exec.body = 1, expr */
/* <Field> Exec.globals = 2, expr */
/* <Field> Exec.locals = 3, expr */
/* <Field> ExprStmt.location = 0, location */
/* <Field> ExprStmt.value = 1, expr */
/* <Field> Filter.location = 0, location */
/* <Field> Filter.parenthesised = 1, bool */
/* <Field> Filter.value = 2, expr */
/* <Field> Filter.filter = 3, expr */
/* <Field> For.location = 0, location */
/* <Field> For.target = 1, expr */
/* <Field> For.iter = 2, expr */
/* <Field> For.body = 3, stmt_list */
/* <Field> For.orelse = 4, stmt_list */
/* <Field> For.is_async = 5, bool */
/* <Field> FormattedValue.location = 0, location */
/* <Field> FormattedValue.parenthesised = 1, bool */
/* <Field> FormattedValue.value = 2, expr */
/* <Field> FormattedValue.conversion = 3, str */
/* <Field> FormattedValue.format_spec = 4, JoinedStr */
/* <Field> Function.name = 0, str */
/* <Field> Function.args = 1, parameter_list */
/* <Field> Function.vararg = 2, expr */
/* <Field> Function.kwonlyargs = 3, expr_list */
/* <Field> Function.kwarg = 4, expr */
/* <Field> Function.body = 5, stmt_list */
/* <Field> Function.is_async = 6, bool */
/* <Parent> Function = FunctionParent */
/* <Field> FunctionExpr.location = 0, location */
/* <Field> FunctionExpr.parenthesised = 1, bool */
/* <Field> FunctionExpr.name = 2, str */
/* <Field> FunctionExpr.args = 3, arguments */
/* <Field> FunctionExpr.returns = 4, expr */
/* <Field> FunctionExpr.inner_scope = 5, Function */
/* <Field> GeneratorExp.location = 0, location */
/* <Field> GeneratorExp.parenthesised = 1, bool */
/* <Field> GeneratorExp.function = 2, Function */
/* <Field> GeneratorExp.iterable = 3, expr */
/* <Field> Global.location = 0, location */
/* <Field> Global.names = 1, str_list */
/* <Field> If.location = 0, location */
/* <Field> If.test = 1, expr */
/* <Field> If.body = 2, stmt_list */
/* <Field> If.orelse = 3, stmt_list */
/* <Field> IfExp.location = 0, location */
/* <Field> IfExp.parenthesised = 1, bool */
/* <Field> IfExp.test = 2, expr */
/* <Field> IfExp.body = 3, expr */
/* <Field> IfExp.orelse = 4, expr */
/* <Field> Import.location = 0, location */
/* <Field> Import.names = 1, alias_list */
/* <Field> ImportExpr.location = 0, location */
/* <Field> ImportExpr.parenthesised = 1, bool */
/* <Field> ImportExpr.level = 2, int */
/* <Field> ImportExpr.name = 3, str */
/* <Field> ImportExpr.top = 4, bool */
/* <Field> ImportStar.location = 0, location */
/* <Field> ImportStar.module = 1, expr */
/* <Field> ImportMember.location = 0, location */
/* <Field> ImportMember.parenthesised = 1, bool */
/* <Field> ImportMember.module = 2, expr */
/* <Field> ImportMember.name = 3, str */
/* <Field> Fstring.location = 0, location */
/* <Field> Fstring.parenthesised = 1, bool */
/* <Field> Fstring.values = 2, expr_list */
/* <Parent> Fstring = FormattedValue */
/* <Field> KeyValuePair.location = 0, location */
/* <Field> KeyValuePair.value = 1, expr */
/* <Field> KeyValuePair.key = 2, expr */
/* <Field> Lambda.location = 0, location */
/* <Field> Lambda.parenthesised = 1, bool */
/* <Field> Lambda.args = 2, arguments */
/* <Field> Lambda.inner_scope = 3, Function */
/* <Field> List.location = 0, location */
/* <Field> List.parenthesised = 1, bool */
/* <Field> List.elts = 2, expr_list */
/* <Field> List.ctx = 3, expr_context */
/* <Field> ListComp.location = 0, location */
/* <Field> ListComp.parenthesised = 1, bool */
/* <Field> ListComp.function = 2, Function */
/* <Field> ListComp.iterable = 3, expr */
/* <Field> ListComp.generators = 4, comprehension_list */
/* <Field> ListComp.elt = 5, expr */
/* <Field> Module.name = 0, str */
/* <Field> Module.hash = 1, str */
/* <Field> Module.body = 2, stmt_list */
/* <Field> Module.kind = 3, str */
/* <Field> Name.location = 0, location */
/* <Field> Name.parenthesised = 1, bool */
/* <Field> Name.variable = 2, variable */
/* <Field> Name.ctx = 3, expr_context */
/* <Parent> Name = ParameterList */
/* <Field> Nonlocal.location = 0, location */
/* <Field> Nonlocal.names = 1, str_list */
/* <Field> Num.location = 0, location */
/* <Field> Num.parenthesised = 1, bool */
/* <Field> Num.n = 2, number */
/* <Field> Num.text = 3, number */
/* <Field> Pass.location = 0, location */
/* <Field> PlaceHolder.location = 0, location */
/* <Field> PlaceHolder.parenthesised = 1, bool */
/* <Field> PlaceHolder.variable = 2, variable */
/* <Field> PlaceHolder.ctx = 3, expr_context */
/* <Field> Print.location = 0, location */
/* <Field> Print.dest = 1, expr */
/* <Field> Print.values = 2, expr_list */
/* <Field> Print.nl = 3, bool */
/* <Field> Raise.location = 0, location */
/* <Field> Raise.exc = 1, expr */
/* <Field> Raise.cause = 2, expr */
/* <Field> Raise.type = 3, expr */
/* <Field> Raise.inst = 4, expr */
/* <Field> Raise.tback = 5, expr */
/* <Field> Repr.location = 0, location */
/* <Field> Repr.parenthesised = 1, bool */
/* <Field> Repr.value = 2, expr */
/* <Field> Return.location = 0, location */
/* <Field> Return.value = 1, expr */
/* <Field> Set.location = 0, location */
/* <Field> Set.parenthesised = 1, bool */
/* <Field> Set.elts = 2, expr_list */
/* <Field> SetComp.location = 0, location */
/* <Field> SetComp.parenthesised = 1, bool */
/* <Field> SetComp.function = 2, Function */
/* <Field> SetComp.iterable = 3, expr */
/* <Field> Slice.location = 0, location */
/* <Field> Slice.parenthesised = 1, bool */
/* <Field> Slice.start = 2, expr */
/* <Field> Slice.stop = 3, expr */
/* <Field> Slice.step = 4, expr */
/* <Field> SpecialOperation.location = 0, location */
/* <Field> SpecialOperation.parenthesised = 1, bool */
/* <Field> SpecialOperation.name = 2, str */
/* <Field> SpecialOperation.arguments = 3, expr_list */
/* <Field> Starred.location = 0, location */
/* <Field> Starred.parenthesised = 1, bool */
/* <Field> Starred.value = 2, expr */
/* <Field> Starred.ctx = 3, expr_context */
/* <Field> Str.location = 0, location */
/* <Field> Str.parenthesised = 1, bool */
/* <Field> Str.s = 2, str */
/* <Field> Str.prefix = 3, str */
/* <Field> Str.implicitly_concatenated_parts = 4, StringPart_list */
/* <Field> StringPart.text = 0, str */
/* <Field> StringPart.location = 1, location */
/* <Parent> StringPart = StringPartList */
/* <Parent> StringPartList = BytesOrStr */
/* <Field> Subscript.location = 0, location */
/* <Field> Subscript.parenthesised = 1, bool */
/* <Field> Subscript.value = 2, expr */
/* <Field> Subscript.index = 3, expr */
/* <Field> Subscript.ctx = 4, expr_context */
/* <Field> TemplateDottedNotation.location = 0, location */
/* <Field> TemplateDottedNotation.parenthesised = 1, bool */
/* <Field> TemplateDottedNotation.value = 2, expr */
/* <Field> TemplateDottedNotation.attr = 3, str */
/* <Field> TemplateDottedNotation.ctx = 4, expr_context */
/* <Field> TemplateWrite.location = 0, location */
/* <Field> TemplateWrite.value = 1, expr */
/* <Field> Try.location = 0, location */
/* <Field> Try.body = 1, stmt_list */
/* <Field> Try.orelse = 2, stmt_list */
/* <Field> Try.handlers = 3, stmt_list */
/* <Field> Try.finalbody = 4, stmt_list */
/* <Field> Tuple.location = 0, location */
/* <Field> Tuple.parenthesised = 1, bool */
/* <Field> Tuple.elts = 2, expr_list */
/* <Field> Tuple.ctx = 3, expr_context */
/* <Parent> Tuple = ParameterList */
/* <Field> UnaryExpr.location = 0, location */
/* <Field> UnaryExpr.parenthesised = 1, bool */
/* <Field> UnaryExpr.op = 2, unaryop */
/* <Field> UnaryExpr.operand = 3, expr */
/* <Field> While.location = 0, location */
/* <Field> While.test = 1, expr */
/* <Field> While.body = 2, stmt_list */
/* <Field> While.orelse = 3, stmt_list */
/* <Field> With.location = 0, location */
/* <Field> With.context_expr = 1, expr */
/* <Field> With.optional_vars = 2, expr */
/* <Field> With.body = 3, stmt_list */
/* <Field> With.is_async = 4, bool */
/* <Field> Yield.location = 0, location */
/* <Field> Yield.parenthesised = 1, bool */
/* <Field> Yield.value = 2, expr */
/* <Field> YieldFrom.location = 0, location */
/* <Field> YieldFrom.parenthesised = 1, bool */
/* <Field> YieldFrom.value = 2, expr */
/* <Field> Alias.value = 0, expr */
/* <Field> Alias.asname = 1, expr */
/* <Parent> Alias = AliasList */
/* <Parent> AliasList = Import */
/* <Field> Arguments.kw_defaults = 0, expr_list */
/* <Field> Arguments.defaults = 1, expr_list */
/* <Field> Arguments.annotations = 2, expr_list */
/* <Field> Arguments.varargannotation = 3, expr */
/* <Field> Arguments.kwargannotation = 4, expr */
/* <Field> Arguments.kw_annotations = 5, expr_list */
/* <Parent> Arguments = ArgumentsParent */
/* <Parent> boolean = BoolParent */
/* <Parent> Boolop = BoolExpr */
/* <Parent> string = Bytes */
/* <Parent> Cmpop = CmpopList */
/* <Parent> CmpopList = Compare */
/* <Field> Comprehension.location = 0, location */
/* <Field> Comprehension.iter = 1, expr */
/* <Field> Comprehension.target = 2, expr */
/* <Field> Comprehension.ifs = 3, expr_list */
/* <Parent> Comprehension = ComprehensionList */
/* <Parent> ComprehensionList = ListComp */
/* <Parent> DictItem = DictItemList */
/* <Parent> DictItemList = DictItemListParent */
/* <Field> Expr.location = 0, location */
/* <Field> Expr.parenthesised = 1, bool */
/* <Parent> Expr = ExprParent */
/* <Parent> ExprContext = ExprContextParent */
/* <Parent> ExprList = ExprListParent */
/* <Parent> int = ImportExpr */
/* <Field> Keyword.location = 0, location */
/* <Field> Keyword.value = 1, expr */
/* <Field> Keyword.arg = 2, str */
/* <Parent> Location = LocationParent */
/* <Parent> string = Num */
/* <Parent> Operator = BinaryExpr */
/* <Parent> ParameterList = Function */
/* <Field> Stmt.location = 0, location */
/* <Parent> Stmt = StmtList */
/* <Parent> StmtList = StmtListParent */
/* <Parent> string = StrParent */
/* <Parent> StringList = StrListParent */
/* <Parent> Unaryop = UnaryExpr */
/* <Parent> Variable = VariableParent */
py_Classes(unique int id : @py_Class,
unique int parent : @py_ClassExpr ref);
py_Functions(unique int id : @py_Function,
unique int parent : @py_Function_parent ref);
py_Modules(unique int id : @py_Module);
py_StringParts(unique int id : @py_StringPart,
int parent : @py_StringPart_list ref,
int idx : int ref);
py_StringPart_lists(unique int id : @py_StringPart_list,
unique int parent : @py_Bytes_or_Str ref);
py_aliases(unique int id : @py_alias,
int parent : @py_alias_list ref,
int idx : int ref);
py_alias_lists(unique int id : @py_alias_list,
unique int parent : @py_Import ref);
py_arguments(unique int id : @py_arguments,
unique int parent : @py_arguments_parent ref);
py_bools(int parent : @py_bool_parent ref,
int idx : int ref);
py_boolops(unique int id : @py_boolop,
int kind: int ref,
unique int parent : @py_BoolExpr ref);
py_bytes(varchar(1) id : string ref,
int parent : @py_Bytes ref,
int idx : int ref);
py_cmpops(unique int id : @py_cmpop,
int kind: int ref,
int parent : @py_cmpop_list ref,
int idx : int ref);
py_cmpop_lists(unique int id : @py_cmpop_list,
unique int parent : @py_Compare ref);
py_comprehensions(unique int id : @py_comprehension,
int parent : @py_comprehension_list ref,
int idx : int ref);
py_comprehension_lists(unique int id : @py_comprehension_list,
unique int parent : @py_ListComp ref);
py_dict_items(unique int id : @py_dict_item,
int kind: int ref,
int parent : @py_dict_item_list ref,
int idx : int ref);
py_dict_item_lists(unique int id : @py_dict_item_list,
unique int parent : @py_dict_item_list_parent ref);
py_exprs(unique int id : @py_expr,
int kind: int ref,
int parent : @py_expr_parent ref,
int idx : int ref);
py_expr_contexts(unique int id : @py_expr_context,
int kind: int ref,
unique int parent : @py_expr_context_parent ref);
py_expr_lists(unique int id : @py_expr_list,
int parent : @py_expr_list_parent ref,
int idx : int ref);
py_ints(int id : int ref,
unique int parent : @py_ImportExpr ref);
py_locations(unique int id : @location ref,
unique int parent : @py_location_parent ref);
py_numbers(varchar(1) id : string ref,
int parent : @py_Num ref,
int idx : int ref);
py_operators(unique int id : @py_operator,
int kind: int ref,
unique int parent : @py_BinaryExpr ref);
py_parameter_lists(unique int id : @py_parameter_list,
unique int parent : @py_Function ref);
py_stmts(unique int id : @py_stmt,
int kind: int ref,
int parent : @py_stmt_list ref,
int idx : int ref);
py_stmt_lists(unique int id : @py_stmt_list,
int parent : @py_stmt_list_parent ref,
int idx : int ref);
py_strs(varchar(1) id : string ref,
int parent : @py_str_parent ref,
int idx : int ref);
py_str_lists(unique int id : @py_str_list,
unique int parent : @py_str_list_parent ref);
py_unaryops(unique int id : @py_unaryop,
int kind: int ref,
unique int parent : @py_UnaryExpr ref);
py_variables(int id : @py_variable ref,
unique int parent : @py_variable_parent ref);
case @py_boolop.kind of
0 = @py_And
| 1 = @py_Or;
case @py_cmpop.kind of
0 = @py_Eq
| 1 = @py_Gt
| 2 = @py_GtE
| 3 = @py_In
| 4 = @py_Is
| 5 = @py_IsNot
| 6 = @py_Lt
| 7 = @py_LtE
| 8 = @py_NotEq
| 9 = @py_NotIn;
case @py_dict_item.kind of
0 = @py_DictUnpacking
| 1 = @py_KeyValuePair
| 2 = @py_keyword;
case @py_expr.kind of
0 = @py_Attribute
| 1 = @py_BinaryExpr
| 2 = @py_BoolExpr
| 3 = @py_Bytes
| 4 = @py_Call
| 5 = @py_ClassExpr
| 6 = @py_Compare
| 7 = @py_Dict
| 8 = @py_DictComp
| 9 = @py_Ellipsis
| 10 = @py_FunctionExpr
| 11 = @py_GeneratorExp
| 12 = @py_IfExp
| 13 = @py_ImportExpr
| 14 = @py_ImportMember
| 15 = @py_Lambda
| 16 = @py_List
| 17 = @py_ListComp
| 18 = @py_Name
| 19 = @py_Num
| 20 = @py_Repr
| 21 = @py_Set
| 22 = @py_SetComp
| 23 = @py_Slice
| 24 = @py_Starred
| 25 = @py_Str
| 26 = @py_Subscript
| 27 = @py_Tuple
| 28 = @py_UnaryExpr
| 29 = @py_Yield
| 30 = @py_YieldFrom
| 31 = @py_TemplateDottedNotation
| 32 = @py_Filter
| 33 = @py_PlaceHolder
| 34 = @py_Await
| 35 = @py_Fstring
| 36 = @py_FormattedValue
| 37 = @py_AssignExpr
| 38 = @py_SpecialOperation;
case @py_expr_context.kind of
0 = @py_AugLoad
| 1 = @py_AugStore
| 2 = @py_Del
| 3 = @py_Load
| 4 = @py_Param
| 5 = @py_Store;
case @py_operator.kind of
0 = @py_Add
| 1 = @py_BitAnd
| 2 = @py_BitOr
| 3 = @py_BitXor
| 4 = @py_Div
| 5 = @py_FloorDiv
| 6 = @py_LShift
| 7 = @py_Mod
| 8 = @py_Mult
| 9 = @py_Pow
| 10 = @py_RShift
| 11 = @py_Sub
| 12 = @py_MatMult;
case @py_stmt.kind of
0 = @py_Assert
| 1 = @py_Assign
| 2 = @py_AugAssign
| 3 = @py_Break
| 4 = @py_Continue
| 5 = @py_Delete
| 6 = @py_ExceptStmt
| 7 = @py_Exec
| 8 = @py_Expr_stmt
| 9 = @py_For
| 10 = @py_Global
| 11 = @py_If
| 12 = @py_Import
| 13 = @py_ImportStar
| 14 = @py_Nonlocal
| 15 = @py_Pass
| 16 = @py_Print
| 17 = @py_Raise
| 18 = @py_Return
| 19 = @py_Try
| 20 = @py_While
| 21 = @py_With
| 22 = @py_TemplateWrite
| 23 = @py_AnnAssign;
case @py_unaryop.kind of
0 = @py_Invert
| 1 = @py_Not
| 2 = @py_UAdd
| 3 = @py_USub;
@py_Bytes_or_Str = @py_Bytes | @py_Str;
@py_Function_parent = @py_DictComp | @py_FunctionExpr | @py_GeneratorExp | @py_Lambda | @py_ListComp | @py_SetComp;
@py_arguments_parent = @py_FunctionExpr | @py_Lambda;
@py_ast_node = @py_Class | @py_Function | @py_Module | @py_StringPart | @py_comprehension | @py_dict_item | @py_expr | @py_stmt;
@py_bool_parent = @py_For | @py_Function | @py_Print | @py_With | @py_expr;
@py_dict_item_list_parent = @py_Call | @py_ClassExpr | @py_Dict;
@py_expr_context_parent = @py_Attribute | @py_List | @py_Name | @py_PlaceHolder | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_Tuple;
@py_expr_list_parent = @py_Assign | @py_BoolExpr | @py_Call | @py_ClassExpr | @py_Compare | @py_Delete | @py_Fstring | @py_Function | @py_List | @py_Print | @py_Set | @py_SpecialOperation | @py_Tuple | @py_arguments | @py_comprehension;
@py_expr_or_stmt = @py_expr | @py_stmt;
@py_expr_parent = @py_AnnAssign | @py_Assert | @py_Assign | @py_AssignExpr | @py_Attribute | @py_AugAssign | @py_Await | @py_BinaryExpr | @py_Call | @py_Compare | @py_DictComp | @py_DictUnpacking | @py_ExceptStmt | @py_Exec | @py_Expr_stmt | @py_Filter | @py_For | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_GeneratorExp | @py_If | @py_IfExp | @py_ImportMember | @py_ImportStar | @py_KeyValuePair | @py_ListComp | @py_Print | @py_Raise | @py_Repr | @py_Return | @py_SetComp | @py_Slice | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_TemplateWrite | @py_UnaryExpr | @py_While | @py_With | @py_Yield | @py_YieldFrom | @py_alias | @py_arguments | @py_comprehension | @py_expr_list | @py_keyword | @py_parameter_list;
@py_location_parent = @py_DictUnpacking | @py_KeyValuePair | @py_StringPart | @py_comprehension | @py_expr | @py_keyword | @py_stmt;
@py_parameter = @py_Name | @py_Tuple;
@py_scope = @py_Class | @py_Function | @py_Module;
@py_stmt_list_parent = @py_Class | @py_ExceptStmt | @py_For | @py_Function | @py_If | @py_Module | @py_Try | @py_While | @py_With;
@py_str_list_parent = @py_Global | @py_Nonlocal;
@py_str_parent = @py_Attribute | @py_Class | @py_ClassExpr | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_ImportExpr | @py_ImportMember | @py_Module | @py_SpecialOperation | @py_Str | @py_StringPart | @py_TemplateDottedNotation | @py_keyword | @py_str_list;
@py_variable_parent = @py_Name | @py_PlaceHolder;
/*
* End of auto-generated part
*/
/* Map relative names to absolute names for imports */
py_absolute_names(int module : @py_Module ref,
varchar(1) relname : string ref,
varchar(1) absname : string ref);
py_exports(int id : @py_Module ref,
varchar(1) name : string ref);
/* Successor information */
py_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_true_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_exception_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_false_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_flow_bb_node(unique int flownode : @py_flow_node,
int realnode : @py_ast_node ref,
int basicblock : @py_flow_node ref,
int index : int ref);
py_scope_flow(int flow : @py_flow_node ref,
int scope : @py_scope ref,
int kind : int ref);
py_idoms(unique int node : @py_flow_node ref,
int immediate_dominator : @py_flow_node ref);
py_ssa_phi(int phi : @py_ssa_var ref,
int arg: @py_ssa_var ref);
py_ssa_var(unique int id : @py_ssa_var,
int var : @py_variable ref);
py_ssa_use(int node: @py_flow_node ref,
int var : @py_ssa_var ref);
py_ssa_defn(unique int id : @py_ssa_var ref,
int node: @py_flow_node ref);
@py_base_var = @py_variable | @py_ssa_var;
py_scopes(unique int node : @py_expr_or_stmt ref,
int scope : @py_scope ref);
py_scope_location(unique int id : @location ref,
unique int scope : @py_scope ref);
py_flags_versioned(varchar(1) name : string ref,
varchar(1) value : string ref,
varchar(1) version : string ref);
py_syntax_error_versioned(unique int id : @location ref,
varchar(1) message : string ref,
varchar(1) version : string ref);
py_comments(unique int id : @py_comment,
varchar(1) text : string ref,
unique int location : @location ref);
/* Type information support */
py_cobjects(unique int obj : @py_cobject);
py_cobjecttypes(unique int obj : @py_cobject ref,
int typeof : @py_cobject ref);
py_cobjectnames(unique int obj : @py_cobject ref,
varchar(1) name : string ref);
/* Kind should be 0 for introspection, > 0 from source, as follows:
1 from C extension source
*/
py_cobject_sources(int obj : @py_cobject ref,
int kind : int ref);
py_cmembers_versioned(int object : @py_cobject ref,
varchar(1) name : string ref,
int member : @py_cobject ref,
varchar(1) version : string ref);
py_citems(int object : @py_cobject ref,
int index : int ref,
int member : @py_cobject ref);
ext_argtype(int funcid : @py_object ref,
int arg : int ref,
int typeid : @py_object ref);
ext_rettype(int funcid : @py_object ref,
int typeid : @py_object ref);
ext_proptype(int propid : @py_object ref,
int typeid : @py_object ref);
ext_argreturn(int funcid : @py_object ref,
int arg : int ref);
py_special_objects(unique int obj : @py_cobject ref,
unique varchar(1) name : string ref);
py_decorated_object(int object : @py_object ref,
int level: int ref);
@py_object = @py_cobject | @py_flow_node;
@py_source_element = @py_ast_node | @container;
/* XML Files */
xmlEncoding (unique int id: @file ref, varchar(900) encoding: string ref);
xmlDTDs (unique int id: @xmldtd,
varchar(900) root: string ref,
varchar(900) publicId: string ref,
varchar(900) systemId: string ref,
int fileid: @file ref);
xmlElements (unique int id: @xmlelement,
varchar(900) name: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int fileid: @file ref);
xmlAttrs (unique int id: @xmlattribute,
int elementid: @xmlelement ref,
varchar(900) name: string ref,
varchar(3600) value: string ref,
int idx: int ref,
int fileid: @file ref);
xmlNs (int id: @xmlnamespace,
varchar(900) prefixName: string ref,
varchar(900) URI: string ref,
int fileid: @file ref);
xmlHasNs (int elementId: @xmlnamespaceable ref,
int nsId: @xmlnamespace ref,
int fileid: @file ref);
xmlComments (unique int id: @xmlcomment,
varchar(3600) text: string ref,
int parentid: @xmlparent ref,
int fileid: @file ref);
xmlChars (unique int id: @xmlcharacters,
varchar(3600) text: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int isCDATA: int ref,
int fileid: @file ref);
@xmlparent = @file | @xmlelement;
@xmlnamespaceable = @xmlelement | @xmlattribute;
xmllocations(int xmlElement: @xmllocatable ref,
int location: @location_default ref);
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;

View File

@@ -0,0 +1,4 @@
name: codeql/python-downgrades
groups: python
downgrades: .
library: true

View File

@@ -0,0 +1,5 @@
name: codeql/python-consistency-queries
groups: [python, test, consistency-queries]
dependencies:
codeql/python-all: "*"
extractor: python

View File

@@ -1,3 +1,12 @@
## 0.0.9
## 0.0.8
### Deprecated APIs
* Moved the files defining regex injection configuration and customization, instead of `import semmle.python.security.injection.RegexInjection` please use `import semmle.python.security.dataflow.RegexInjection` (the same for `RegexInjectionCustomizations`).
* The `codeql/python-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/python-all` CodeQL pack.
## 0.0.7
## 0.0.6

View File

@@ -1,4 +0,0 @@
---
category: deprecated
---
* The `codeql/python-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/python-all` CodeQL pack.

View File

@@ -0,0 +1,4 @@
---
category: deprecated
---
* The old points-to based modeling has been deprecated. Use the new type-tracking/API-graphs based modeling instead.

View File

@@ -1,4 +1,6 @@
---
category: deprecated
---
## 0.0.8
### Deprecated APIs
* Moved the files defining regex injection configuration and customization, instead of `import semmle.python.security.injection.RegexInjection` please use `import semmle.python.security.dataflow.RegexInjection` (the same for `RegexInjectionCustomizations`).
* The `codeql/python-upgrades` CodeQL pack has been removed. All upgrades scripts have been merged into the `codeql/python-all` CodeQL pack.

View File

@@ -0,0 +1 @@
## 0.0.9

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.0.7
lastReleaseVersion: 0.0.9

View File

@@ -1,5 +1,5 @@
name: codeql/python-all
version: 0.0.8-dev
version: 0.0.10-dev
groups: python
dbscheme: semmlecode.python.dbscheme
extractor: python

View File

@@ -114,13 +114,13 @@ module API {
* Gets a node such that there is an edge in the API graph between this node and the other
* one, and that edge is labeled with `lbl`.
*/
Node getASuccessor(string lbl) { Impl::edge(this, lbl, result) }
Node getASuccessor(Label::ApiLabel lbl) { Impl::edge(this, lbl, result) }
/**
* Gets a node such that there is an edge in the API graph between that other node and
* this one, and that edge is labeled with `lbl`
*/
Node getAPredecessor(string lbl) { this = result.getASuccessor(lbl) }
Node getAPredecessor(Label::ApiLabel lbl) { this = result.getASuccessor(lbl) }
/**
* Gets a node such that there is an edge in the API graph between this node and the other
@@ -174,9 +174,8 @@ module API {
length = 0 and
result = ""
or
exists(Node pred, string lbl, string predpath |
exists(Node pred, Label::ApiLabel lbl, string predpath |
Impl::edge(pred, lbl, this) and
lbl != "" and
predpath = pred.getAPath(length - 1) and
exists(string dot | if length = 1 then dot = "" else dot = "." |
result = predpath + dot + lbl and
@@ -335,7 +334,8 @@ module API {
*
* For instance, `prefix_member("foo.bar", "baz", "foo.bar.baz")` would hold.
*/
private predicate prefix_member(TApiNode base, string member, TApiNode sub) {
cached
predicate prefix_member(TApiNode base, string member, TApiNode sub) {
exists(string sub_str, string regexp |
regexp = "(.+)[.]([^.]+)" and
base = MkModuleImport(sub_str.regexpCapture(regexp, 1)) and
@@ -386,7 +386,7 @@ module API {
* `lbl` in the API graph.
*/
cached
predicate use(TApiNode base, string lbl, DataFlow::Node ref) {
predicate use(TApiNode base, Label::ApiLabel lbl, DataFlow::Node ref) {
exists(DataFlow::LocalSourceNode src, DataFlow::LocalSourceNode pred |
// First, we find a predecessor of the node `ref` that we want to determine. The predecessor
// is any node that is a type-tracked use of a data flow node (`src`), which is itself a
@@ -481,7 +481,7 @@ module API {
* Holds if there is an edge from `pred` to `succ` in the API graph that is labeled with `lbl`.
*/
cached
predicate edge(TApiNode pred, string lbl, TApiNode succ) {
predicate edge(TApiNode pred, Label::ApiLabel lbl, TApiNode succ) {
/* There's an edge from the root node for each imported module. */
exists(string m |
pred = MkRoot() and
@@ -514,36 +514,126 @@ module API {
cached
int distanceFromRoot(TApiNode nd) = shortestDistances(MkRoot/0, edge/2)(_, nd, result)
}
}
private module Label {
/** Gets the edge label for the module `m`. */
bindingset[m]
bindingset[result]
string mod(string m) { result = "moduleImport(\"" + m + "\")" }
/** Provides classes modeling the various edges (labels) in the API graph. */
module Label {
/** A label in the API-graph */
class ApiLabel extends TLabel {
/** Gets a string representation of this label. */
string toString() { result = "???" }
}
/** Gets the `member` edge label for member `m`. */
bindingset[m]
bindingset[result]
string member(string m) { result = "getMember(\"" + m + "\")" }
private import LabelImpl
/** Gets the `member` edge label for the unknown member. */
string unknownMember() { result = "getUnknownMember()" }
private module LabelImpl {
private import semmle.python.dataflow.new.internal.Builtins
private import semmle.python.dataflow.new.internal.ImportStar
/** Gets the `member` edge label for the given attribute reference. */
string memberFromRef(DataFlow::AttrRef pr) {
result = member(pr.getAttributeName())
or
not exists(pr.getAttributeName()) and
result = unknownMember()
newtype TLabel =
MkLabelModule(string mod) { exists(Impl::MkModuleImport(mod)) } or
MkLabelMember(string member) {
member = any(DataFlow::AttrRef pr).getAttributeName() or
exists(Builtins::likelyBuiltin(member)) or
ImportStar::namePossiblyDefinedInImportStar(_, member, _) or
Impl::prefix_member(_, member, _)
} or
MkLabelUnknownMember() or
MkLabelParameter(int i) {
none() // TODO: Fill in when adding def nodes
} or
MkLabelReturn() or
MkLabelSubclass() or
MkLabelAwait()
/** A label for a module. */
class LabelModule extends ApiLabel {
string mod;
LabelModule() { this = MkLabelModule(mod) }
/** Gets the module associated with this label. */
string getMod() { result = mod }
override string toString() { result = "moduleImport(\"" + mod + "\")" }
}
/** A label for the member named `prop`. */
class LabelMember extends ApiLabel {
string member;
LabelMember() { this = MkLabelMember(member) }
/** Gets the property associated with this label. */
string getMember() { result = member }
override string toString() { result = "getMember(\"" + member + "\")" }
}
/** A label for a member with an unknown name. */
class LabelUnknownMember extends ApiLabel {
LabelUnknownMember() { this = MkLabelUnknownMember() }
override string toString() { result = "getUnknownMember()" }
}
/** A label for parameter `i`. */
class LabelParameter extends ApiLabel {
int i;
LabelParameter() { this = MkLabelParameter(i) }
override string toString() { result = "getParameter(" + i + ")" }
/** Gets the index of the parameter for this label. */
int getIndex() { result = i }
}
/** A label that gets the return value of a function. */
class LabelReturn extends ApiLabel {
LabelReturn() { this = MkLabelReturn() }
override string toString() { result = "getReturn()" }
}
/** A label that gets the subclass of a class. */
class LabelSubclass extends ApiLabel {
LabelSubclass() { this = MkLabelSubclass() }
override string toString() { result = "getASubclass()" }
}
/** A label for awaited values. */
class LabelAwait extends ApiLabel {
LabelAwait() { this = MkLabelAwait() }
override string toString() { result = "getAwaited()" }
}
}
/** Gets the edge label for the module `m`. */
LabelModule mod(string m) { result.getMod() = m }
/** Gets the `member` edge label for member `m`. */
LabelMember member(string m) { result.getMember() = m }
/** Gets the `member` edge label for the unknown member. */
LabelUnknownMember unknownMember() { any() }
/** Gets the `member` edge label for the given attribute reference. */
ApiLabel memberFromRef(DataFlow::AttrRef pr) {
result = member(pr.getAttributeName())
or
not exists(pr.getAttributeName()) and
result = unknownMember()
}
/** Gets the `return` edge label. */
LabelReturn return() { any() }
/** Gets the `subclass` edge label. */
LabelSubclass subclass() { any() }
/** Gets the `await` edge label. */
LabelAwait await() { any() }
}
/** Gets the `return` edge label. */
string return() { result = "getReturn()" }
/** Gets the `subclass` edge label. */
string subclass() { result = "getASubclass()" }
/** Gets the `await` edge label. */
string await() { result = "getAwaited()" }
}

View File

@@ -62,33 +62,33 @@ abstract class AstNode extends AstNode_ {
/* Parents */
/** Internal implementation class */
library class FunctionParent extends FunctionParent_ { }
class FunctionParent extends FunctionParent_ { }
/** Internal implementation class */
library class ArgumentsParent extends ArgumentsParent_ { }
class ArgumentsParent extends ArgumentsParent_ { }
/** Internal implementation class */
library class ExprListParent extends ExprListParent_ { }
class ExprListParent extends ExprListParent_ { }
/** Internal implementation class */
library class ExprContextParent extends ExprContextParent_ { }
class ExprContextParent extends ExprContextParent_ { }
/** Internal implementation class */
library class StmtListParent extends StmtListParent_ { }
class StmtListParent extends StmtListParent_ { }
/** Internal implementation class */
library class StrListParent extends StrListParent_ { }
class StrListParent extends StrListParent_ { }
/** Internal implementation class */
library class ExprParent extends ExprParent_ { }
class ExprParent extends ExprParent_ { }
/** Internal implementation class */
class PatternListParent extends PatternListParent_ { }
/** Internal implementation class */
library class PatternParent extends PatternParent_ { }
class PatternParent extends PatternParent_ { }
library class DictItem extends DictItem_, AstNode {
class DictItem extends DictItem_, AstNode {
override string toString() { result = DictItem_.super.toString() }
override AstNode getAChildNode() { none() }
@@ -171,9 +171,9 @@ class ExprList extends ExprList_ {
/** A list of patterns */
class PatternList extends PatternList_ { }
library class DictItemList extends DictItemList_ { }
class DictItemList extends DictItemList_ { }
library class DictItemListParent extends DictItemListParent_ { }
class DictItemListParent extends DictItemListParent_ { }
/** A list of strings (the primitive type string not Bytes or Unicode) */
class StringList extends StringList_ { }

File diff suppressed because it is too large Load Diff

View File

@@ -115,6 +115,9 @@ module Path {
PathNormalization::Range range;
PathNormalization() { this = range }
/** Gets an argument to this path normalization that is interpreted as a path. */
DataFlow::Node getPathArg() { result = range.getPathArg() }
}
/** Provides a class for modeling new path normalization APIs. */
@@ -123,7 +126,10 @@ module Path {
* A data-flow node that performs path normalization. This is often needed in order
* to safely access paths.
*/
abstract class Range extends DataFlow::Node { }
abstract class Range extends DataFlow::Node {
/** Gets an argument to this path normalization that is interpreted as a path. */
abstract DataFlow::Node getPathArg();
}
}
/** A data-flow node that checks that a path is safe to access. */
@@ -443,6 +449,44 @@ module RegexExecution {
}
}
/** Provides classes for modeling LDAP-related APIs. */
module LDAP {
/**
* A data-flow node that executes an LDAP query.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `LDAPQuery::Range` instead.
*/
class LdapExecution extends DataFlow::Node {
LdapExecution::Range range;
LdapExecution() { this = range }
/** Gets the argument containing the filter string. */
DataFlow::Node getFilter() { result = range.getFilter() }
/** Gets the argument containing the base DN. */
DataFlow::Node getBaseDn() { result = range.getBaseDn() }
}
/** Provides classes for modeling new LDAP query execution-related APIs. */
module LdapExecution {
/**
* A data-flow node that executes an LDAP query.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `LDAPQuery` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets the argument containing the filter string. */
abstract DataFlow::Node getFilter();
/** Gets the argument containing the base DN. */
abstract DataFlow::Node getBaseDn();
}
}
}
/**
* A data-flow node that escapes meta-characters, which could be used to prevent
* injection attacks.
@@ -500,8 +544,20 @@ module Escaping {
/** Gets the escape-kind for escaping a string so it can safely be included in HTML. */
string getHtmlKind() { result = "html" }
/** Gets the escape-kind for escaping a string so it can safely be included in HTML. */
/** Gets the escape-kind for escaping a string so it can safely be included in a regular expression. */
string getRegexKind() { result = "regex" }
/**
* Gets the escape-kind for escaping a string so it can safely be used as a
* distinguished name (DN) in an LDAP search.
*/
string getLdapDnKind() { result = "ldap_dn" }
/**
* Gets the escape-kind for escaping a string so it can safely be used as a
* filter in an LDAP search.
*/
string getLdapFilterKind() { result = "ldap_filter" }
// TODO: If adding an XML kind, update the modeling of the `MarkupSafe` PyPI package.
//
// Technically it claims to escape for both HTML and XML, but for now we don't have
@@ -526,9 +582,28 @@ class RegexEscaping extends Escaping {
RegexEscaping() { range.getKind() = Escaping::getRegexKind() }
}
/**
* An escape of a string so it can be safely used as a distinguished name (DN)
* in an LDAP search.
*/
class LdapDnEscaping extends Escaping {
LdapDnEscaping() { range.getKind() = Escaping::getLdapDnKind() }
}
/**
* An escape of a string so it can be safely used as a filter in an LDAP search.
*/
class LdapFilterEscaping extends Escaping {
LdapFilterEscaping() { range.getKind() = Escaping::getLdapFilterKind() }
}
/** Provides classes for modeling HTTP-related APIs. */
module HTTP {
import semmle.python.web.HttpConstants
/** Gets an HTTP verb, in upper case */
string httpVerb() { result in ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"] }
/** Gets an HTTP verb, in lower case */
string httpVerbLower() { result = httpVerb().toLowerCase() }
/** Provides classes for modeling HTTP servers. */
module Server {

View File

@@ -22,6 +22,8 @@ private import semmle.python.frameworks.FlaskSqlAlchemy
private import semmle.python.frameworks.Idna
private import semmle.python.frameworks.Invoke
private import semmle.python.frameworks.Jmespath
private import semmle.python.frameworks.Ldap
private import semmle.python.frameworks.Ldap3
private import semmle.python.frameworks.MarkupSafe
private import semmle.python.frameworks.Multidict
private import semmle.python.frameworks.Mysql

View File

@@ -53,9 +53,6 @@ private newtype TPrintAstNode =
shouldPrint(list.getAnItem(), _) and
not list = any(Module mod).getBody() and
not forall(AstNode child | child = list.getAnItem() | isNotNeeded(child))
} or
TRegExpTermNode(RegExpTerm term) {
exists(StrConst str | term.getRootTerm() = getParsedRegExp(str) and shouldPrint(str, _))
}
/**
@@ -430,32 +427,6 @@ class ParameterNode extends AstElementNode {
*/
class StrConstNode extends AstElementNode {
override StrConst element;
override PrintAstNode getChild(int childIndex) {
childIndex = 0 and result.(RegExpTermNode).getTerm() = getParsedRegExp(element)
}
}
/**
* A print node for a regular expression term.
*/
class RegExpTermNode extends TRegExpTermNode, PrintAstNode {
RegExpTerm term;
RegExpTermNode() { this = TRegExpTermNode(term) }
/** Gets the `RegExpTerm` for this node. */
RegExpTerm getTerm() { result = term }
override PrintAstNode getChild(int childIndex) {
result.(RegExpTermNode).getTerm() = term.getChild(childIndex)
}
override string toString() {
result = "[" + strictconcat(term.getPrimaryQLClass(), " | ") + "] " + term.toString()
}
override Location getLocation() { result = term.getLocation() }
}
/**

View File

@@ -1290,7 +1290,7 @@ class DataFlowCallOption extends TDataFlowCallOption {
}
}
/** Content tagged with the type of a containing object. */
/** A `Content` tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;
private DataFlowType t;

View File

@@ -1007,7 +1007,7 @@ predicate listStoreStep(CfgNode nodeFrom, ListElementContent c, CfgNode nodeTo)
}
/** Data flows from an element of a set to the set. */
predicate setStoreStep(CfgNode nodeFrom, ListElementContent c, CfgNode nodeTo) {
predicate setStoreStep(CfgNode nodeFrom, SetElementContent c, CfgNode nodeTo) {
// Set
// `{..., 42, ...}`
// nodeFrom is `42`, cfg node

View File

@@ -15,6 +15,7 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
* Holds if data flows from `source` to `sink` in zero or more local
* (intra-procedural) steps.
*/
pragma[inline]
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
/**

View File

@@ -14,12 +14,14 @@ private import semmle.python.Frameworks
* Holds if taint propagates from `source` to `sink` in zero or more local
* (intra-procedural) steps.
*/
pragma[inline]
predicate localTaint(DataFlow::Node source, DataFlow::Node sink) { localTaintStep*(source, sink) }
/**
* Holds if taint can flow from `e1` to `e2` in zero or more local (intra-procedural)
* steps.
*/
pragma[inline]
predicate localExprTaint(Expr e1, Expr e2) {
localTaint(DataFlow::exprNode(e1), DataFlow::exprNode(e2))
}

View File

@@ -3,7 +3,7 @@
private import TypeTrackerSpecific
/**
* Any string that may appear as the name of a piece of content. This will usually include things like:
* A string that may appear as the name of a piece of content. This will usually include things like:
* - Attribute names (in Python)
* - Property names (in JavaScript)
*
@@ -18,7 +18,7 @@ class ContentName extends string {
ContentName() { this = getPossibleContentName() }
}
/** Either a content name, or the empty string (representing no content). */
/** A content name, or the empty string (representing no content). */
class OptionalContentName extends string {
OptionalContentName() { this instanceof ContentName or this = "" }
}
@@ -200,7 +200,7 @@ module StepSummary {
private newtype TTypeTracker = MkTypeTracker(Boolean hasCall, OptionalContentName content)
/**
* Summary of the steps needed to track a value to a given dataflow node.
* A summary of the steps needed to track a value to a given dataflow node.
*
* This can be used to track objects that implement a certain API in order to
* recognize calls to that API. Note that type-tracking does not by itself provide a
@@ -347,7 +347,7 @@ module TypeTracker {
private newtype TTypeBackTracker = MkTypeBackTracker(Boolean hasReturn, OptionalContentName content)
/**
* Summary of the steps needed to back-track a use of a value to a given dataflow node.
* A summary of the steps needed to back-track a use of a value to a given dataflow node.
*
* This can for example be used to track callbacks that are passed to a certain API,
* so we can model specific parameters of that callback as having a certain type.

View File

@@ -0,0 +1,75 @@
/**
* Provides classes modeling security-relevant aspects of the `python-ldap` PyPI package (imported as `ldap`).
* See https://www.python-ldap.org/en/python-ldap-3.3.0/index.html
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.Concepts
private import semmle.python.ApiGraphs
/**
* Provides models for the `python-ldap` PyPI package (imported as `ldap`).
*
* See https://www.python-ldap.org/en/python-ldap-3.3.0/index.html
*/
private module Ldap {
/**
* The execution of an `ldap` query.
*
* See https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#functions
*/
private class LdapQueryExecution extends DataFlow::CallCfgNode, LDAP::LdapExecution::Range {
LdapQueryExecution() {
this =
API::moduleImport("ldap")
.getMember("initialize")
.getReturn()
.getMember(["search", "search_s", "search_st", "search_ext", "search_ext_s"])
.getACall()
}
override DataFlow::Node getFilter() {
result in [this.getArg(2), this.getArgByName("filterstr")]
}
override DataFlow::Node getBaseDn() { result in [this.getArg(0), this.getArgByName("base")] }
}
/**
* A call to `ldap.dn.escape_dn_chars`.
*
* See https://github.com/python-ldap/python-ldap/blob/7ce471e238cdd9a4dd8d17baccd1c9e05e6f894a/Lib/ldap/dn.py#L17
*/
private class LdapEscapeDnCall extends DataFlow::CallCfgNode, Escaping::Range {
LdapEscapeDnCall() {
this = API::moduleImport("ldap").getMember("dn").getMember("escape_dn_chars").getACall()
}
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("s")] }
override DataFlow::Node getOutput() { result = this }
override string getKind() { result = Escaping::getLdapDnKind() }
}
/**
* A call to `ldap.filter.escape_filter_chars`.
*
* See https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap-filter.html#ldap.filter.escape_filter_chars
*/
private class LdapEscapeFilterCall extends DataFlow::CallCfgNode, Escaping::Range {
LdapEscapeFilterCall() {
this =
API::moduleImport("ldap").getMember("filter").getMember("escape_filter_chars").getACall()
}
override DataFlow::Node getAnInput() {
result in [this.getArg(0), this.getArgByName("assertion_value")]
}
override DataFlow::Node getOutput() { result = this }
override string getKind() { result = Escaping::getLdapFilterKind() }
}
}

View File

@@ -0,0 +1,80 @@
/**
* Provides classes modeling security-relevant aspects of the `ldap3` PyPI package
* See https://pypi.org/project/ldap3/
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.Concepts
private import semmle.python.ApiGraphs
/**
* Provides models for the `ldap3` PyPI package
*
* See https://pypi.org/project/ldap3/
*/
private module Ldap3 {
/** The execution of an `ldap` query. */
private class LdapQueryExecution extends DataFlow::CallCfgNode, LDAP::LdapExecution::Range {
LdapQueryExecution() {
this =
API::moduleImport("ldap3")
.getMember("Connection")
.getReturn()
.getMember("search")
.getACall()
}
override DataFlow::Node getFilter() {
result in [this.getArg(1), this.getArgByName("search_filter")]
}
override DataFlow::Node getBaseDn() {
result in [this.getArg(0), this.getArgByName("search_base")]
}
}
/**
* A call to `ldap3.utils.dn.escape_rdn`.
*
* See https://github.com/cannatag/ldap3/blob/4d33166f0869b929f59c6e6825a1b9505eb99967/ldap3/utils/dn.py#L390
*/
private class LdapEscapeDnCall extends DataFlow::CallCfgNode, Escaping::Range {
LdapEscapeDnCall() {
this =
API::moduleImport("ldap3")
.getMember("utils")
.getMember("dn")
.getMember("escape_rdn")
.getACall()
}
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("rdn")] }
override DataFlow::Node getOutput() { result = this }
override string getKind() { result = Escaping::getLdapDnKind() }
}
/**
* A call to `ldap3.utils.conv.escape_filter_chars`.
*
* See https://github.com/cannatag/ldap3/blob/4d33166f0869b929f59c6e6825a1b9505eb99967/ldap3/utils/conv.py#L91
*/
private class LdapEscapeFilterCall extends DataFlow::CallCfgNode, Escaping::Range {
LdapEscapeFilterCall() {
this =
API::moduleImport("ldap3")
.getMember("utils")
.getMember("conv")
.getMember("escape_filter_chars")
.getACall()
}
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("text")] }
override DataFlow::Node getOutput() { result = this }
override string getKind() { result = Escaping::getLdapFilterKind() }
}
}

View File

@@ -970,7 +970,7 @@ private module StdlibPrivate {
private class OsPathNormpathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
OsPathNormpathCall() { this = os::path().getMember("normpath").getACall() }
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
override DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
}
/**
@@ -980,7 +980,7 @@ private module StdlibPrivate {
private class OsPathAbspathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
OsPathAbspathCall() { this = os::path().getMember("abspath").getACall() }
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
override DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
}
/**
@@ -990,7 +990,7 @@ private module StdlibPrivate {
private class OsPathRealpathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
OsPathRealpathCall() { this = os::path().getMember("realpath").getACall() }
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
override DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
}
/**

View File

@@ -198,14 +198,11 @@ abstract class RegexString extends Expr {
/** Whether there is a character class, between start (inclusive) and end (exclusive) */
predicate charSet(int start, int end) {
exists(int inner_start, int inner_end |
exists(int inner_start |
this.char_set_start(start, inner_start) and
not this.char_set_start(_, start)
|
end = inner_end + 1 and
inner_end > inner_start and
this.nonEscapedCharAt(inner_end) = "]" and
not exists(int mid | this.nonEscapedCharAt(mid) = "]" | mid > inner_start and mid < inner_end)
end - 1 = min(int i | this.nonEscapedCharAt(i) = "]" and inner_start < i)
)
}
@@ -344,9 +341,7 @@ abstract class RegexString extends Expr {
this.escapingChar(start) and
this.getChar(start + 1) = "N" and
this.getChar(start + 2) = "{" and
this.getChar(end - 1) = "}" and
end > start and
not exists(int i | start + 2 < i and i < end - 1 | this.getChar(i) = "}")
end - 1 = min(int i | start + 2 < i and this.getChar(i) = "}")
}
/**

View File

@@ -4,7 +4,7 @@ import semmle.python.security.SensitiveData
import semmle.python.dataflow.Files
import semmle.python.web.Http
module ClearTextStorage {
deprecated module ClearTextStorage {
abstract class Sink extends TaintSink {
override predicate sinks(TaintKind kind) { kind instanceof SensitiveData }
}
@@ -26,7 +26,7 @@ module ClearTextStorage {
}
}
module ClearTextLogging {
deprecated module ClearTextLogging {
abstract class Sink extends TaintSink {
override predicate sinks(TaintKind kind) { kind instanceof SensitiveData }
}

View File

@@ -3,12 +3,12 @@ import semmle.python.dataflow.TaintTracking
private import semmle.python.security.SensitiveData
private import semmle.crypto.Crypto as CryptoLib
abstract class WeakCryptoSink extends TaintSink {
abstract deprecated class WeakCryptoSink extends TaintSink {
override predicate sinks(TaintKind taint) { taint instanceof SensitiveData }
}
/** Modeling the 'pycrypto' package https://github.com/dlitz/pycrypto (latest release 2013) */
module Pycrypto {
deprecated module Pycrypto {
ModuleValue cipher(string name) { result = Module::named("Crypto.Cipher").attr(name) }
class CipherInstance extends TaintKind {
@@ -58,7 +58,7 @@ module Pycrypto {
}
}
module Cryptography {
deprecated module Cryptography {
ModuleValue ciphers() {
result = Module::named("cryptography.hazmat.primitives.ciphers") and
result.isPackage()
@@ -128,7 +128,7 @@ module Cryptography {
}
}
private class CipherConfig extends TaintTracking::Configuration {
deprecated private class CipherConfig extends TaintTracking::Configuration {
CipherConfig() { this = "Crypto cipher config" }
override predicate isSource(TaintTracking::Source source) {

View File

@@ -7,13 +7,15 @@ import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
private Value traceback_function(string name) { result = Module::named("traceback").attr(name) }
deprecated private Value traceback_function(string name) {
result = Module::named("traceback").attr(name)
}
/**
* This represents information relating to an exception, for instance the
* message, arguments or parts of the exception traceback.
*/
class ExceptionInfo extends StringKind {
deprecated class ExceptionInfo extends StringKind {
ExceptionInfo() { this = "exception.info" }
override string repr() { result = "exception info" }
@@ -23,12 +25,12 @@ class ExceptionInfo extends StringKind {
* A class representing sources of information about
* execution state exposed in tracebacks and the like.
*/
abstract class ErrorInfoSource extends TaintSource { }
abstract deprecated class ErrorInfoSource extends TaintSource { }
/**
* This kind represents exceptions themselves.
*/
class ExceptionKind extends TaintKind {
deprecated class ExceptionKind extends TaintKind {
ExceptionKind() { this = "exception.kind" }
override string repr() { result = "exception" }
@@ -44,7 +46,7 @@ class ExceptionKind extends TaintKind {
* A source of exception objects, either explicitly created, or captured by an
* `except` statement.
*/
class ExceptionSource extends ErrorInfoSource {
deprecated class ExceptionSource extends ErrorInfoSource {
ExceptionSource() {
exists(ClassValue cls |
cls.getASuperType() = ClassValue::baseException() and
@@ -63,7 +65,7 @@ class ExceptionSource extends ErrorInfoSource {
* Represents a sequence of pieces of information relating to an exception,
* for instance the contents of the `args` attribute, or the stack trace.
*/
class ExceptionInfoSequence extends SequenceKind {
deprecated class ExceptionInfoSequence extends SequenceKind {
ExceptionInfoSequence() { this.getItem() instanceof ExceptionInfo }
}
@@ -71,7 +73,7 @@ class ExceptionInfoSequence extends SequenceKind {
* Represents calls to functions in the `traceback` module that return
* sequences of exception information.
*/
class CallToTracebackFunction extends ErrorInfoSource {
deprecated class CallToTracebackFunction extends ErrorInfoSource {
CallToTracebackFunction() {
exists(string name |
name in [
@@ -92,7 +94,7 @@ class CallToTracebackFunction extends ErrorInfoSource {
* Represents calls to functions in the `traceback` module that return a single
* string of information about an exception.
*/
class FormattedTracebackSource extends ErrorInfoSource {
deprecated class FormattedTracebackSource extends ErrorInfoSource {
FormattedTracebackSource() { this = traceback_function("format_exc").getACall() }
override string toString() { result = "exception.info.source" }

View File

@@ -1,6 +1,6 @@
import semmle.python.dataflow.Implementation
module TaintTrackingPaths {
deprecated module TaintTrackingPaths {
predicate edge(TaintTrackingNode src, TaintTrackingNode dest, string label) {
exists(TaintTrackingNode source, TaintTrackingNode sink |
source.getConfiguration().hasFlowPath(source, sink) and
@@ -11,6 +11,6 @@ module TaintTrackingPaths {
}
}
query predicate edges(TaintTrackingNode fromnode, TaintTrackingNode tonode) {
deprecated query predicate edges(TaintTrackingNode fromnode, TaintTrackingNode tonode) {
TaintTrackingPaths::edge(fromnode, tonode, _)
}

View File

@@ -15,7 +15,7 @@ import semmle.python.web.HttpRequest
import semmle.python.security.internal.SensitiveDataHeuristics
private import HeuristicNames
abstract class SensitiveData extends TaintKind {
abstract deprecated class SensitiveData extends TaintKind {
bindingset[this]
SensitiveData() { this = this }
@@ -23,7 +23,7 @@ abstract class SensitiveData extends TaintKind {
abstract SensitiveDataClassification getClassification();
}
module SensitiveData {
deprecated module SensitiveData {
class Secret extends SensitiveData {
Secret() { this = "sensitive.data.secret" }
@@ -115,4 +115,4 @@ module SensitiveData {
}
//Backwards compatibility
class SensitiveDataSource = SensitiveData::Source;
deprecated class SensitiveDataSource = SensitiveData::Source;

View File

@@ -1,4 +1,6 @@
/**
* DEPRECATED -- use flow state instead
*
* This defines a `PathGraph` where sinks from `TaintTracking::Configuration`s are identified with
* sources from `TaintTracking2::Configuration`s if they represent the same `ControlFlowNode`.
*
@@ -28,9 +30,11 @@ private newtype TCustomPathNode =
CrossoverNode(DataFlow::Node node) { crossoverNode(node) }
/**
* DEPRECATED: Use flow state instead
*
* A class representing the set of all the path nodes in either config.
*/
class CustomPathNode extends TCustomPathNode {
deprecated class CustomPathNode extends TCustomPathNode {
/** Gets the PathNode if it is in Config1. */
DataFlow::PathNode asNode1() {
this = Config1Node(result) or this = CrossoverNode(result.getNode())
@@ -64,8 +68,12 @@ class CustomPathNode extends TCustomPathNode {
}
}
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(CustomPathNode a, CustomPathNode b) {
/**
* DEPRECATED: Use flow state instead
*
* Holds if `(a,b)` is an edge in the graph of data flow path explanations.
*/
deprecated query predicate edges(CustomPathNode a, CustomPathNode b) {
// Edge is in Config1 graph
DataFlow::PathGraph::edges(a.asNode1(), b.asNode1())
or
@@ -73,8 +81,12 @@ query predicate edges(CustomPathNode a, CustomPathNode b) {
DataFlow2::PathGraph::edges(a.asNode2(), b.asNode2())
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(CustomPathNode n, string key, string val) {
/**
* DEPRECATED: Use flow state instead
*
* Holds if `n` is a node in the graph of data flow path explanations.
*/
deprecated query predicate nodes(CustomPathNode n, string key, string val) {
// Node is in Config1 graph
DataFlow::PathGraph::nodes(n.asNode1(), key, val)
or

View File

@@ -0,0 +1,60 @@
/**
* Provides taint-tracking configurations for detecting LDAP injection vulnerabilities
*
* Note, for performance reasons: only import this file if
* `LdapInjection::Configuration` is needed, otherwise
* `LdapInjectionCustomizations` should be imported instead.
*/
import python
import semmle.python.Concepts
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.RemoteFlowSources
/**
* Provides aint-tracking configurations for detecting LDAP injection vulnerabilities.class
*
* Two configurations are provided. One is for detecting LDAP injection
* via the distinguished name (DN). The other is for detecting LDAP injection
* via the filter. These require different escapings.
*/
module LdapInjection {
import LdapInjectionCustomizations::LdapInjection
/**
* A taint-tracking configuration for detecting LDAP injection vulnerabilities
* via the distinguished name (DN) parameter of an LDAP search.
*/
class DnConfiguration extends TaintTracking::Configuration {
DnConfiguration() { this = "LdapDnInjection" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof DnSink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof DnSanitizer }
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof DnSanitizerGuard
}
}
/**
* A taint-tracking configuration for detecting LDAP injection vulnerabilities
* via the filter parameter of an LDAP search.
*/
class FilterConfiguration extends TaintTracking::Configuration {
FilterConfiguration() { this = "LdapFilterInjection" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof FilterSink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof FilterSanitizer }
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof FilterSanitizerGuard
}
}
}

View File

@@ -0,0 +1,97 @@
/**
* Provides default sources, sinks and sanitizers for detecting
* "ldap injection"
* vulnerabilities, as well as extension points for adding your own.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.Concepts
private import semmle.python.dataflow.new.RemoteFlowSources
private import semmle.python.dataflow.new.BarrierGuards
/**
* Provides default sources, sinks and sanitizers for detecting
* "ldap injection"
* vulnerabilities, as well as extension points for adding your own.
*/
module LdapInjection {
/**
* A data flow source for "ldap injection" vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for "ldap injection" vulnerabilities.
*/
abstract class DnSink extends DataFlow::Node { }
/**
* A data flow sink for "ldap injection" vulnerabilities.
*/
abstract class FilterSink extends DataFlow::Node { }
/**
* A sanitizer for "ldap injection" vulnerabilities.
*/
abstract class DnSanitizer extends DataFlow::Node { }
/**
* A sanitizer for "ldap injection" vulnerabilities.
*/
abstract class FilterSanitizer extends DataFlow::Node { }
/**
* A sanitizer guard for "ldap injection" vulnerabilities.
*/
abstract class DnSanitizerGuard extends DataFlow::BarrierGuard { }
/**
* A sanitizer guard for "ldap injection" vulnerabilities.
*/
abstract class FilterSanitizerGuard extends DataFlow::BarrierGuard { }
/**
* A source of remote user input, considered as a flow source.
*/
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
/**
* A logging operation, considered as a flow sink.
*/
class LdapExecutionAsDnSink extends DnSink {
LdapExecutionAsDnSink() { this = any(LDAP::LdapExecution ldap).getBaseDn() }
}
/**
* A logging operation, considered as a flow sink.
*/
class LdapExecutionAsFilterSink extends FilterSink {
LdapExecutionAsFilterSink() { this = any(LDAP::LdapExecution ldap).getFilter() }
}
/**
* A comparison with a constant string, considered as a sanitizer-guard.
*/
class StringConstCompareAsDnSanitizerGuard extends DnSanitizerGuard, StringConstCompare { }
/**
* A comparison with a constant string, considered as a sanitizer-guard.
*/
class StringConstCompareAsFilterSanitizerGuard extends FilterSanitizerGuard, StringConstCompare {
}
/**
* A call to replace line breaks functions as a sanitizer.
*/
class LdapDnEscapingSanitizer extends DnSanitizer, DataFlow::CallCfgNode {
LdapDnEscapingSanitizer() { this = any(LdapDnEscaping ldapDnEsc).getOutput() }
}
/**
* A call to replace line breaks functions as a sanitizer.
*/
class LdapFilterEscapingSanitizer extends FilterSanitizer, DataFlow::CallCfgNode {
LdapFilterEscapingSanitizer() { this = any(LdapFilterEscaping ldapDnEsc).getOutput() }
}
}

View File

@@ -2,24 +2,102 @@
* Provides taint-tracking configurations for detecting "path injection" vulnerabilities.
*
* Note, for performance reasons: only import this file if
* the Configurations or the `pathInjection` predicate are needed, otherwise
* `PathInjection::Configuration` is needed, otherwise
* `PathInjectionCustomizations` should be imported instead.
*/
private import python
private import semmle.python.Concepts
private import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
/**
* Provides a taint-tracking configuration for detecting "path injection" vulnerabilities.
*/
module PathInjection {
import PathInjectionCustomizations::PathInjection
/**
* A taint-tracking configuration for detecting "path injection" vulnerabilities.
*
* This configuration uses two flow states, `NotNormalized` and `NormalizedUnchecked`,
* to track the requirement that a file path must be first normalized and then checked
* before it is safe to use.
*
* At sources, paths are assumed not normalized. At normalization points, they change
* state to `NormalizedUnchecked` after which they can be made safe by an appropriate
* check of the prefix.
*
* Such checks are ineffective in the `NotNormalized` state.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "PathInjection" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
source instanceof Source and state instanceof NotNormalized
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
sink instanceof Sink and
(
state instanceof NotNormalized or
state instanceof NormalizedUnchecked
)
}
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) {
// Block `NotNormalized` paths here, since they change state to `NormalizedUnchecked`
node instanceof Path::PathNormalization and
state instanceof NotNormalized
or
node = any(Path::SafeAccessCheck c).getAGuardedNode() and
state instanceof NormalizedUnchecked
}
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof SanitizerGuard
}
override predicate isAdditionalFlowStep(
DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo,
DataFlow::FlowState stateTo
) {
nodeFrom = nodeTo.(Path::PathNormalization).getPathArg() and
stateFrom instanceof NotNormalized and
stateTo instanceof NormalizedUnchecked
}
}
/** A state signifying that the file path has not been normalized. */
class NotNormalized extends DataFlow::FlowState {
NotNormalized() { this = "NotNormalized" }
}
/** A state signifying that the file path has been normalized, but not checked. */
class NormalizedUnchecked extends DataFlow::FlowState {
NormalizedUnchecked() { this = "NormalizedUnchecked" }
}
}
// ---------------------------------------------------------------------------
// Old, deprecated code
// ---------------------------------------------------------------------------
private import semmle.python.dataflow.new.DataFlow2
private import semmle.python.dataflow.new.TaintTracking
private import semmle.python.dataflow.new.TaintTracking2
import ChainedConfigs12
private import ChainedConfigs12
import PathInjectionCustomizations::PathInjection
// ---------------------------------------------------------------------------
// Case 1. The path is never normalized.
// ---------------------------------------------------------------------------
/** Configuration to find paths from sources to sinks that contain no normalization. */
class PathNotNormalizedConfiguration extends TaintTracking::Configuration {
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Configuration to find paths from sources to sinks that contain no normalization.
*/
deprecated class PathNotNormalizedConfiguration extends TaintTracking::Configuration {
PathNotNormalizedConfiguration() { this = "PathNotNormalizedConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -38,18 +116,24 @@ class PathNotNormalizedConfiguration extends TaintTracking::Configuration {
}
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Holds if there is a path injection from source to sink, where the (python) path is
* not normalized.
*/
predicate pathNotNormalized(CustomPathNode source, CustomPathNode sink) {
deprecated predicate pathNotNormalized(CustomPathNode source, CustomPathNode sink) {
any(PathNotNormalizedConfiguration config).hasFlowPath(source.asNode1(), sink.asNode1())
}
// ---------------------------------------------------------------------------
// Case 2. The path is normalized at least once, but never checked afterwards.
// ---------------------------------------------------------------------------
/** Configuration to find paths from sources to normalizations that contain no prior normalizations. */
class FirstNormalizationConfiguration extends TaintTracking::Configuration {
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Configuration to find paths from sources to normalizations that contain no prior normalizations.
*/
deprecated class FirstNormalizationConfiguration extends TaintTracking::Configuration {
FirstNormalizationConfiguration() { this = "FirstNormalizationConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -65,8 +149,12 @@ class FirstNormalizationConfiguration extends TaintTracking::Configuration {
}
}
/** Configuration to find paths from normalizations to sinks that do not go through a check. */
class NormalizedPathNotCheckedConfiguration extends TaintTracking2::Configuration {
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Configuration to find paths from normalizations to sinks that do not go through a check.
*/
deprecated class NormalizedPathNotCheckedConfiguration extends TaintTracking2::Configuration {
NormalizedPathNotCheckedConfiguration() { this = "NormalizedPathNotCheckedConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof Path::PathNormalization }
@@ -83,10 +171,12 @@ class NormalizedPathNotCheckedConfiguration extends TaintTracking2::Configuratio
}
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Holds if there is a path injection from source to sink, where the (python) path is
* normalized at least once, but never checked afterwards.
*/
predicate pathNotCheckedAfterNormalization(CustomPathNode source, CustomPathNode sink) {
deprecated predicate pathNotCheckedAfterNormalization(CustomPathNode source, CustomPathNode sink) {
exists(
FirstNormalizationConfiguration config, DataFlow::PathNode mid1, DataFlow2::PathNode mid2,
NormalizedPathNotCheckedConfiguration config2
@@ -100,8 +190,12 @@ predicate pathNotCheckedAfterNormalization(CustomPathNode source, CustomPathNode
// ---------------------------------------------------------------------------
// Query: Either case 1 or case 2.
// ---------------------------------------------------------------------------
/** Holds if there is a path injection from source to sink */
predicate pathInjection(CustomPathNode source, CustomPathNode sink) {
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Holds if there is a path injection from source to sink
*/
deprecated predicate pathInjection(CustomPathNode source, CustomPathNode sink) {
pathNotNormalized(source, sink)
or
pathNotCheckedAfterNormalization(source, sink)

View File

@@ -2,7 +2,7 @@ import python
import semmle.python.security.strings.Basic
/** Assume that taint flows from argument to result for *any* call */
class AnyCallStringFlow extends DataFlowExtension::DataFlowNode {
deprecated class AnyCallStringFlow extends DataFlowExtension::DataFlowNode {
AnyCallStringFlow() { any(CallNode call).getAnArg() = this }
override ControlFlowNode getASuccessorNode() { result.(CallNode).getAnArg() = this }

View File

@@ -11,18 +11,18 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
/** Abstract taint sink that is potentially vulnerable to malicious shell commands. */
abstract class CommandSink extends TaintSink { }
abstract deprecated class CommandSink extends TaintSink { }
private ModuleObject osOrPopenModule() { result.getName() = ["os", "popen2"] }
deprecated private ModuleObject osOrPopenModule() { result.getName() = ["os", "popen2"] }
private Object makeOsCall() {
deprecated private Object makeOsCall() {
exists(string name | result = ModuleObject::named("subprocess").attr(name) |
name = ["Popen", "call", "check_call", "check_output", "run"]
)
}
/**Special case for first element in sequence. */
class FirstElementKind extends TaintKind {
deprecated class FirstElementKind extends TaintKind {
FirstElementKind() { this = "sequence[" + any(ExternalStringKind key) + "][0]" }
override string repr() { result = "first item in sequence of " + this.getItem().repr() }
@@ -31,7 +31,7 @@ class FirstElementKind extends TaintKind {
ExternalStringKind getItem() { this = "sequence[" + result + "][0]" }
}
class FirstElementFlow extends DataFlowExtension::DataFlowNode {
deprecated class FirstElementFlow extends DataFlowExtension::DataFlowNode {
FirstElementFlow() { this = any(SequenceNode s).getElement(0) }
override ControlFlowNode getASuccessorNode(TaintKind fromkind, TaintKind tokind) {
@@ -43,7 +43,7 @@ class FirstElementFlow extends DataFlowExtension::DataFlowNode {
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `subprocess.call(shell=vuln)` and similar calls.
*/
class ShellCommand extends CommandSink {
deprecated class ShellCommand extends CommandSink {
override string toString() { result = "shell command" }
ShellCommand() {
@@ -81,7 +81,7 @@ class ShellCommand extends CommandSink {
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `subprocess.call(vuln, ...)` and similar calls.
*/
class OsCommandFirstArgument extends CommandSink {
deprecated class OsCommandFirstArgument extends CommandSink {
override string toString() { result = "OS command first argument" }
OsCommandFirstArgument() {
@@ -111,7 +111,7 @@ class OsCommandFirstArgument extends CommandSink {
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `invoke.run(vuln, ...)` and similar calls.
*/
class InvokeRun extends CommandSink {
deprecated class InvokeRun extends CommandSink {
InvokeRun() {
this = Value::named("invoke.run").(FunctionValue).getArgumentForCall(_, 0)
or
@@ -127,12 +127,12 @@ class InvokeRun extends CommandSink {
* Internal TaintKind to track the invoke.Context instance passed to functions
* marked with @invoke.task
*/
private class InvokeContextArg extends TaintKind {
deprecated private class InvokeContextArg extends TaintKind {
InvokeContextArg() { this = "InvokeContextArg" }
}
/** Internal TaintSource to track the context passed to functions marked with @invoke.task */
private class InvokeContextArgSource extends TaintSource {
deprecated private class InvokeContextArgSource extends TaintSource {
InvokeContextArgSource() {
exists(Function f, Expr decorator |
count(f.getADecorator()) = 1 and
@@ -158,7 +158,7 @@ private class InvokeContextArgSource extends TaintSource {
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `invoke.Context().run(vuln, ...)` and similar calls.
*/
class InvokeContextRun extends CommandSink {
deprecated class InvokeContextRun extends CommandSink {
InvokeContextRun() {
exists(CallNode call |
any(InvokeContextArg k).taints(call.getFunction().(AttrNode).getObject("run"))
@@ -187,7 +187,7 @@ class InvokeContextRun extends CommandSink {
* A taint sink that is potentially vulnerable to malicious shell commands.
* The `vuln` in `fabric.Group().run(vuln, ...)` and similar calls.
*/
class FabricGroupRun extends CommandSink {
deprecated class FabricGroupRun extends CommandSink {
FabricGroupRun() {
exists(ClassValue cls |
cls.getASuperType() = Value::named("fabric.Group") and
@@ -203,7 +203,7 @@ class FabricGroupRun extends CommandSink {
// -------------------------------------------------------------------------- //
// Modeling of the 'invoke' package and 'fabric' package (v 1.x)
// -------------------------------------------------------------------------- //
class FabricV1Commands extends CommandSink {
deprecated class FabricV1Commands extends CommandSink {
FabricV1Commands() {
// since `run` and `sudo` are decorated, we can't use FunctionValue's :(
exists(CallNode call |
@@ -228,7 +228,7 @@ class FabricV1Commands extends CommandSink {
* An extension that propagates taint from the arguments of `fabric.api.execute(func, arg0, arg1, ...)`
* to the parameters of `func`, since this will call `func(arg0, arg1, ...)`.
*/
class FabricExecuteExtension extends DataFlowExtension::DataFlowNode {
deprecated class FabricExecuteExtension extends DataFlowExtension::DataFlowNode {
CallNode call;
FabricExecuteExtension() {

View File

@@ -2,7 +2,7 @@ import python
import semmle.python.dataflow.TaintTracking
/** `pickle.loads(untrusted)` vulnerability. */
abstract class DeserializationSink extends TaintSink {
abstract deprecated class DeserializationSink extends TaintSink {
bindingset[this]
DeserializationSink() { this = this }
}

View File

@@ -14,7 +14,7 @@ import semmle.python.security.strings.Untrusted
* A taint sink that represents an argument to exec or eval that is vulnerable to malicious input.
* The `vuln` in `exec(vuln)` or similar.
*/
class StringEvaluationNode extends TaintSink {
deprecated class StringEvaluationNode extends TaintSink {
override string toString() { result = "exec or eval" }
StringEvaluationNode() {

View File

@@ -11,13 +11,15 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.injection.Deserialization
private FunctionObject marshalLoads() { result = ModuleObject::named("marshal").attr("loads") }
deprecated private FunctionObject marshalLoads() {
result = ModuleObject::named("marshal").attr("loads")
}
/**
* A taint sink that is potentially vulnerable to malicious marshaled objects.
* The `vuln` in `marshal.loads(vuln)`.
*/
class UnmarshalingNode extends DeserializationSink {
deprecated class UnmarshalingNode extends DeserializationSink {
override string toString() { result = "unmarshaling vulnerability" }
UnmarshalingNode() {

View File

@@ -6,7 +6,7 @@ import semmle.python.security.strings.Untrusted
* Prevents taint flowing through ntpath.normpath()
* NormalizedPath below handles that case.
*/
class PathSanitizer extends Sanitizer {
deprecated class PathSanitizer extends Sanitizer {
PathSanitizer() { this = "path.sanitizer" }
override predicate sanitizingNode(TaintKind taint, ControlFlowNode node) {
@@ -15,7 +15,7 @@ class PathSanitizer extends Sanitizer {
}
}
private FunctionObject abspath() {
deprecated private FunctionObject abspath() {
exists(ModuleObject os_path | ModuleObject::named("os").attr("path") = os_path |
os_path.attr("abspath") = result
or
@@ -24,18 +24,18 @@ private FunctionObject abspath() {
}
/** A path that has been normalized, but not verified to be safe */
class NormalizedPath extends TaintKind {
deprecated class NormalizedPath extends TaintKind {
NormalizedPath() { this = "normalized.path.injection" }
override string repr() { result = "normalized path" }
}
private predicate abspath_call(CallNode call, ControlFlowNode arg) {
deprecated private predicate abspath_call(CallNode call, ControlFlowNode arg) {
call.getFunction().refersTo(abspath()) and
arg = call.getArg(0)
}
class AbsPath extends DataFlowExtension::DataFlowNode {
deprecated class AbsPath extends DataFlowExtension::DataFlowNode {
AbsPath() { abspath_call(_, this) }
override ControlFlowNode getASuccessorNode(TaintKind fromkind, TaintKind tokind) {
@@ -45,7 +45,7 @@ class AbsPath extends DataFlowExtension::DataFlowNode {
}
}
class NormalizedPathSanitizer extends Sanitizer {
deprecated class NormalizedPathSanitizer extends Sanitizer {
NormalizedPathSanitizer() { this = "normalized.path.sanitizer" }
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
@@ -59,7 +59,7 @@ class NormalizedPathSanitizer extends Sanitizer {
* A taint sink that is vulnerable to malicious paths.
* The `vuln` in `open(vuln)` and similar.
*/
class OpenNode extends TaintSink {
deprecated class OpenNode extends TaintSink {
override string toString() { result = "argument to open()" }
OpenNode() {

View File

@@ -11,7 +11,7 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.injection.Deserialization
private ModuleObject pickleModule() {
deprecated private ModuleObject pickleModule() {
result.getName() = "pickle"
or
result.getName() = "cPickle"
@@ -19,10 +19,10 @@ private ModuleObject pickleModule() {
result.getName() = "dill"
}
private FunctionObject pickleLoads() { result = pickleModule().attr("loads") }
deprecated private FunctionObject pickleLoads() { result = pickleModule().attr("loads") }
/** `pickle.loads(untrusted)` vulnerability. */
class UnpicklingNode extends DeserializationSink {
deprecated class UnpicklingNode extends DeserializationSink {
override string toString() { result = "unpickling untrusted data" }
UnpicklingNode() {

View File

@@ -11,7 +11,7 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.SQL
private StringObject first_part(ControlFlowNode command) {
deprecated private StringObject first_part(ControlFlowNode command) {
command.(BinaryExprNode).getOp() instanceof Add and
command.(BinaryExprNode).getLeft().refersTo(result)
or
@@ -26,7 +26,7 @@ private StringObject first_part(ControlFlowNode command) {
}
/** Holds if `command` appears to be a SQL command string of which `inject` is a part. */
predicate probable_sql_command(ControlFlowNode command, ControlFlowNode inject) {
deprecated predicate probable_sql_command(ControlFlowNode command, ControlFlowNode inject) {
exists(string prefix |
inject = command.getAChild*() and
first_part(command).getText().regexpMatch(" *" + prefix + ".*")
@@ -39,7 +39,7 @@ predicate probable_sql_command(ControlFlowNode command, ControlFlowNode inject)
* A taint kind representing a DB cursor.
* This will be overridden to provide specific kinds of DB cursor.
*/
abstract class DbCursor extends TaintKind {
abstract deprecated class DbCursor extends TaintKind {
bindingset[this]
DbCursor() { any() }
@@ -50,7 +50,7 @@ abstract class DbCursor extends TaintKind {
* A part of a string that appears to be a SQL command and is thus
* vulnerable to malicious input.
*/
class SimpleSqlStringInjection extends SqlInjectionSink {
deprecated class SimpleSqlStringInjection extends SqlInjectionSink {
override string toString() { result = "simple SQL string injection" }
SimpleSqlStringInjection() { probable_sql_command(_, this) }
@@ -62,13 +62,13 @@ class SimpleSqlStringInjection extends SqlInjectionSink {
* A taint source representing sources of DB connections.
* This will be overridden to provide specific kinds of DB connection sources.
*/
abstract class DbConnectionSource extends TaintSource { }
abstract deprecated class DbConnectionSource extends TaintSource { }
/**
* A taint sink that is vulnerable to malicious SQL queries.
* The `vuln` in `db.connection.execute(vuln)` and similar.
*/
class DbConnectionExecuteArgument extends SqlInjectionSink {
deprecated class DbConnectionExecuteArgument extends SqlInjectionSink {
override string toString() { result = "db.connection.execute" }
DbConnectionExecuteArgument() {

View File

@@ -11,23 +11,25 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.injection.Deserialization
private ModuleObject xmlElementTreeModule() { result.getName() = "xml.etree.ElementTree" }
deprecated private ModuleObject xmlElementTreeModule() {
result.getName() = "xml.etree.ElementTree"
}
private ModuleObject xmlMiniDomModule() { result.getName() = "xml.dom.minidom" }
deprecated private ModuleObject xmlMiniDomModule() { result.getName() = "xml.dom.minidom" }
private ModuleObject xmlPullDomModule() { result.getName() = "xml.dom.pulldom" }
deprecated private ModuleObject xmlPullDomModule() { result.getName() = "xml.dom.pulldom" }
private ModuleObject xmlSaxModule() { result.getName() = "xml.sax" }
deprecated private ModuleObject xmlSaxModule() { result.getName() = "xml.sax" }
private class ExpatParser extends TaintKind {
deprecated private class ExpatParser extends TaintKind {
ExpatParser() { this = "expat.parser" }
}
private FunctionObject expatCreateParseFunction() {
deprecated private FunctionObject expatCreateParseFunction() {
result = ModuleObject::named("xml.parsers.expat").attr("ParserCreate")
}
private class ExpatCreateParser extends TaintSource {
deprecated private class ExpatCreateParser extends TaintSource {
ExpatCreateParser() { expatCreateParseFunction().getACall() = this }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExpatParser }
@@ -35,7 +37,7 @@ private class ExpatCreateParser extends TaintSource {
override string toString() { result = "expat.create.parser" }
}
private FunctionObject xmlFromString() {
deprecated private FunctionObject xmlFromString() {
result = xmlElementTreeModule().attr("fromstring")
or
result = xmlMiniDomModule().attr("parseString")
@@ -46,7 +48,7 @@ private FunctionObject xmlFromString() {
}
/** A (potentially) malicious XML string. */
class ExternalXmlString extends ExternalStringKind {
deprecated class ExternalXmlString extends ExternalStringKind {
ExternalXmlString() { this = "external xml encoded object" }
}
@@ -54,7 +56,7 @@ class ExternalXmlString extends ExternalStringKind {
* A call to an XML library function that is potentially vulnerable to a
* specially crafted XML string.
*/
class XmlLoadNode extends DeserializationSink {
deprecated class XmlLoadNode extends DeserializationSink {
override string toString() { result = "xml.load vulnerability" }
XmlLoadNode() {

View File

@@ -11,10 +11,10 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.injection.Deserialization
private FunctionObject yamlLoad() { result = ModuleObject::named("yaml").attr("load") }
deprecated private FunctionObject yamlLoad() { result = ModuleObject::named("yaml").attr("load") }
/** `yaml.load(untrusted)` vulnerability. */
class YamlLoadNode extends DeserializationSink {
deprecated class YamlLoadNode extends DeserializationSink {
override string toString() { result = "yaml.load vulnerability" }
YamlLoadNode() {

View File

@@ -1052,13 +1052,13 @@ private module SuffixConstruction {
*/
pragma[noinline]
private string relevant(RegExpRoot root) {
exists(ascii(result))
exists(ascii(result)) and exists(root)
or
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
or
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
result = ["|", "\n", "Z"]
result = ["|", "\n", "Z"] and exists(root)
}
/**

View File

@@ -3,7 +3,7 @@ private import Common
import semmle.python.dataflow.TaintTracking
/** An extensible kind of taint representing any kind of string. */
abstract class StringKind extends TaintKind {
abstract deprecated class StringKind extends TaintKind {
bindingset[this]
StringKind() { this = this }
@@ -42,7 +42,7 @@ abstract class StringKind extends TaintKind {
}
}
private class StringEqualitySanitizer extends Sanitizer {
deprecated private class StringEqualitySanitizer extends Sanitizer {
StringEqualitySanitizer() { this = "string equality sanitizer" }
/** The test `if untrusted == "KNOWN_VALUE":` sanitizes `untrusted` on its `true` edge. */
@@ -64,13 +64,13 @@ private class StringEqualitySanitizer extends Sanitizer {
}
/** tonode = ....format(fromnode) */
private predicate str_format(ControlFlowNode fromnode, CallNode tonode) {
deprecated private predicate str_format(ControlFlowNode fromnode, CallNode tonode) {
tonode.getFunction().(AttrNode).getName() = "format" and
tonode.getAnArg() = fromnode
}
/** tonode = codec.[en|de]code(fromnode) */
private predicate encode_decode(ControlFlowNode fromnode, CallNode tonode) {
deprecated private predicate encode_decode(ControlFlowNode fromnode, CallNode tonode) {
exists(FunctionObject func, string name |
not func.getFunction().isMethod() and
func.getACall() = tonode and
@@ -84,7 +84,7 @@ private predicate encode_decode(ControlFlowNode fromnode, CallNode tonode) {
}
/** tonode = str(fromnode) */
private predicate to_str(ControlFlowNode fromnode, CallNode tonode) {
deprecated private predicate to_str(ControlFlowNode fromnode, CallNode tonode) {
tonode.getAnArg() = fromnode and
(
tonode = ClassValue::bytes().getACall()
@@ -94,7 +94,7 @@ private predicate to_str(ControlFlowNode fromnode, CallNode tonode) {
}
/** tonode = fromnode[:] */
private predicate slice(ControlFlowNode fromnode, SubscriptNode tonode) {
deprecated private predicate slice(ControlFlowNode fromnode, SubscriptNode tonode) {
exists(Slice all |
all = tonode.getIndex().getNode() and
not exists(all.getStart()) and
@@ -104,13 +104,13 @@ private predicate slice(ControlFlowNode fromnode, SubscriptNode tonode) {
}
/** tonode = os.path.join(..., fromnode, ...) */
private predicate os_path_join(ControlFlowNode fromnode, CallNode tonode) {
deprecated private predicate os_path_join(ControlFlowNode fromnode, CallNode tonode) {
tonode = Value::named("os.path.join").getACall() and
tonode.getAnArg() = fromnode
}
/** tonode = f"... {fromnode} ..." */
private predicate f_string(ControlFlowNode fromnode, ControlFlowNode tonode) {
deprecated private predicate f_string(ControlFlowNode fromnode, ControlFlowNode tonode) {
tonode.getNode().(Fstring).getAValue() = fromnode.getNode()
}

View File

@@ -1,7 +1,7 @@
import python
/* A call that returns a copy (or similar) of the argument */
predicate copy_call(ControlFlowNode fromnode, CallNode tonode) {
deprecated predicate copy_call(ControlFlowNode fromnode, CallNode tonode) {
tonode.getFunction().(AttrNode).getObject("copy") = fromnode
or
exists(ModuleValue copy, string name | name = "copy" or name = "deepcopy" |

View File

@@ -5,7 +5,7 @@ private import Common
/**
* An extensible kind of taint representing an externally controlled string.
*/
abstract class ExternalStringKind extends StringKind {
abstract deprecated class ExternalStringKind extends StringKind {
bindingset[this]
ExternalStringKind() { this = this }
@@ -30,7 +30,7 @@ abstract class ExternalStringKind extends StringKind {
}
/** A kind of "taint", representing a sequence, with a "taint" member */
class ExternalStringSequenceKind extends SequenceKind {
deprecated class ExternalStringSequenceKind extends SequenceKind {
ExternalStringSequenceKind() { this.getItem() instanceof ExternalStringKind }
}
@@ -38,7 +38,7 @@ class ExternalStringSequenceKind extends SequenceKind {
* An hierachical dictionary or list where the entire structure is externally controlled
* This is typically a parsed JSON object.
*/
class ExternalJsonKind extends TaintKind {
deprecated class ExternalJsonKind extends TaintKind {
ExternalJsonKind() { this = "json[" + any(ExternalStringKind key) + "]" }
/** Gets the taint kind for item in this sequence */
@@ -61,7 +61,7 @@ class ExternalJsonKind extends TaintKind {
}
/** A kind of "taint", representing a dictionary mapping keys to tainted strings. */
class ExternalStringDictKind extends DictKind {
deprecated class ExternalStringDictKind extends DictKind {
ExternalStringDictKind() { this.getValue() instanceof ExternalStringKind }
}
@@ -69,12 +69,12 @@ class ExternalStringDictKind extends DictKind {
* A kind of "taint", representing a dictionary mapping keys to sequences of
* tainted strings.
*/
class ExternalStringSequenceDictKind extends DictKind {
deprecated class ExternalStringSequenceDictKind extends DictKind {
ExternalStringSequenceDictKind() { this.getValue() instanceof ExternalStringSequenceKind }
}
/** TaintKind for the result of `urlsplit(tainted_string)` */
class ExternalUrlSplitResult extends ExternalStringSequenceKind {
deprecated class ExternalUrlSplitResult extends ExternalStringSequenceKind {
// https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlsplit
override TaintKind getTaintOfAttribute(string name) {
result = super.getTaintOfAttribute(name)
@@ -103,7 +103,7 @@ class ExternalUrlSplitResult extends ExternalStringSequenceKind {
}
/** TaintKind for the result of `urlparse(tainted_string)` */
class ExternalUrlParseResult extends ExternalStringSequenceKind {
deprecated class ExternalUrlParseResult extends ExternalStringSequenceKind {
// https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlparse
override TaintKind getTaintOfAttribute(string name) {
result = super.getTaintOfAttribute(name)
@@ -134,7 +134,7 @@ class ExternalUrlParseResult extends ExternalStringSequenceKind {
/* Helper for getTaintForStep() */
pragma[noinline]
private predicate json_subscript_taint(
deprecated private predicate json_subscript_taint(
SubscriptNode sub, ControlFlowNode obj, ExternalJsonKind seq, TaintKind key
) {
sub.isLoad() and
@@ -142,12 +142,12 @@ private predicate json_subscript_taint(
key = seq.getValue()
}
private predicate json_load(ControlFlowNode fromnode, CallNode tonode) {
deprecated private predicate json_load(ControlFlowNode fromnode, CallNode tonode) {
tonode = Value::named("json.loads").getACall() and
tonode.getArg(0) = fromnode
}
private predicate urlsplit(ControlFlowNode fromnode, CallNode tonode) {
deprecated private predicate urlsplit(ControlFlowNode fromnode, CallNode tonode) {
// This could be implemented as `exists(FunctionValue` without the explicit six part,
// but then our tests will need to import +100 modules, so for now this slightly
// altered version gets to live on.
@@ -166,7 +166,7 @@ private predicate urlsplit(ControlFlowNode fromnode, CallNode tonode) {
)
}
private predicate urlparse(ControlFlowNode fromnode, CallNode tonode) {
deprecated private predicate urlparse(ControlFlowNode fromnode, CallNode tonode) {
// This could be implemented as `exists(FunctionValue` without the explicit six part,
// but then our tests will need to import +100 modules, so for now this slightly
// altered version gets to live on.
@@ -185,7 +185,7 @@ private predicate urlparse(ControlFlowNode fromnode, CallNode tonode) {
)
}
private predicate parse_qs(ControlFlowNode fromnode, CallNode tonode) {
deprecated private predicate parse_qs(ControlFlowNode fromnode, CallNode tonode) {
// This could be implemented as `exists(FunctionValue` without the explicit six part,
// but then our tests will need to import +100 modules, so for now this slightly
// altered version gets to live on.
@@ -211,7 +211,7 @@ private predicate parse_qs(ControlFlowNode fromnode, CallNode tonode) {
)
}
private predicate parse_qsl(ControlFlowNode fromnode, CallNode tonode) {
deprecated private predicate parse_qsl(ControlFlowNode fromnode, CallNode tonode) {
// This could be implemented as `exists(FunctionValue` without the explicit six part,
// but then our tests will need to import +100 modules, so for now this slightly
// altered version gets to live on.
@@ -238,7 +238,7 @@ private predicate parse_qsl(ControlFlowNode fromnode, CallNode tonode) {
}
/** A kind of "taint", representing an open file-like object from an external source. */
class ExternalFileObject extends TaintKind {
deprecated class ExternalFileObject extends TaintKind {
ExternalStringKind valueKind;
ExternalFileObject() { this = "file[" + valueKind + "]" }
@@ -266,7 +266,7 @@ class ExternalFileObject extends TaintKind {
* - `if splitres.netloc == "KNOWN_VALUE"`
* - `if splitres[0] == "KNOWN_VALUE"`
*/
class UrlsplitUrlparseTempSanitizer extends Sanitizer {
deprecated class UrlsplitUrlparseTempSanitizer extends Sanitizer {
// TODO: remove this once we have better support for named tuples
UrlsplitUrlparseTempSanitizer() { this = "UrlsplitUrlparseTempSanitizer" }

View File

@@ -5,6 +5,6 @@ import External
* A kind of taint representing an externally controlled string.
* This class is a simple sub-class of `ExternalStringKind`.
*/
class UntrustedStringKind extends ExternalStringKind {
deprecated class UntrustedStringKind extends ExternalStringKind {
UntrustedStringKind() { this = "externally controlled string" }
}

View File

@@ -87,7 +87,7 @@ class RangeIterationVariableFact extends PointsToExtension {
}
/* bottle module route constants */
class BottleRoutePointToExtension extends PointsToExtension {
deprecated class BottleRoutePointToExtension extends PointsToExtension {
string name;
BottleRoutePointToExtension() {

View File

@@ -4,13 +4,13 @@ import semmle.python.security.strings.External
import HttpConstants
/** Generic taint source from a http request */
abstract class HttpRequestTaintSource extends TaintSource { }
abstract deprecated class HttpRequestTaintSource extends TaintSource { }
/**
* Taint kind representing the WSGI environment.
* As specified in PEP 3333. https://www.python.org/dev/peps/pep-3333/#environ-variables
*/
class WsgiEnvironment extends TaintKind {
deprecated class WsgiEnvironment extends TaintKind {
WsgiEnvironment() { this = "wsgi.environment" }
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
@@ -43,7 +43,7 @@ class WsgiEnvironment extends TaintKind {
* A standard morsel object from a HTTP request, a value in a cookie,
* typically an instance of `http.cookies.Morsel`
*/
class UntrustedMorsel extends TaintKind {
deprecated class UntrustedMorsel extends TaintKind {
UntrustedMorsel() { this = "http.Morsel" }
override TaintKind getTaintOfAttribute(string name) {
@@ -53,7 +53,7 @@ class UntrustedMorsel extends TaintKind {
}
/** A standard cookie object from a HTTP request, typically an instance of `http.cookies.SimpleCookie` */
class UntrustedCookie extends TaintKind {
deprecated class UntrustedCookie extends TaintKind {
UntrustedCookie() { this = "http.Cookie" }
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
@@ -62,7 +62,7 @@ class UntrustedCookie extends TaintKind {
}
}
abstract class CookieOperation extends @py_flow_node {
abstract deprecated class CookieOperation extends @py_flow_node {
/** Gets a textual representation of this element. */
abstract string toString();
@@ -71,20 +71,20 @@ abstract class CookieOperation extends @py_flow_node {
abstract ControlFlowNode getValue();
}
abstract class CookieGet extends CookieOperation { }
abstract deprecated class CookieGet extends CookieOperation { }
abstract class CookieSet extends CookieOperation { }
abstract deprecated class CookieSet extends CookieOperation { }
/** Generic taint sink in a http response */
abstract class HttpResponseTaintSink extends TaintSink {
abstract deprecated class HttpResponseTaintSink extends TaintSink {
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
abstract class HttpRedirectTaintSink extends TaintSink {
abstract deprecated class HttpRedirectTaintSink extends TaintSink {
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
}
module Client {
deprecated module Client {
// TODO: user-input in other than URL:
// - `data`, `json` for `requests.post`
// - `body` for `HTTPConnection.request`

View File

@@ -1,5 +1,7 @@
/** Gets an HTTP verb, in upper case */
string httpVerb() { result in ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"] }
deprecated string httpVerb() {
result in ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]
}
/** Gets an HTTP verb, in lower case */
string httpVerbLower() { result = httpVerb().toLowerCase() }
deprecated string httpVerbLower() { result = httpVerb().toLowerCase() }

View File

@@ -3,16 +3,16 @@ import semmle.python.web.Http
import semmle.python.types.Extensions
/** The bottle module */
ModuleValue theBottleModule() { result = Module::named("bottle") }
deprecated ModuleValue theBottleModule() { result = Module::named("bottle") }
/** The bottle.Bottle class */
ClassValue theBottleClass() { result = theBottleModule().attr("Bottle") }
deprecated ClassValue theBottleClass() { result = theBottleModule().attr("Bottle") }
/**
* Holds if `route` is routed to `func`
* by decorating `func` with `app.route(route)` or `route(route)`
*/
predicate bottle_route(CallNode route_call, ControlFlowNode route, Function func) {
deprecated predicate bottle_route(CallNode route_call, ControlFlowNode route, Function func) {
exists(CallNode decorator_call, string name |
route_call.getFunction().(AttrNode).getObject(name).pointsTo().getClass() = theBottleClass() or
route_call.getFunction().pointsTo(theBottleModule().attr(name))
@@ -24,7 +24,7 @@ predicate bottle_route(CallNode route_call, ControlFlowNode route, Function func
)
}
class BottleRoute extends ControlFlowNode {
deprecated class BottleRoute extends ControlFlowNode {
BottleRoute() { bottle_route(this, _, _) }
string getUrl() {

View File

@@ -9,12 +9,12 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.bottle.General
FunctionValue bottle_redirect() { result = theBottleModule().attr("redirect") }
deprecated FunctionValue bottle_redirect() { result = theBottleModule().attr("redirect") }
/**
* Represents an argument to the `bottle.redirect` function.
*/
class BottleRedirect extends TaintSink {
deprecated class BottleRedirect extends TaintSink {
override string toString() { result = "bottle.redirect" }
BottleRedirect() {

View File

@@ -4,9 +4,9 @@ import semmle.python.security.strings.External
import semmle.python.web.Http
import semmle.python.web.bottle.General
private Value theBottleRequestObject() { result = theBottleModule().attr("request") }
deprecated private Value theBottleRequestObject() { result = theBottleModule().attr("request") }
class BottleRequestKind extends TaintKind {
deprecated class BottleRequestKind extends TaintKind {
BottleRequestKind() { this = "bottle.request" }
override TaintKind getTaintOfAttribute(string name) {
@@ -21,13 +21,13 @@ class BottleRequestKind extends TaintKind {
}
}
private class RequestSource extends HttpRequestTaintSource {
deprecated private class RequestSource extends HttpRequestTaintSource {
RequestSource() { this.(ControlFlowNode).pointsTo(theBottleRequestObject()) }
override predicate isSourceOf(TaintKind kind) { kind instanceof BottleRequestKind }
}
class BottleFormsDict extends TaintKind {
deprecated class BottleFormsDict extends TaintKind {
BottleFormsDict() { this = "bottle.FormsDict" }
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
@@ -48,7 +48,7 @@ class BottleFormsDict extends TaintKind {
}
}
class FileUpload extends TaintKind {
deprecated class FileUpload extends TaintKind {
FileUpload() { this = "bottle.FileUpload" }
override TaintKind getTaintOfAttribute(string name) {
@@ -60,7 +60,7 @@ class FileUpload extends TaintKind {
}
}
class UntrustedFile extends TaintKind {
deprecated class UntrustedFile extends TaintKind {
UntrustedFile() { this = "Untrusted file" }
}
@@ -69,7 +69,7 @@ class UntrustedFile extends TaintKind {
// Move UntrustedFile to shared location
//
/** Parameter to a bottle request handler function */
class BottleRequestParameter extends HttpRequestTaintSource {
deprecated class BottleRequestParameter extends HttpRequestTaintSource {
BottleRequestParameter() {
exists(BottleRoute route | route.getANamedArgument() = this.(ControlFlowNode).getNode())
}

View File

@@ -9,13 +9,13 @@ import semmle.python.web.bottle.General
* This isn't really a "taint", but we use the value tracking machinery to
* track the flow of response objects.
*/
class BottleResponse extends TaintKind {
deprecated class BottleResponse extends TaintKind {
BottleResponse() { this = "bottle.response" }
}
private Value theBottleResponseObject() { result = theBottleModule().attr("response") }
deprecated private Value theBottleResponseObject() { result = theBottleModule().attr("response") }
class BottleResponseBodyAssignment extends HttpResponseTaintSink {
deprecated class BottleResponseBodyAssignment extends HttpResponseTaintSink {
BottleResponseBodyAssignment() {
exists(DefinitionNode lhs |
lhs.getValue() = this and
@@ -26,7 +26,7 @@ class BottleResponseBodyAssignment extends HttpResponseTaintSink {
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}
class BottleHandlerFunctionResult extends HttpResponseTaintSink {
deprecated class BottleHandlerFunctionResult extends HttpResponseTaintSink {
BottleHandlerFunctionResult() {
exists(BottleRoute route, Return ret |
ret.getScope() = route.getFunction() and
@@ -39,7 +39,7 @@ class BottleHandlerFunctionResult extends HttpResponseTaintSink {
override string toString() { result = "bottle handler function result" }
}
class BottleCookieSet extends CookieSet, CallNode {
deprecated class BottleCookieSet extends CookieSet, CallNode {
BottleCookieSet() {
any(BottleResponse r).taints(this.getFunction().(AttrNode).getObject("set_cookie"))
}

View File

@@ -1,11 +1,11 @@
import python
import semmle.python.web.Http
module CherryPy {
deprecated module CherryPy {
FunctionValue expose() { result = Value::named("cherrypy.expose") }
}
class CherryPyExposedFunction extends Function {
deprecated class CherryPyExposedFunction extends Function {
CherryPyExposedFunction() {
this.getADecorator().pointsTo(CherryPy::expose())
or
@@ -13,7 +13,7 @@ class CherryPyExposedFunction extends Function {
}
}
class CherryPyRoute extends CallNode {
deprecated class CherryPyRoute extends CallNode {
CherryPyRoute() {
/* cherrypy.quickstart(root, script_name, config) */
Value::named("cherrypy.quickstart").(FunctionValue).getACall() = this

View File

@@ -5,7 +5,7 @@ import semmle.python.web.Http
import semmle.python.web.cherrypy.General
/** The cherrypy.request local-proxy object */
class CherryPyRequest extends TaintKind {
deprecated class CherryPyRequest extends TaintKind {
CherryPyRequest() { this = "cherrypy.request" }
override TaintKind getTaintOfAttribute(string name) {
@@ -20,7 +20,7 @@ class CherryPyRequest extends TaintKind {
}
}
class CherryPyExposedFunctionParameter extends HttpRequestTaintSource {
deprecated class CherryPyExposedFunctionParameter extends HttpRequestTaintSource {
CherryPyExposedFunctionParameter() {
exists(Parameter p |
p = any(CherryPyExposedFunction f).getAnArg() and
@@ -34,7 +34,7 @@ class CherryPyExposedFunctionParameter extends HttpRequestTaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
}
class CherryPyRequestSource extends HttpRequestTaintSource {
deprecated class CherryPyRequestSource extends HttpRequestTaintSource {
CherryPyRequestSource() { this.(ControlFlowNode).pointsTo(Value::named("cherrypy.request")) }
override predicate isSourceOf(TaintKind kind) { kind instanceof CherryPyRequest }

View File

@@ -4,7 +4,7 @@ import semmle.python.security.strings.Untrusted
import semmle.python.web.Http
import semmle.python.web.cherrypy.General
class CherryPyExposedFunctionResult extends HttpResponseTaintSink {
deprecated class CherryPyExposedFunctionResult extends HttpResponseTaintSink {
CherryPyExposedFunctionResult() {
exists(Return ret |
ret.getScope() instanceof CherryPyExposedFunction and

View File

@@ -6,7 +6,7 @@
import python
private import semmle.python.web.Http
class RequestsHttpRequest extends Client::HttpRequest, CallNode {
deprecated class RequestsHttpRequest extends Client::HttpRequest, CallNode {
CallableValue func;
string method;

View File

@@ -1,7 +1,7 @@
import python
private import semmle.python.web.Http
ClassValue httpConnectionClass() {
deprecated ClassValue httpConnectionClass() {
// Python 2
result = Value::named("httplib.HTTPConnection")
or
@@ -18,7 +18,7 @@ ClassValue httpConnectionClass() {
result = Value::named("six.moves.http_client.HTTPSConnection")
}
class HttpConnectionHttpRequest extends Client::HttpRequest, CallNode {
deprecated class HttpConnectionHttpRequest extends Client::HttpRequest, CallNode {
CallNode constructor_call;
CallableValue func;

View File

@@ -4,16 +4,18 @@ import semmle.python.security.injection.Sql
/**
* A taint kind representing a django cursor object.
*/
class DjangoDbCursor extends DbCursor {
deprecated class DjangoDbCursor extends DbCursor {
DjangoDbCursor() { this = "django.db.connection.cursor" }
}
private Value theDjangoConnectionObject() { result = Value::named("django.db.connection") }
deprecated private Value theDjangoConnectionObject() {
result = Value::named("django.db.connection")
}
/**
* A kind of taint source representing sources of django cursor objects.
*/
class DjangoDbCursorSource extends DbConnectionSource {
deprecated class DjangoDbCursorSource extends DbConnectionSource {
DjangoDbCursorSource() {
exists(AttrNode cursor |
this.(CallNode).getFunction() = cursor and
@@ -26,13 +28,15 @@ class DjangoDbCursorSource extends DbConnectionSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoDbCursor }
}
ClassValue theDjangoRawSqlClass() { result = Value::named("django.db.models.expressions.RawSQL") }
deprecated ClassValue theDjangoRawSqlClass() {
result = Value::named("django.db.models.expressions.RawSQL")
}
/**
* A sink of taint on calls to `django.db.models.expressions.RawSQL`. This
* allows arbitrary SQL statements to be executed, which is a security risk.
*/
class DjangoRawSqlSink extends SqlInjectionSink {
deprecated class DjangoRawSqlSink extends SqlInjectionSink {
DjangoRawSqlSink() {
exists(CallNode call |
call = theDjangoRawSqlClass().getACall() and

View File

@@ -5,7 +5,7 @@ import semmle.python.web.Http
// TODO: Since django uses `path = partial(...)`, our analysis doesn't understand this is
// a FunctionValue, so we can't use `FunctionValue.getArgumentForCall`
// https://github.com/django/django/blob/master/django/urls/conf.py#L76
abstract class DjangoRoute extends CallNode {
abstract deprecated class DjangoRoute extends CallNode {
DjangoViewHandler getViewHandler() {
result = view_handler_from_view_arg(this.getArg(1))
or
@@ -26,7 +26,7 @@ abstract class DjangoRoute extends CallNode {
* https://docs.djangoproject.com/en/1.11/topics/http/views/
* https://docs.djangoproject.com/en/3.0/topics/http/views/
*/
class DjangoViewHandler extends PythonFunctionValue {
deprecated class DjangoViewHandler extends PythonFunctionValue {
/** Gets the index of the 'request' argument */
int getRequestArgIndex() { result = 0 }
}
@@ -36,7 +36,7 @@ class DjangoViewHandler extends PythonFunctionValue {
* https://docs.djangoproject.com/en/1.11/topics/class-based-views/
* https://docs.djangoproject.com/en/3.0/topics/class-based-views/
*/
private class DjangoViewClass extends ClassValue {
deprecated private class DjangoViewClass extends ClassValue {
DjangoViewClass() {
Value::named("django.views.generic.View") = this.getASuperType()
or
@@ -44,7 +44,7 @@ private class DjangoViewClass extends ClassValue {
}
}
class DjangoClassBasedViewHandler extends DjangoViewHandler {
deprecated class DjangoClassBasedViewHandler extends DjangoViewHandler {
DjangoClassBasedViewHandler() { exists(DjangoViewClass cls | cls.lookup(httpVerbLower()) = this) }
override int getRequestArgIndex() {
@@ -57,7 +57,7 @@ class DjangoClassBasedViewHandler extends DjangoViewHandler {
* Gets the function that will handle requests when `view_arg` is used as the view argument to a
* django route. That is, this methods handles Class-based Views and its `as_view()` function.
*/
private DjangoViewHandler view_handler_from_view_arg(ControlFlowNode view_arg) {
deprecated private DjangoViewHandler view_handler_from_view_arg(ControlFlowNode view_arg) {
// Function-based view
result = view_arg.pointsTo()
or
@@ -70,11 +70,11 @@ private DjangoViewHandler view_handler_from_view_arg(ControlFlowNode view_arg) {
// We need this "dummy" class, since otherwise the regex argument would not be considered
// a regex (RegexString is abstract)
class DjangoRouteRegex extends RegexString {
deprecated class DjangoRouteRegex extends RegexString {
DjangoRouteRegex() { exists(DjangoRegexRoute route | route.getRouteArg() = this.getAFlowNode()) }
}
class DjangoRegexRoute extends DjangoRoute {
deprecated class DjangoRegexRoute extends DjangoRoute {
ControlFlowNode route;
DjangoRegexRoute() {
@@ -109,7 +109,7 @@ class DjangoRegexRoute extends DjangoRoute {
}
}
class DjangoPathRoute extends DjangoRoute {
deprecated class DjangoPathRoute extends DjangoRoute {
ControlFlowNode route;
DjangoPathRoute() {

View File

@@ -5,12 +5,12 @@ import semmle.python.web.Http
import semmle.python.security.injection.Sql
/** A django model class */
class DjangoModel extends ClassValue {
deprecated class DjangoModel extends ClassValue {
DjangoModel() { Value::named("django.db.models.Model") = this.getASuperType() }
}
/** A "taint" for django database tables */
class DjangoDbTableObjects extends TaintKind {
deprecated class DjangoDbTableObjects extends TaintKind {
DjangoDbTableObjects() { this = "django.db.models.Model.objects" }
override TaintKind getTaintOfMethodResult(string name) {
@@ -24,7 +24,7 @@ class DjangoDbTableObjects extends TaintKind {
}
/** Django model objects, which are sources of django database table "taint" */
class DjangoModelObjects extends TaintSource {
deprecated class DjangoModelObjects extends TaintSource {
DjangoModelObjects() {
this.(AttrNode).isLoad() and this.(AttrNode).getObject("objects").pointsTo(any(DjangoModel m))
}
@@ -38,7 +38,7 @@ class DjangoModelObjects extends TaintSource {
* A call to the `raw` method on a django model. This allows a raw SQL query
* to be sent to the database, which is a security risk.
*/
class DjangoModelRawCall extends SqlInjectionSink {
deprecated class DjangoModelRawCall extends SqlInjectionSink {
DjangoModelRawCall() {
exists(CallNode raw_call, ControlFlowNode queryset | this = raw_call.getArg(0) |
raw_call.getFunction().(AttrNode).getObject("raw") = queryset and
@@ -55,7 +55,7 @@ class DjangoModelRawCall extends SqlInjectionSink {
* A call to the `extra` method on a django model. This allows a raw SQL query
* to be sent to the database, which is a security risk.
*/
class DjangoModelExtraCall extends SqlInjectionSink {
deprecated class DjangoModelExtraCall extends SqlInjectionSink {
DjangoModelExtraCall() {
exists(CallNode extra_call, ControlFlowNode queryset | this = extra_call.getArg(0) |
extra_call.getFunction().(AttrNode).getObject("extra") = queryset and

View File

@@ -13,7 +13,7 @@ private import semmle.python.web.Http
/**
* The URL argument for a call to the `django.shortcuts.redirect` function.
*/
class DjangoShortcutsRedirectSink extends HttpRedirectTaintSink {
deprecated class DjangoShortcutsRedirectSink extends HttpRedirectTaintSink {
override string toString() { result = "DjangoShortcutsRedirectSink" }
DjangoShortcutsRedirectSink() {
@@ -27,7 +27,7 @@ deprecated class DjangoRedirect = DjangoShortcutsRedirectSink;
/**
* The URL argument when instantiating a Django Redirect Response.
*/
class DjangoRedirectResponseSink extends HttpRedirectTaintSink {
deprecated class DjangoRedirectResponseSink extends HttpRedirectTaintSink {
DjangoRedirectResponseSink() {
exists(CallNode call | call = any(DjangoRedirectResponseClass cls).getACall() |
this = call.getArg(0)

View File

@@ -4,7 +4,7 @@ import semmle.python.web.Http
import semmle.python.web.django.General
/** A django.request.HttpRequest object */
class DjangoRequest extends TaintKind {
deprecated class DjangoRequest extends TaintKind {
DjangoRequest() { this = "django.request.HttpRequest" }
override TaintKind getTaintOfAttribute(string name) {
@@ -20,13 +20,13 @@ class DjangoRequest extends TaintKind {
/* Helper for getTaintForStep() */
pragma[noinline]
private predicate subscript_taint(SubscriptNode sub, ControlFlowNode obj, TaintKind kind) {
deprecated private predicate subscript_taint(SubscriptNode sub, ControlFlowNode obj, TaintKind kind) {
sub.getObject() = obj and
kind instanceof ExternalStringKind
}
/** A django.request.QueryDict object */
class DjangoQueryDict extends TaintKind {
deprecated class DjangoQueryDict extends TaintKind {
DjangoQueryDict() { this = "django.http.request.QueryDict" }
override TaintKind getTaintForFlowStep(ControlFlowNode fromnode, ControlFlowNode tonode) {
@@ -40,7 +40,7 @@ class DjangoQueryDict extends TaintKind {
}
/** A Django request parameter */
class DjangoRequestSource extends HttpRequestTaintSource {
deprecated class DjangoRequestSource extends HttpRequestTaintSource {
DjangoRequestSource() {
exists(DjangoRoute route, DjangoViewHandler view, int request_arg_index |
route.getViewHandler() = view and
@@ -55,7 +55,7 @@ class DjangoRequestSource extends HttpRequestTaintSource {
}
/** An argument specified in a url routing table */
class DjangoRequestParameter extends HttpRequestTaintSource {
deprecated class DjangoRequestParameter extends HttpRequestTaintSource {
DjangoRequestParameter() {
exists(DjangoRoute route, Function f, DjangoViewHandler view, int request_arg_index |
route.getViewHandler() = view and

View File

@@ -15,12 +15,12 @@ private import semmle.python.web.Http
deprecated class DjangoResponse = DjangoResponseKind;
/** INTERNAL class used for tracking a django response object. */
private class DjangoResponseKind extends TaintKind {
deprecated private class DjangoResponseKind extends TaintKind {
DjangoResponseKind() { this = "django.response.HttpResponse" }
}
/** INTERNAL taint-source used for tracking a django response object. */
private class DjangoResponseSource extends TaintSource {
deprecated private class DjangoResponseSource extends TaintSource {
DjangoResponseSource() { exists(DjangoContentResponseClass cls | cls.getACall() = this) }
override predicate isSourceOf(TaintKind kind) { kind instanceof DjangoResponseKind }
@@ -29,7 +29,7 @@ private class DjangoResponseSource extends TaintSource {
}
/** A write to a django response, which is vulnerable to external data (xss) */
class DjangoResponseWrite extends HttpResponseTaintSink {
deprecated class DjangoResponseWrite extends HttpResponseTaintSink {
DjangoResponseWrite() {
exists(AttrNode meth, CallNode call |
call.getFunction() = meth and
@@ -46,7 +46,7 @@ class DjangoResponseWrite extends HttpResponseTaintSink {
/**
* An argument to initialization of a django response.
*/
class DjangoResponseContent extends HttpResponseTaintSink {
deprecated class DjangoResponseContent extends HttpResponseTaintSink {
DjangoContentResponseClass cls;
CallNode call;
@@ -63,7 +63,7 @@ class DjangoResponseContent extends HttpResponseTaintSink {
/**
* An argument to initialization of a django response, which is vulnerable to external data (XSS).
*/
class DjangoResponseContentXSSVulnerable extends DjangoResponseContent {
deprecated class DjangoResponseContentXSSVulnerable extends DjangoResponseContent {
override DjangoXSSVulnerableResponseClass cls;
DjangoResponseContentXSSVulnerable() {
@@ -76,7 +76,7 @@ class DjangoResponseContentXSSVulnerable extends DjangoResponseContent {
}
}
class DjangoCookieSet extends CookieSet, CallNode {
deprecated class DjangoCookieSet extends CookieSet, CallNode {
DjangoCookieSet() {
any(DjangoResponseKind r).taints(this.getFunction().(AttrNode).getObject("set_cookie"))
}

View File

@@ -13,7 +13,7 @@ deprecated ClassValue theDjangoHttpRedirectClass() {
}
/** A class that is a Django Redirect Response (subclass of `django.http.HttpResponseRedirectBase`). */
class DjangoRedirectResponseClass extends ClassValue {
deprecated class DjangoRedirectResponseClass extends ClassValue {
DjangoRedirectResponseClass() {
exists(ClassValue redirect_base |
// version 1.x
@@ -31,7 +31,7 @@ class DjangoRedirectResponseClass extends ClassValue {
* A class that is a Django Response, which can contain content.
* A subclass of `django.http.HttpResponse` that is not a `DjangoRedirectResponseClass`.
*/
class DjangoContentResponseClass extends ClassValue {
deprecated class DjangoContentResponseClass extends ClassValue {
ClassValue base;
DjangoContentResponseClass() {
@@ -59,7 +59,7 @@ class DjangoContentResponseClass extends ClassValue {
}
/** A class that is a Django Response, and is vulnerable to XSS. */
class DjangoXSSVulnerableResponseClass extends DjangoContentResponseClass {
deprecated class DjangoXSSVulnerableResponseClass extends DjangoContentResponseClass {
DjangoXSSVulnerableResponseClass() {
// We want to avoid FPs on subclasses that are not exposed to XSS, for example `JsonResponse`.
// The easiest way is to disregard any subclass that has a special `__init__` method.

View File

@@ -2,21 +2,23 @@ import python
import semmle.python.web.Http
/** The falcon API class */
ClassValue theFalconAPIClass() { result = Value::named("falcon.API") }
deprecated ClassValue theFalconAPIClass() { result = Value::named("falcon.API") }
/** Holds if `route` is routed to `resource` */
private predicate api_route(CallNode route_call, ControlFlowNode route, ClassValue resource) {
deprecated private predicate api_route(
CallNode route_call, ControlFlowNode route, ClassValue resource
) {
route_call.getFunction().(AttrNode).getObject("add_route").pointsTo().getClass() =
theFalconAPIClass() and
route_call.getArg(0) = route and
route_call.getArg(1).pointsTo().getClass() = resource
}
private predicate route(FalconRoute route, Function target, string funcname) {
deprecated private predicate route(FalconRoute route, Function target, string funcname) {
route.getResourceClass().lookup("on_" + funcname).(FunctionValue).getScope() = target
}
class FalconRoute extends ControlFlowNode {
deprecated class FalconRoute extends ControlFlowNode {
FalconRoute() { api_route(this, _, _) }
string getUrl() {
@@ -31,7 +33,7 @@ class FalconRoute extends ControlFlowNode {
FalconHandlerFunction getHandlerFunction(string method) { route(this, result, method) }
}
class FalconHandlerFunction extends Function {
deprecated class FalconHandlerFunction extends Function {
FalconHandlerFunction() { route(_, this, _) }
private string methodName() { route(_, this, result) }

View File

@@ -5,7 +5,7 @@ import semmle.python.web.falcon.General
import semmle.python.security.strings.External
/** https://falcon.readthedocs.io/en/stable/api/request_and_response.html */
class FalconRequest extends TaintKind {
deprecated class FalconRequest extends TaintKind {
FalconRequest() { this = "falcon.request" }
override TaintKind getTaintOfAttribute(string name) {
@@ -29,7 +29,7 @@ class FalconRequest extends TaintKind {
}
}
class FalconRequestParameter extends HttpRequestTaintSource {
deprecated class FalconRequestParameter extends HttpRequestTaintSource {
FalconRequestParameter() {
exists(FalconHandlerFunction f | f.getRequest() = this.(ControlFlowNode).getNode())
}

View File

@@ -5,12 +5,12 @@ import semmle.python.web.falcon.General
import semmle.python.security.strings.External
/** https://falcon.readthedocs.io/en/stable/api/request_and_response.html */
class FalconResponse extends TaintKind {
deprecated class FalconResponse extends TaintKind {
FalconResponse() { this = "falcon.response" }
}
/** Only used internally to track the response parameter */
private class FalconResponseParameter extends TaintSource {
deprecated private class FalconResponseParameter extends TaintSource {
FalconResponseParameter() {
exists(FalconHandlerFunction f | f.getResponse() = this.(ControlFlowNode).getNode())
}
@@ -18,7 +18,7 @@ private class FalconResponseParameter extends TaintSource {
override predicate isSourceOf(TaintKind k) { k instanceof FalconResponse }
}
class FalconResponseBodySink extends HttpResponseTaintSink {
deprecated class FalconResponseBodySink extends HttpResponseTaintSink {
FalconResponseBodySink() {
exists(AttrNode attr | any(FalconResponse f).taints(attr.getObject("body")) |
attr.(DefinitionNode).getValue() = this

View File

@@ -3,18 +3,18 @@ import semmle.python.web.Http
import semmle.python.web.flask.Response
/** The flask app class */
ClassValue theFlaskClass() { result = Value::named("flask.Flask") }
deprecated ClassValue theFlaskClass() { result = Value::named("flask.Flask") }
/** The flask MethodView class */
ClassValue theFlaskMethodViewClass() { result = Value::named("flask.views.MethodView") }
deprecated ClassValue theFlaskMethodViewClass() { result = Value::named("flask.views.MethodView") }
ClassValue theFlaskReponseClass() { result = Value::named("flask.Response") }
deprecated ClassValue theFlaskReponseClass() { result = Value::named("flask.Response") }
/**
* Holds if `route` is routed to `func`
* by decorating `func` with `app.route(route)`
*/
predicate app_route(ControlFlowNode route, Function func) {
deprecated predicate app_route(ControlFlowNode route, Function func) {
exists(CallNode route_call, CallNode decorator_call |
route_call.getFunction().(AttrNode).getObject("route").pointsTo().getClass() = theFlaskClass() and
decorator_call.getFunction() = route_call and
@@ -24,7 +24,7 @@ predicate app_route(ControlFlowNode route, Function func) {
}
/* Helper for add_url_rule */
private predicate add_url_rule_call(ControlFlowNode regex, ControlFlowNode callable) {
deprecated private predicate add_url_rule_call(ControlFlowNode regex, ControlFlowNode callable) {
exists(CallNode call |
call.getFunction().(AttrNode).getObject("add_url_rule").pointsTo().getClass() = theFlaskClass() and
regex = call.getArg(0)
@@ -35,7 +35,7 @@ private predicate add_url_rule_call(ControlFlowNode regex, ControlFlowNode calla
}
/** Holds if urls matching `regex` are routed to `func` */
predicate add_url_rule(ControlFlowNode regex, Function func) {
deprecated predicate add_url_rule(ControlFlowNode regex, Function func) {
exists(ControlFlowNode callable | add_url_rule_call(regex, callable) |
exists(PythonFunctionValue f | f.getScope() = func and callable.pointsTo(f))
or
@@ -51,14 +51,14 @@ predicate add_url_rule(ControlFlowNode regex, Function func) {
* Holds if urls matching `regex` are routed to `func` using
* any of flask's routing mechanisms.
*/
predicate flask_routing(ControlFlowNode regex, Function func) {
deprecated predicate flask_routing(ControlFlowNode regex, Function func) {
app_route(regex, func)
or
add_url_rule(regex, func)
}
/** A class that extends flask.views.MethodView */
private class MethodViewClass extends ClassValue {
deprecated private class MethodViewClass extends ClassValue {
MethodViewClass() { this.getASuperType() = theFlaskMethodViewClass() }
/* As we are restricted to strings for taint kinds, we need to map these classes to strings. */
@@ -68,12 +68,12 @@ private class MethodViewClass extends ClassValue {
TaintKind asTaint() { result = this.taintString() }
}
private class MethodViewTaint extends TaintKind {
deprecated private class MethodViewTaint extends TaintKind {
MethodViewTaint() { any(MethodViewClass cls).taintString() = this }
}
/** A source of method view "taint"s. */
private class AsView extends TaintSource {
deprecated private class AsView extends TaintSource {
AsView() {
exists(ClassValue view_class |
view_class.getASuperType() = theFlaskMethodViewClass() and
@@ -91,7 +91,7 @@ private class AsView extends TaintSource {
}
}
class FlaskCookieSet extends CookieSet, CallNode {
deprecated class FlaskCookieSet extends CookieSet, CallNode {
FlaskCookieSet() {
any(FlaskResponseTaintKind t).taints(this.getFunction().(AttrNode).getObject("set_cookie"))
}

View File

@@ -9,12 +9,12 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.flask.General
FunctionValue flask_redirect() { result = Value::named("flask.redirect") }
deprecated FunctionValue flask_redirect() { result = Value::named("flask.redirect") }
/**
* Represents an argument to the `flask.redirect` function.
*/
class FlaskRedirect extends HttpRedirectTaintSink {
deprecated class FlaskRedirect extends HttpRedirectTaintSink {
override string toString() { result = "flask.redirect" }
FlaskRedirect() {

View File

@@ -3,16 +3,16 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.web.Http
import semmle.python.web.flask.General
private Value theFlaskRequestObject() { result = Value::named("flask.request") }
deprecated private Value theFlaskRequestObject() { result = Value::named("flask.request") }
/** Holds if `attr` is an access of attribute `name` of the flask request object */
private predicate flask_request_attr(AttrNode attr, string name) {
deprecated private predicate flask_request_attr(AttrNode attr, string name) {
attr.isLoad() and
attr.getObject(name).pointsTo(theFlaskRequestObject())
}
/** Source of external data from a flask request */
class FlaskRequestData extends HttpRequestTaintSource {
deprecated class FlaskRequestData extends HttpRequestTaintSource {
FlaskRequestData() {
not this instanceof FlaskRequestArgs and
exists(string name | flask_request_attr(this, name) |
@@ -26,7 +26,7 @@ class FlaskRequestData extends HttpRequestTaintSource {
}
/** Source of dictionary whose values are externally controlled */
class FlaskRequestArgs extends HttpRequestTaintSource {
deprecated class FlaskRequestArgs extends HttpRequestTaintSource {
FlaskRequestArgs() {
exists(string attr | flask_request_attr(this, attr) |
attr in ["args", "form", "values", "files", "headers", "json"]
@@ -39,7 +39,7 @@ class FlaskRequestArgs extends HttpRequestTaintSource {
}
/** Source of dictionary whose values are externally controlled */
class FlaskRequestJson extends HttpRequestTaintSource {
deprecated class FlaskRequestJson extends HttpRequestTaintSource {
FlaskRequestJson() { flask_request_attr(this, "json") }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalJsonKind }
@@ -57,7 +57,7 @@ class FlaskRequestJson extends HttpRequestTaintSource {
* def hello(name):
* ```
*/
class FlaskRoutedParameter extends HttpRequestTaintSource {
deprecated class FlaskRoutedParameter extends HttpRequestTaintSource {
FlaskRoutedParameter() {
exists(string name, Function func, StrConst url_pattern |
this.(ControlFlowNode).getNode() = func.getArgByName(name) and
@@ -72,7 +72,7 @@ class FlaskRoutedParameter extends HttpRequestTaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
}
private string werkzeug_rule_re() {
deprecated private string werkzeug_rule_re() {
// since flask uses werkzeug internally, we are using its routing rules from
// https://github.com/pallets/werkzeug/blob/4dc8d6ab840d4b78cbd5789cef91b01e3bde01d5/src/werkzeug/routing.py#L138-L151
result =

View File

@@ -7,7 +7,7 @@ import semmle.python.web.flask.General
* A flask response, which is vulnerable to any sort of
* http response malice.
*/
class FlaskRoutedResponse extends HttpResponseTaintSink {
deprecated class FlaskRoutedResponse extends HttpResponseTaintSink {
FlaskRoutedResponse() {
exists(PythonFunctionValue response |
flask_routing(_, response.getScope()) and
@@ -20,7 +20,7 @@ class FlaskRoutedResponse extends HttpResponseTaintSink {
override string toString() { result = "flask.routed.response" }
}
class FlaskResponseArgument extends HttpResponseTaintSink {
deprecated class FlaskResponseArgument extends HttpResponseTaintSink {
FlaskResponseArgument() {
exists(CallNode call |
(
@@ -37,11 +37,11 @@ class FlaskResponseArgument extends HttpResponseTaintSink {
override string toString() { result = "flask.response.argument" }
}
class FlaskResponseTaintKind extends TaintKind {
deprecated class FlaskResponseTaintKind extends TaintKind {
FlaskResponseTaintKind() { this = "flask.Response" }
}
class FlaskResponseConfiguration extends TaintTracking::Configuration {
deprecated class FlaskResponseConfiguration extends TaintTracking::Configuration {
FlaskResponseConfiguration() { this = "Flask response configuration" }
override predicate isSource(DataFlow::Node node, TaintKind kind) {

View File

@@ -9,7 +9,7 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Basic
import semmle.python.web.Http
private ClassValue redirectClass() {
deprecated private ClassValue redirectClass() {
exists(ModuleValue ex | ex.getName() = "pyramid.httpexceptions" |
ex.attr("HTTPFound") = result
or
@@ -20,7 +20,7 @@ private ClassValue redirectClass() {
/**
* Represents an argument to the `tornado.redirect` function.
*/
class PyramidRedirect extends HttpRedirectTaintSink {
deprecated class PyramidRedirect extends HttpRedirectTaintSink {
override string toString() { result = "pyramid.redirect" }
PyramidRedirect() {

View File

@@ -4,14 +4,14 @@ import semmle.python.web.Http
private import semmle.python.web.webob.Request
private import semmle.python.web.pyramid.View
class PyramidRequest extends BaseWebobRequest {
deprecated class PyramidRequest extends BaseWebobRequest {
PyramidRequest() { this = "pyramid.request" }
override ClassValue getType() { result = Value::named("pyramid.request.Request") }
}
/** Source of pyramid request objects */
class PyramidViewArgument extends HttpRequestTaintSource {
deprecated class PyramidViewArgument extends HttpRequestTaintSource {
PyramidViewArgument() {
exists(Function view_func |
is_pyramid_view_function(view_func) and

View File

@@ -9,7 +9,7 @@ private import semmle.python.web.Http
* A pyramid response, which is vulnerable to any sort of
* http response malice.
*/
class PyramidRoutedResponse extends HttpResponseTaintSink {
deprecated class PyramidRoutedResponse extends HttpResponseTaintSink {
PyramidRoutedResponse() {
exists(PythonFunctionValue view |
is_pyramid_view_function(view.getScope()) and
@@ -22,7 +22,7 @@ class PyramidRoutedResponse extends HttpResponseTaintSink {
override string toString() { result = "pyramid.routed.response" }
}
class PyramidCookieSet extends CookieSet, CallNode {
deprecated class PyramidCookieSet extends CookieSet, CallNode {
PyramidCookieSet() {
exists(ControlFlowNode f |
f = this.getFunction().(AttrNode).getObject("set_cookie") and

View File

@@ -1,9 +1,9 @@
import python
ModuleValue thePyramidViewModule() { result.getName() = "pyramid.view" }
deprecated ModuleValue thePyramidViewModule() { result.getName() = "pyramid.view" }
Value thePyramidViewConfig() { result = thePyramidViewModule().attr("view_config") }
deprecated Value thePyramidViewConfig() { result = thePyramidViewModule().attr("view_config") }
predicate is_pyramid_view_function(Function func) {
deprecated predicate is_pyramid_view_function(Function func) {
func.getADecorator().pointsTo().getClass() = thePyramidViewConfig()
}

View File

@@ -9,7 +9,7 @@ import semmle.python.dataflow.TaintTracking
import semmle.python.web.Http
/** Source of BaseHTTPRequestHandler instances. */
class StdLibRequestSource extends HttpRequestTaintSource {
deprecated class StdLibRequestSource extends HttpRequestTaintSource {
StdLibRequestSource() {
exists(ClassValue cls |
cls.getABaseType+() = Value::named("BaseHTTPServer.BaseHTTPRequestHandler")
@@ -24,7 +24,7 @@ class StdLibRequestSource extends HttpRequestTaintSource {
}
/** TaintKind for an instance of BaseHTTPRequestHandler. */
class BaseHTTPRequestHandlerKind extends TaintKind {
deprecated class BaseHTTPRequestHandlerKind extends TaintKind {
BaseHTTPRequestHandlerKind() { this = "BaseHTTPRequestHandlerKind" }
override TaintKind getTaintOfAttribute(string name) {
@@ -40,7 +40,7 @@ class BaseHTTPRequestHandlerKind extends TaintKind {
}
/** TaintKind for headers (instance of HTTPMessage). */
class HTTPMessageKind extends ExternalStringDictKind {
deprecated class HTTPMessageKind extends ExternalStringDictKind {
override TaintKind getTaintOfMethodResult(string name) {
result = super.getTaintOfMethodResult(name)
or
@@ -63,14 +63,14 @@ class HTTPMessageKind extends ExternalStringDictKind {
}
/** Source of parsed HTTP forms (by using the `cgi` module). */
class CgiFieldStorageSource extends HttpRequestTaintSource {
deprecated class CgiFieldStorageSource extends HttpRequestTaintSource {
CgiFieldStorageSource() { this = Value::named("cgi.FieldStorage").getACall() }
override predicate isSourceOf(TaintKind kind) { kind instanceof CgiFieldStorageFormKind }
}
/** TaintKind for a parsed HTTP form. */
class CgiFieldStorageFormKind extends TaintKind {
deprecated class CgiFieldStorageFormKind extends TaintKind {
/*
* There is a slight difference between how we model form/fields and how it is handled by the code.
* In the code
@@ -115,7 +115,7 @@ class CgiFieldStorageFormKind extends TaintKind {
}
/** TaintKind for the field of a parsed HTTP form. */
class CgiFieldStorageFieldKind extends TaintKind {
deprecated class CgiFieldStorageFieldKind extends TaintKind {
CgiFieldStorageFieldKind() { this = "CgiFieldStorageFieldKind" }
override TaintKind getTaintOfAttribute(string name) {

View File

@@ -6,7 +6,7 @@ import python
import semmle.python.dataflow.TaintTracking
import semmle.python.web.Http
private predicate is_wfile(AttrNode wfile) {
deprecated private predicate is_wfile(AttrNode wfile) {
exists(ClassValue cls |
// Python 2
cls.getABaseType+() = Value::named("BaseHTTPServer.BaseHTTPRequestHandler")
@@ -19,7 +19,7 @@ private predicate is_wfile(AttrNode wfile) {
}
/** Sink for `h.wfile.write` where `h` is an instance of BaseHTTPRequestHandler. */
class StdLibWFileWriteSink extends HttpResponseTaintSink {
deprecated class StdLibWFileWriteSink extends HttpResponseTaintSink {
StdLibWFileWriteSink() {
exists(CallNode call |
is_wfile(call.getFunction().(AttrNode).getObject("write")) and
@@ -31,7 +31,7 @@ class StdLibWFileWriteSink extends HttpResponseTaintSink {
}
/** Sink for `h.wfile.writelines` where `h` is an instance of BaseHTTPRequestHandler. */
class StdLibWFileWritelinesSink extends HttpResponseTaintSink {
deprecated class StdLibWFileWritelinesSink extends HttpResponseTaintSink {
StdLibWFileWritelinesSink() {
exists(CallNode call |
is_wfile(call.getFunction().(AttrNode).getObject("writelines")) and

View File

@@ -13,7 +13,7 @@ import Tornado
/**
* Represents an argument to the `tornado.redirect` function.
*/
class TornadoHttpRequestHandlerRedirect extends HttpRedirectTaintSink {
deprecated class TornadoHttpRequestHandlerRedirect extends HttpRedirectTaintSink {
override string toString() { result = "tornado.HttpRequestHandler.redirect" }
TornadoHttpRequestHandlerRedirect() {

View File

@@ -4,7 +4,7 @@ import semmle.python.web.Http
import Tornado
/** A tornado.request.HttpRequest object */
class TornadoRequest extends TaintKind {
deprecated class TornadoRequest extends TaintKind {
TornadoRequest() { this = "tornado.request.HttpRequest" }
override TaintKind getTaintOfAttribute(string name) {
@@ -30,7 +30,7 @@ class TornadoRequest extends TaintKind {
}
}
class TornadoRequestSource extends HttpRequestTaintSource {
deprecated class TornadoRequestSource extends HttpRequestTaintSource {
TornadoRequestSource() { isTornadoRequestHandlerInstance(this.(AttrNode).getObject("request")) }
override string toString() { result = "Tornado request source" }
@@ -38,7 +38,7 @@ class TornadoRequestSource extends HttpRequestTaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoRequest }
}
class TornadoExternalInputSource extends HttpRequestTaintSource {
deprecated class TornadoExternalInputSource extends HttpRequestTaintSource {
TornadoExternalInputSource() {
exists(string name |
name in ["get_argument", "get_query_argument", "get_body_argument", "decode_argument"]
@@ -52,7 +52,7 @@ class TornadoExternalInputSource extends HttpRequestTaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
}
class TornadoExternalInputListSource extends HttpRequestTaintSource {
deprecated class TornadoExternalInputListSource extends HttpRequestTaintSource {
TornadoExternalInputListSource() {
exists(string name |
name = "get_arguments" or

View File

@@ -4,11 +4,11 @@ import semmle.python.security.strings.Basic
private import semmle.python.web.Http
import Tornado
class TornadoConnection extends TaintKind {
deprecated class TornadoConnection extends TaintKind {
TornadoConnection() { this = "tornado.http.connection" }
}
class TornadoConnectionSource extends TaintSource {
deprecated class TornadoConnectionSource extends TaintSource {
TornadoConnectionSource() {
isTornadoRequestHandlerInstance(this.(AttrNode).getObject("connection"))
}
@@ -18,7 +18,7 @@ class TornadoConnectionSource extends TaintSource {
override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoConnection }
}
class TornadoConnectionWrite extends HttpResponseTaintSink {
deprecated class TornadoConnectionWrite extends HttpResponseTaintSink {
override string toString() { result = "tornado.connection.write" }
TornadoConnectionWrite() {
@@ -32,7 +32,7 @@ class TornadoConnectionWrite extends HttpResponseTaintSink {
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}
class TornadoHttpRequestHandlerWrite extends HttpResponseTaintSink {
deprecated class TornadoHttpRequestHandlerWrite extends HttpResponseTaintSink {
override string toString() { result = "tornado.HttpRequestHandler.write" }
TornadoHttpRequestHandlerWrite() {

View File

@@ -2,11 +2,11 @@ import python
import semmle.python.dataflow.TaintTracking
import semmle.python.web.Http
private ClassValue theTornadoRequestHandlerClass() {
deprecated private ClassValue theTornadoRequestHandlerClass() {
result = Value::named("tornado.web.RequestHandler")
}
ClassValue aTornadoRequestHandlerClass() {
deprecated ClassValue aTornadoRequestHandlerClass() {
result.getABaseType+() = theTornadoRequestHandlerClass()
}
@@ -14,7 +14,7 @@ ClassValue aTornadoRequestHandlerClass() {
* Holds if `node` is likely to refer to an instance of a tornado
* `RequestHandler` class.
*/
predicate isTornadoRequestHandlerInstance(ControlFlowNode node) {
deprecated predicate isTornadoRequestHandlerInstance(ControlFlowNode node) {
node.pointsTo().getClass() = aTornadoRequestHandlerClass()
or
/*
@@ -30,11 +30,11 @@ predicate isTornadoRequestHandlerInstance(ControlFlowNode node) {
node.(NameNode).isSelf()
}
CallNode callToNamedTornadoRequestHandlerMethod(string name) {
deprecated CallNode callToNamedTornadoRequestHandlerMethod(string name) {
isTornadoRequestHandlerInstance(result.getFunction().(AttrNode).getObject(name))
}
class TornadoCookieSet extends CookieSet, CallNode {
deprecated class TornadoCookieSet extends CookieSet, CallNode {
TornadoCookieSet() {
exists(ControlFlowNode f |
f = this.getFunction().(AttrNode).getObject("set_cookie") and

View File

@@ -3,7 +3,7 @@ import semmle.python.security.strings.External
import semmle.python.web.Http
import TurboGears
private class ValidatedMethodParameter extends Parameter {
deprecated private class ValidatedMethodParameter extends Parameter {
ValidatedMethodParameter() {
exists(string name, TurboGearsControllerMethod method |
method.getArgByName(name) = this and
@@ -12,7 +12,7 @@ private class ValidatedMethodParameter extends Parameter {
}
}
class UnvalidatedControllerMethodParameter extends HttpRequestTaintSource {
deprecated class UnvalidatedControllerMethodParameter extends HttpRequestTaintSource {
UnvalidatedControllerMethodParameter() {
exists(Parameter p |
any(TurboGearsControllerMethod m | not m.getName() = "onerror").getAnArg() = p and

View File

@@ -4,7 +4,7 @@ import semmle.python.security.strings.Basic
import semmle.python.web.Http
import TurboGears
class ControllerMethodReturnValue extends HttpResponseTaintSink {
deprecated class ControllerMethodReturnValue extends HttpResponseTaintSink {
override string toString() { result = "TurboGears ControllerMethodReturnValue" }
ControllerMethodReturnValue() {
@@ -17,7 +17,7 @@ class ControllerMethodReturnValue extends HttpResponseTaintSink {
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
}
class ControllerMethodTemplatedReturnValue extends HttpResponseTaintSink {
deprecated class ControllerMethodTemplatedReturnValue extends HttpResponseTaintSink {
override string toString() { result = "TurboGears ControllerMethodTemplatedReturnValue" }
ControllerMethodTemplatedReturnValue() {

View File

@@ -1,11 +1,15 @@
import python
import semmle.python.dataflow.TaintTracking
private ClassValue theTurboGearsControllerClass() { result = Value::named("tg.TGController") }
deprecated private ClassValue theTurboGearsControllerClass() {
result = Value::named("tg.TGController")
}
ClassValue aTurboGearsControllerClass() { result.getABaseType+() = theTurboGearsControllerClass() }
deprecated ClassValue aTurboGearsControllerClass() {
result.getABaseType+() = theTurboGearsControllerClass()
}
class TurboGearsControllerMethod extends Function {
deprecated class TurboGearsControllerMethod extends Function {
ControlFlowNode decorator;
TurboGearsControllerMethod() {

View File

@@ -4,7 +4,7 @@ import semmle.python.web.Http
import Twisted
/** A twisted.web.http.Request object */
class TwistedRequest extends TaintKind {
deprecated class TwistedRequest extends TaintKind {
TwistedRequest() { this = "twisted.request.http.Request" }
override TaintKind getTaintOfAttribute(string name) {
@@ -21,7 +21,7 @@ class TwistedRequest extends TaintKind {
}
}
class TwistedRequestSource extends HttpRequestTaintSource {
deprecated class TwistedRequestSource extends HttpRequestTaintSource {
TwistedRequestSource() { isTwistedRequestInstance(this) }
override string toString() { result = "Twisted request source" }

View File

@@ -5,7 +5,7 @@ import semmle.python.security.strings.Basic
import Twisted
import Request
class TwistedResponse extends HttpResponseTaintSink {
deprecated class TwistedResponse extends HttpResponseTaintSink {
TwistedResponse() {
exists(PythonFunctionValue func, string name |
isKnownRequestHandlerMethodName(name) and
@@ -25,7 +25,7 @@ class TwistedResponse extends HttpResponseTaintSink {
* object, which affects the properties of the subsequent response sent to this
* request.
*/
class TwistedRequestSetter extends HttpResponseTaintSink {
deprecated class TwistedRequestSetter extends HttpResponseTaintSink {
TwistedRequestSetter() {
exists(CallNode call, ControlFlowNode node, string name |
(

View File

@@ -1,22 +1,24 @@
import python
import semmle.python.dataflow.TaintTracking
private ClassValue theTwistedHttpRequestClass() {
deprecated private ClassValue theTwistedHttpRequestClass() {
result = Value::named("twisted.web.http.Request")
}
private ClassValue theTwistedHttpResourceClass() {
deprecated private ClassValue theTwistedHttpResourceClass() {
result = Value::named("twisted.web.resource.Resource")
}
ClassValue aTwistedRequestHandlerClass() { result.getABaseType+() = theTwistedHttpResourceClass() }
deprecated ClassValue aTwistedRequestHandlerClass() {
result.getABaseType+() = theTwistedHttpResourceClass()
}
FunctionValue getTwistedRequestHandlerMethod(string name) {
deprecated FunctionValue getTwistedRequestHandlerMethod(string name) {
result = aTwistedRequestHandlerClass().declaredAttribute(name)
}
bindingset[name]
predicate isKnownRequestHandlerMethodName(string name) {
deprecated predicate isKnownRequestHandlerMethodName(string name) {
name = "render" or
name.matches("render_%")
}
@@ -25,7 +27,7 @@ predicate isKnownRequestHandlerMethodName(string name) {
* Holds if `node` is likely to refer to an instance of the twisted
* `Request` class.
*/
predicate isTwistedRequestInstance(NameNode node) {
deprecated predicate isTwistedRequestInstance(NameNode node) {
node.pointsTo().getClass() = theTwistedHttpRequestClass()
or
/*

View File

@@ -2,7 +2,7 @@ import python
import semmle.python.dataflow.TaintTracking
import semmle.python.web.Http
abstract class BaseWebobRequest extends TaintKind {
abstract deprecated class BaseWebobRequest extends TaintKind {
bindingset[this]
BaseWebobRequest() { any() }
@@ -31,7 +31,7 @@ abstract class BaseWebobRequest extends TaintKind {
}
}
class WebobRequest extends BaseWebobRequest {
deprecated class WebobRequest extends BaseWebobRequest {
WebobRequest() { this = "webob.Request" }
override ClassValue getType() { result = Value::named("webob.request.Request") }

View File

@@ -6,122 +6,22 @@
*/
class Person extends string {
Person() {
this = "Ronil" or
this = "Dina" or
this = "Ravi" or
this = "Bruce" or
this = "Jo" or
this = "Aida" or
this = "Esme" or
this = "Charlie" or
this = "Fred" or
this = "Meera" or
this = "Maya" or
this = "Chad" or
this = "Tiana" or
this = "Laura" or
this = "George" or
this = "Will" or
this = "Mary" or
this = "Almira" or
this = "Susannah" or
this = "Rhoda" or
this = "Cynthia" or
this = "Eunice" or
this = "Olive" or
this = "Virginia" or
this = "Angeline" or
this = "Helen" or
this = "Cornelia" or
this = "Harriet" or
this = "Mahala" or
this = "Abby" or
this = "Margaret" or
this = "Deb" or
this = "Minerva" or
this = "Severus" or
this = "Lavina" or
this = "Adeline" or
this = "Cath" or
this = "Elisa" or
this = "Lucretia" or
this = "Anne" or
this = "Eleanor" or
this = "Joanna" or
this = "Adam" or
this = "Agnes" or
this = "Rosanna" or
this = "Clara" or
this = "Melissa" or
this = "Amy" or
this = "Isabel" or
this = "Jemima" or
this = "Cordelia" or
this = "Melinda" or
this = "Delila" or
this = "Jeremiah" or
this = "Elijah" or
this = "Hester" or
this = "Walter" or
this = "Oliver" or
this = "Hugh" or
this = "Aaron" or
this = "Reuben" or
this = "Eli" or
this = "Amos" or
this = "Augustus" or
this = "Theodore" or
this = "Ira" or
this = "Timothy" or
this = "Cyrus" or
this = "Horace" or
this = "Simon" or
this = "Asa" or
this = "Frank" or
this = "Nelson" or
this = "Leonard" or
this = "Harrison" or
this = "Anthony" or
this = "Louis" or
this = "Milton" or
this = "Noah" or
this = "Cornelius" or
this = "Abdul" or
this = "Warren" or
this = "Harvey" or
this = "Dennis" or
this = "Wesley" or
this = "Sylvester" or
this = "Gilbert" or
this = "Sullivan" or
this = "Edmund" or
this = "Wilson" or
this = "Perry" or
this = "Matthew" or
this = "Simba" or
this = "Nala" or
this = "Rafiki" or
this = "Shenzi" or
this = "Ernest" or
this = "Gertrude" or
this = "Oscar" or
this = "Lilian" or
this = "Raymond" or
this = "Elgar" or
this = "Elmer" or
this = "Herbert" or
this = "Maude" or
this = "Mae" or
this = "Otto" or
this = "Edwin" or
this = "Ophelia" or
this = "Parsley" or
this = "Sage" or
this = "Rosemary" or
this = "Thyme" or
this = "Garfunkel" or
this = "King Basil" or
this = "Stephen"
this =
[
"Ronil", "Dina", "Ravi", "Bruce", "Jo", "Aida", "Esme", "Charlie", "Fred", "Meera", "Maya",
"Chad", "Tiana", "Laura", "George", "Will", "Mary", "Almira", "Susannah", "Rhoda",
"Cynthia", "Eunice", "Olive", "Virginia", "Angeline", "Helen", "Cornelia", "Harriet",
"Mahala", "Abby", "Margaret", "Deb", "Minerva", "Severus", "Lavina", "Adeline", "Cath",
"Elisa", "Lucretia", "Anne", "Eleanor", "Joanna", "Adam", "Agnes", "Rosanna", "Clara",
"Melissa", "Amy", "Isabel", "Jemima", "Cordelia", "Melinda", "Delila", "Jeremiah", "Elijah",
"Hester", "Walter", "Oliver", "Hugh", "Aaron", "Reuben", "Eli", "Amos", "Augustus",
"Theodore", "Ira", "Timothy", "Cyrus", "Horace", "Simon", "Asa", "Frank", "Nelson",
"Leonard", "Harrison", "Anthony", "Louis", "Milton", "Noah", "Cornelius", "Abdul", "Warren",
"Harvey", "Dennis", "Wesley", "Sylvester", "Gilbert", "Sullivan", "Edmund", "Wilson",
"Perry", "Matthew", "Simba", "Nala", "Rafiki", "Shenzi", "Ernest", "Gertrude", "Oscar",
"Lilian", "Raymond", "Elgar", "Elmer", "Herbert", "Maude", "Mae", "Otto", "Edwin",
"Ophelia", "Parsley", "Sage", "Rosemary", "Thyme", "Garfunkel", "King Basil", "Stephen"
]
}
/** Gets the hair color of the person. If the person is bald, there is no result. */
@@ -936,25 +836,12 @@ class Person extends string {
/** Holds if the person is deceased. */
predicate isDeceased() {
this = "Ernest" or
this = "Gertrude" or
this = "Oscar" or
this = "Lilian" or
this = "Edwin" or
this = "Raymond" or
this = "Elgar" or
this = "Elmer" or
this = "Herbert" or
this = "Maude" or
this = "Mae" or
this = "Otto" or
this = "Ophelia" or
this = "Parsley" or
this = "Sage" or
this = "Rosemary" or
this = "Thyme" or
this = "Garfunkel" or
this = "King Basil"
this =
[
"Ernest", "Gertrude", "Oscar", "Lilian", "Edwin", "Raymond", "Elgar", "Elmer", "Herbert",
"Maude", "Mae", "Otto", "Ophelia", "Parsley", "Sage", "Rosemary", "Thyme", "Garfunkel",
"King Basil"
]
}
/** Gets a parent of the person (alive or deceased). */
@@ -1195,12 +1082,7 @@ class Person extends string {
}
/** Holds if the person is allowed in the region. Initially, all villagers are allowed in every region. */
predicate isAllowedIn(string region) {
region = "north" or
region = "south" or
region = "east" or
region = "west"
}
predicate isAllowedIn(string region) { region = ["north", "south", "east", "west"] }
}
/** Returns a parent of the person. */

View File

@@ -0,0 +1,837 @@
/*
* This dbscheme is auto-generated by 'semmle/dbscheme_gen.py'.
* WARNING: Any modifications to this file will be lost.
* Relations can be changed by modifying master.py or
* by adding rules to dbscheme.template
*/
/*
* External artifacts
*/
externalDefects(
unique int id : @externalDefect,
varchar(900) queryPath : string ref,
int location : @location ref,
varchar(900) message : string ref,
float severity : float ref
);
externalMetrics(
unique int id : @externalMetric,
varchar(900) queryPath : string ref,
int location : @location ref,
float value : float ref
);
externalData(
int id : @externalDataElement,
varchar(900) queryPath : string ref,
int column: int ref,
varchar(900) data : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
/*
* Duplicate code
*/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/*
* Line metrics
*/
py_codelines(int id : @py_scope ref,
int count : int ref);
py_commentlines(int id : @py_scope ref,
int count : int ref);
py_docstringlines(int id : @py_scope ref,
int count : int ref);
py_alllines(int id : @py_scope ref,
int count : int ref);
/*
* Version history
*/
svnentries(
int id : @svnentry,
varchar(500) revision : string ref,
varchar(500) author : string ref,
date revisionDate : date ref,
int changeSize : int ref
)
svnaffectedfiles(
int id : @svnentry ref,
int file : @file ref,
varchar(500) action : string ref
)
svnentrymsg(
int id : @svnentry ref,
varchar(500) message : string ref
)
svnchurn(
int commit : @svnentry ref,
int file : @file ref,
int churnedLines : int ref
)
/****************************
Python dbscheme
****************************/
/*
fromSource(0) = unknown,
fromSource(1) = from source,
fromSource(2) = from library
*/
files(unique int id: @file,
varchar(900) name: string ref,
varchar(900) simple: string ref,
varchar(900) ext: string ref,
int fromSource: int ref);
folders(unique int id: @folder,
varchar(900) name: string ref,
varchar(900) simple: string ref);
@container = @folder | @file;
containerparent(int parent: @container ref,
unique int child: @container ref);
@sourceline = @file | @py_Module;
numlines(int element_id: @sourceline ref,
int num_lines: int ref,
int num_code: int ref,
int num_comment: int ref
);
@location = @location_ast | @location_default ;
locations_default(unique int id: @location_default,
int file: @file ref,
int beginLine: int ref,
int beginColumn: int ref,
int endLine: int ref,
int endColumn: int ref);
locations_ast(unique int id: @location_ast,
int module: @py_Module ref,
int beginLine: int ref,
int beginColumn: int ref,
int endLine: int ref,
int endColumn: int ref);
py_module_path(int module: @py_Module ref, int file: @file ref);
variable(unique int id : @py_variable,
int scope : @py_scope ref,
varchar(1) name : string ref);
py_line_lengths(unique int id : @py_line,
int file: @py_Module ref,
int line : int ref,
int length : int ref);
/* AUTO GENERATED PART STARTS HERE */
/* <Field> Assert.location = 0, location */
/* <Field> Assert.test = 1, expr */
/* <Field> Assert.msg = 2, expr */
/* <Field> Assign.location = 0, location */
/* <Field> Assign.value = 1, expr */
/* <Field> Assign.targets = 2, expr_list */
/* <Field> Attribute.location = 0, location */
/* <Field> Attribute.value = 1, expr */
/* <Field> Attribute.attr = 2, str */
/* <Field> Attribute.ctx = 3, expr_context */
/* <Field> AugAssign.location = 0, location */
/* <Field> AugAssign.operation = 1, BinOp */
/* <Field> BinaryExpr.location = 0, location */
/* <Field> BinaryExpr.left = 1, expr */
/* <Field> BinaryExpr.op = 2, operator */
/* <Field> BinaryExpr.right = 3, expr */
/* <Parent> BinaryExpr = AugAssign */
/* <Field> BoolExpr.location = 0, location */
/* <Field> BoolExpr.op = 1, boolop */
/* <Field> BoolExpr.values = 2, expr_list */
/* <Field> Break.location = 0, location */
/* <Field> Bytes.location = 0, location */
/* <Field> Bytes.s = 1, bytes */
/* <Field> Call.location = 0, location */
/* <Field> Call.func = 1, expr */
/* <Field> Call.args = 2, expr_list */
/* <Field> Call.keywords = 3, keyword_list */
/* <Field> Call.starargs = 4, expr */
/* <Field> Call.kwargs = 5, expr */
/* <Field> Class.name = 0, str */
/* <Field> Class.body = 1, stmt_list */
/* <Parent> Class = ClassExpr */
/* <Field> ClassExpr.location = 0, location */
/* <Field> ClassExpr.name = 1, str */
/* <Field> ClassExpr.bases = 2, expr_list */
/* <Field> ClassExpr.keywords = 3, keyword_list */
/* <Field> ClassExpr.starargs = 4, expr */
/* <Field> ClassExpr.kwargs = 5, expr */
/* <Field> ClassExpr.inner_scope = 6, Class */
/* <Field> Compare.location = 0, location */
/* <Field> Compare.left = 1, expr */
/* <Field> Compare.ops = 2, cmpop_list */
/* <Field> Compare.comparators = 3, expr_list */
/* <Field> Continue.location = 0, location */
/* <Field> Delete.location = 0, location */
/* <Field> Delete.targets = 1, expr_list */
/* <Field> Dict.location = 0, location */
/* <Field> Dict.keys = 1, expr_list */
/* <Field> Dict.values = 2, expr_list */
/* <Field> DictComp.location = 0, location */
/* <Field> DictComp.function = 1, Function */
/* <Field> DictComp.iterable = 2, expr */
/* <Field> Ellipsis.location = 0, location */
/* <Field> ExceptStmt.location = 0, location */
/* <Field> ExceptStmt.type = 1, expr */
/* <Field> ExceptStmt.name = 2, expr */
/* <Field> ExceptStmt.body = 3, stmt_list */
/* <Field> Exec.location = 0, location */
/* <Field> Exec.body = 1, expr */
/* <Field> Exec.globals = 2, expr */
/* <Field> Exec.locals = 3, expr */
/* <Field> ExprStmt.location = 0, location */
/* <Field> ExprStmt.value = 1, expr */
/* <Field> For.location = 0, location */
/* <Field> For.target = 1, expr */
/* <Field> For.iter = 2, expr */
/* <Field> For.body = 3, stmt_list */
/* <Field> For.orelse = 4, stmt_list */
/* <Field> Function.name = 0, str */
/* <Field> Function.args = 1, parameter_list */
/* <Field> Function.vararg = 2, expr */
/* <Field> Function.kwonlyargs = 3, str_list */
/* <Field> Function.kwarg = 4, expr */
/* <Field> Function.body = 5, stmt_list */
/* <Parent> Function = FunctionParent */
/* <Field> FunctionExpr.location = 0, location */
/* <Field> FunctionExpr.name = 1, str */
/* <Field> FunctionExpr.args = 2, arguments */
/* <Field> FunctionExpr.returns = 3, expr */
/* <Field> FunctionExpr.inner_scope = 4, Function */
/* <Field> GeneratorExp.location = 0, location */
/* <Field> GeneratorExp.function = 1, Function */
/* <Field> GeneratorExp.iterable = 2, expr */
/* <Field> Global.location = 0, location */
/* <Field> Global.names = 1, str_list */
/* <Field> If.location = 0, location */
/* <Field> If.test = 1, expr */
/* <Field> If.body = 2, stmt_list */
/* <Field> If.orelse = 3, stmt_list */
/* <Field> IfExp.location = 0, location */
/* <Field> IfExp.test = 1, expr */
/* <Field> IfExp.body = 2, expr */
/* <Field> IfExp.orelse = 3, expr */
/* <Field> Import.location = 0, location */
/* <Field> Import.names = 1, alias_list */
/* <Field> ImportExpr.location = 0, location */
/* <Field> ImportExpr.level = 1, int */
/* <Field> ImportExpr.name = 2, str */
/* <Field> ImportExpr.top = 3, bool */
/* <Field> ImportStar.location = 0, location */
/* <Field> ImportStar.module = 1, expr */
/* <Field> ImportMember.location = 0, location */
/* <Field> ImportMember.module = 1, expr */
/* <Field> ImportMember.name = 2, str */
/* <Field> Lambda.location = 0, location */
/* <Field> Lambda.args = 1, arguments */
/* <Field> Lambda.inner_scope = 2, Function */
/* <Field> List.location = 0, location */
/* <Field> List.elts = 1, expr_list */
/* <Field> List.ctx = 2, expr_context */
/* <Field> ListComp.location = 0, location */
/* <Field> ListComp.function = 1, Function */
/* <Field> ListComp.iterable = 2, expr */
/* <Field> ListComp.generators = 3, comprehension_list */
/* <Field> ListComp.elt = 4, expr */
/* <Field> Module.name = 0, str */
/* <Field> Module.hash = 1, str */
/* <Field> Module.body = 2, stmt_list */
/* <Field> Module.kind = 3, str */
/* <Field> Name.location = 0, location */
/* <Field> Name.variable = 1, variable */
/* <Field> Name.ctx = 2, expr_context */
/* <Parent> Name = ParameterList */
/* <Field> Nonlocal.location = 0, location */
/* <Field> Nonlocal.names = 1, str_list */
/* <Field> Num.location = 0, location */
/* <Field> Num.n = 1, number */
/* <Field> Num.text = 2, number */
/* <Field> Pass.location = 0, location */
/* <Field> Print.location = 0, location */
/* <Field> Print.dest = 1, expr */
/* <Field> Print.values = 2, expr_list */
/* <Field> Print.nl = 3, bool */
/* <Field> Raise.location = 0, location */
/* <Field> Raise.exc = 1, expr */
/* <Field> Raise.cause = 2, expr */
/* <Field> Raise.type = 3, expr */
/* <Field> Raise.inst = 4, expr */
/* <Field> Raise.tback = 5, expr */
/* <Field> Repr.location = 0, location */
/* <Field> Repr.value = 1, expr */
/* <Field> Return.location = 0, location */
/* <Field> Return.value = 1, expr */
/* <Field> Set.location = 0, location */
/* <Field> Set.elts = 1, expr_list */
/* <Field> SetComp.location = 0, location */
/* <Field> SetComp.function = 1, Function */
/* <Field> SetComp.iterable = 2, expr */
/* <Field> Slice.location = 0, location */
/* <Field> Slice.start = 1, expr */
/* <Field> Slice.stop = 2, expr */
/* <Field> Slice.step = 3, expr */
/* <Field> Starred.location = 0, location */
/* <Field> Starred.value = 1, expr */
/* <Field> Starred.ctx = 2, expr_context */
/* <Field> Str.location = 0, location */
/* <Field> Str.s = 1, str */
/* <Field> Subscript.location = 0, location */
/* <Field> Subscript.value = 1, expr */
/* <Field> Subscript.index = 2, expr */
/* <Field> Subscript.ctx = 3, expr_context */
/* <Field> Try.location = 0, location */
/* <Field> Try.body = 1, stmt_list */
/* <Field> Try.orelse = 2, stmt_list */
/* <Field> Try.handlers = 3, stmt_list */
/* <Field> Try.finalbody = 4, stmt_list */
/* <Field> Tuple.location = 0, location */
/* <Field> Tuple.elts = 1, expr_list */
/* <Field> Tuple.ctx = 2, expr_context */
/* <Parent> Tuple = ParameterList */
/* <Field> UnaryExpr.location = 0, location */
/* <Field> UnaryExpr.op = 1, unaryop */
/* <Field> UnaryExpr.operand = 2, expr */
/* <Field> While.location = 0, location */
/* <Field> While.test = 1, expr */
/* <Field> While.body = 2, stmt_list */
/* <Field> While.orelse = 3, stmt_list */
/* <Field> With.location = 0, location */
/* <Field> With.context_expr = 1, expr */
/* <Field> With.optional_vars = 2, expr */
/* <Field> With.body = 3, stmt_list */
/* <Field> Yield.location = 0, location */
/* <Field> Yield.value = 1, expr */
/* <Field> YieldFrom.location = 0, location */
/* <Field> YieldFrom.value = 1, expr */
/* <Field> Alias.value = 0, expr */
/* <Field> Alias.asname = 1, expr */
/* <Parent> Alias = AliasList */
/* <Parent> AliasList = Import */
/* <Field> Arguments.kw_defaults = 0, expr_list */
/* <Field> Arguments.defaults = 1, expr_list */
/* <Field> Arguments.annotations = 2, expr_list */
/* <Field> Arguments.varargannotation = 3, expr */
/* <Field> Arguments.kwargannotation = 4, expr */
/* <Parent> Arguments = ArgumentsParent */
/* <Parent> boolean = BoolParent */
/* <Parent> Boolop = BoolExpr */
/* <Parent> string = Bytes */
/* <Parent> Cmpop = CmpopList */
/* <Parent> CmpopList = Compare */
/* <Field> Comprehension.iter = 0, expr */
/* <Field> Comprehension.target = 1, expr */
/* <Field> Comprehension.ifs = 2, expr_list */
/* <Parent> Comprehension = ComprehensionList */
/* <Parent> ComprehensionList = ListComp */
/* <Field> Expr.location = 0, location */
/* <Parent> Expr = ExprParent */
/* <Parent> ExprContext = ExprContextParent */
/* <Parent> ExprList = ExprListParent */
/* <Parent> int = ImportExpr */
/* <Field> Keyword.arg = 0, str */
/* <Field> Keyword.value = 1, expr */
/* <Parent> Keyword = KeywordList */
/* <Parent> KeywordList = KeywordListParent */
/* <Parent> Location = ExprOrStmt */
/* <Parent> string = Num */
/* <Parent> Operator = BinaryExpr */
/* <Parent> ParameterList = Function */
/* <Field> Stmt.location = 0, location */
/* <Parent> Stmt = StmtList */
/* <Parent> StmtList = StmtListParent */
/* <Parent> string = StrParent */
/* <Parent> StringList = StrListParent */
/* <Parent> Unaryop = UnaryExpr */
/* <Parent> Variable = Name */
py_Classes(unique int id : @py_Class,
unique int parent : @py_ClassExpr ref);
py_Functions(unique int id : @py_Function,
int parent : @py_Function_parent ref,
int idx : int ref);
py_Modules(unique int id : @py_Module);
py_aliases(unique int id : @py_alias,
int parent : @py_alias_list ref,
int idx : int ref);
py_alias_lists(unique int id : @py_alias_list,
unique int parent : @py_Import ref);
py_arguments(unique int id : @py_arguments,
int parent : @py_arguments_parent ref,
int idx : int ref);
py_bools(boolean id : boolean ref,
unique int parent : @py_bool_parent ref);
py_boolops(unique int id : @py_boolop,
int kind: int ref,
unique int parent : @py_BoolExpr ref);
py_bytes(varchar(1) id : string ref,
unique int parent : @py_Bytes ref);
py_cmpops(unique int id : @py_cmpop,
int kind: int ref,
int parent : @py_cmpop_list ref,
int idx : int ref);
py_cmpop_lists(unique int id : @py_cmpop_list,
unique int parent : @py_Compare ref);
py_comprehensions(unique int id : @py_comprehension,
int parent : @py_comprehension_list ref,
int idx : int ref);
py_comprehension_lists(unique int id : @py_comprehension_list,
unique int parent : @py_ListComp ref);
py_exprs(unique int id : @py_expr,
int kind: int ref,
int parent : @py_expr_parent ref,
int idx : int ref);
py_expr_contexts(unique int id : @py_expr_context,
int kind: int ref,
int parent : @py_expr_context_parent ref,
int idx : int ref);
py_expr_lists(unique int id : @py_expr_list,
int parent : @py_expr_list_parent ref,
int idx : int ref);
py_ints(int id : int ref,
unique int parent : @py_ImportExpr ref);
py_keywords(unique int id : @py_keyword,
int parent : @py_keyword_list ref,
int idx : int ref);
py_keyword_lists(unique int id : @py_keyword_list,
unique int parent : @py_keyword_list_parent ref);
py_locations(unique int id : @location ref,
unique int parent : @py_expr_or_stmt ref);
py_numbers(varchar(1) id : string ref,
int parent : @py_Num ref,
int idx : int ref);
py_operators(unique int id : @py_operator,
int kind: int ref,
unique int parent : @py_BinaryExpr ref);
py_parameter_lists(unique int id : @py_parameter_list,
unique int parent : @py_Function ref);
py_stmts(unique int id : @py_stmt,
int kind: int ref,
int parent : @py_stmt_list ref,
int idx : int ref);
py_stmt_lists(unique int id : @py_stmt_list,
int parent : @py_stmt_list_parent ref,
int idx : int ref);
py_strs(varchar(1) id : string ref,
int parent : @py_str_parent ref,
int idx : int ref);
py_str_lists(unique int id : @py_str_list,
int parent : @py_str_list_parent ref,
int idx : int ref);
py_unaryops(unique int id : @py_unaryop,
int kind: int ref,
unique int parent : @py_UnaryExpr ref);
py_variables(int id : @py_variable ref,
unique int parent : @py_Name ref);
@py_Function_parent = @py_DictComp | @py_FunctionExpr | @py_GeneratorExp | @py_Lambda | @py_ListComp | @py_SetComp;
@py_arguments_parent = @py_FunctionExpr | @py_Lambda;
@py_ast_node = @py_Class | @py_Function | @py_Module | @py_expr | @py_stmt;
@py_bool_parent = @py_ImportExpr | @py_Print;
case @py_boolop.kind of
0 = @py_And
| 1 = @py_Or;
case @py_cmpop.kind of
0 = @py_Eq
| 1 = @py_Gt
| 2 = @py_GtE
| 3 = @py_In
| 4 = @py_Is
| 5 = @py_IsNot
| 6 = @py_Lt
| 7 = @py_LtE
| 8 = @py_NotEq
| 9 = @py_NotIn;
case @py_expr.kind of
0 = @py_Attribute
| 1 = @py_BinaryExpr
| 2 = @py_BoolExpr
| 3 = @py_Bytes
| 4 = @py_Call
| 5 = @py_ClassExpr
| 6 = @py_Compare
| 7 = @py_Dict
| 8 = @py_DictComp
| 9 = @py_Ellipsis
| 10 = @py_FunctionExpr
| 11 = @py_GeneratorExp
| 12 = @py_IfExp
| 13 = @py_ImportExpr
| 14 = @py_ImportMember
| 15 = @py_Lambda
| 16 = @py_List
| 17 = @py_ListComp
| 18 = @py_Name
| 19 = @py_Num
| 20 = @py_Repr
| 21 = @py_Set
| 22 = @py_SetComp
| 23 = @py_Slice
| 24 = @py_Starred
| 25 = @py_Str
| 26 = @py_Subscript
| 27 = @py_Tuple
| 28 = @py_UnaryExpr
| 29 = @py_Yield
| 30 = @py_YieldFrom;
case @py_expr_context.kind of
0 = @py_AugLoad
| 1 = @py_AugStore
| 2 = @py_Del
| 3 = @py_Load
| 4 = @py_Param
| 5 = @py_Store;
@py_expr_context_parent = @py_Attribute | @py_List | @py_Name | @py_Starred | @py_Subscript | @py_Tuple;
@py_expr_list_parent = @py_Assign | @py_BoolExpr | @py_Call | @py_ClassExpr | @py_Compare | @py_Delete | @py_Dict | @py_List | @py_Print | @py_Set | @py_Tuple | @py_arguments | @py_comprehension;
@py_expr_or_stmt = @py_expr | @py_stmt;
@py_expr_parent = @py_Assert | @py_Assign | @py_Attribute | @py_AugAssign | @py_BinaryExpr | @py_Call | @py_ClassExpr | @py_Compare | @py_DictComp | @py_ExceptStmt | @py_Exec | @py_Expr_stmt | @py_For | @py_Function | @py_FunctionExpr | @py_GeneratorExp | @py_If | @py_IfExp | @py_ImportMember | @py_ImportStar | @py_ListComp | @py_Print | @py_Raise | @py_Repr | @py_Return | @py_SetComp | @py_Slice | @py_Starred | @py_Subscript | @py_UnaryExpr | @py_While | @py_With | @py_Yield | @py_YieldFrom | @py_alias | @py_arguments | @py_comprehension | @py_expr_list | @py_keyword | @py_parameter_list;
@py_keyword_list_parent = @py_Call | @py_ClassExpr;
case @py_operator.kind of
0 = @py_Add
| 1 = @py_BitAnd
| 2 = @py_BitOr
| 3 = @py_BitXor
| 4 = @py_Div
| 5 = @py_FloorDiv
| 6 = @py_LShift
| 7 = @py_Mod
| 8 = @py_Mult
| 9 = @py_Pow
| 10 = @py_RShift
| 11 = @py_Sub;
@py_parameter = @py_Name | @py_Tuple;
@py_scope = @py_Class | @py_Function | @py_Module;
case @py_stmt.kind of
0 = @py_Assert
| 1 = @py_Assign
| 2 = @py_AugAssign
| 3 = @py_Break
| 4 = @py_Continue
| 5 = @py_Delete
| 6 = @py_ExceptStmt
| 7 = @py_Exec
| 8 = @py_Expr_stmt
| 9 = @py_For
| 10 = @py_Global
| 11 = @py_If
| 12 = @py_Import
| 13 = @py_ImportStar
| 14 = @py_Nonlocal
| 15 = @py_Pass
| 16 = @py_Print
| 17 = @py_Raise
| 18 = @py_Return
| 19 = @py_Try
| 20 = @py_While
| 21 = @py_With;
@py_stmt_list_parent = @py_Class | @py_ExceptStmt | @py_For | @py_Function | @py_If | @py_Module | @py_Try | @py_While | @py_With;
@py_str_list_parent = @py_Function | @py_Global | @py_Nonlocal;
@py_str_parent = @py_Attribute | @py_Class | @py_ClassExpr | @py_Function | @py_FunctionExpr | @py_ImportExpr | @py_ImportMember | @py_Module | @py_Str | @py_keyword | @py_str_list;
case @py_unaryop.kind of
0 = @py_Invert
| 1 = @py_Not
| 2 = @py_UAdd
| 3 = @py_USub;
/*
* End of auto-generated part
*/
/* Map relative names to absolute names for imports */
py_absolute_names(int module : @py_Module ref,
varchar(1) relname : string ref,
varchar(1) absname : string ref);
py_exports(int id : @py_Module ref,
varchar(1) name : string ref);
/* Successor information */
py_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_true_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_exception_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_false_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_flow_bb_node(unique int flownode : @py_flow_node,
int realnode : @py_ast_node ref,
int basicblock : @py_flow_node ref,
int index : int ref);
py_scope_flow(int flow : @py_flow_node ref,
int scope : @py_scope ref,
int kind : int ref);
py_idoms(unique int node : @py_flow_node ref,
int immediate_dominator : @py_flow_node ref);
py_ssa_phi(int phi : @py_ssa_var ref,
int arg: @py_ssa_var ref);
py_ssa_var(unique int id : @py_ssa_var,
int var : @py_variable ref);
py_ssa_use(int node: @py_flow_node ref,
int var : @py_ssa_var ref);
py_ssa_defn(unique int id : @py_ssa_var ref,
int node: @py_flow_node ref);
@py_base_var = @py_variable | @py_ssa_var;
py_scopes(unique int node : @py_expr_or_stmt ref,
int scope : @py_scope ref);
py_scope_location(unique int id : @location ref,
unique int scope : @py_scope ref);
py_flags(unique varchar(1) name : string ref,
varchar(1) value : string ref);
py_syntax_error(unique int id : @location ref,
varchar(1) message : string ref);
py_comments(unique int id : @py_comment,
varchar(1) text : string ref,
unique int location : @location ref);
/* Type information support */
py_cobjects(unique int obj : @py_cobject,
int typeof : @py_cobject ref);
py_cmembers(int object : @py_cobject ref,
varchar(1) name : string ref,
int member : @py_cobject ref);
py_citems(int object : @py_cobject ref,
int index : int ref,
int member : @py_cobject ref);
py_cobjectnames(unique int obj : @py_cobject ref,
varchar(1) name : string ref);
py_special_objects(unique int obj : @py_cobject ref,
unique varchar(1) name : string ref);
py_decorated_object(int object : @py_object ref,
int level: int ref);
@py_object = @py_cobject | @py_flow_node;
@py_source_element = @py_ast_node | @container;
/* XML Files */
xmlEncoding (unique int id: @file ref, varchar(900) encoding: string ref);
xmlDTDs (unique int id: @xmldtd,
varchar(900) root: string ref,
varchar(900) publicId: string ref,
varchar(900) systemId: string ref,
int fileid: @file ref);
xmlElements (unique int id: @xmlelement,
varchar(900) name: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int fileid: @file ref);
xmlAttrs (unique int id: @xmlattribute,
int elementid: @xmlelement ref,
varchar(900) name: string ref,
varchar(3600) value: string ref,
int idx: int ref,
int fileid: @file ref);
xmlNs (int id: @xmlnamespace,
varchar(900) prefixName: string ref,
varchar(900) URI: string ref,
int fileid: @file ref);
xmlHasNs (int elementId: @xmlnamespaceable ref,
int nsId: @xmlnamespace ref,
int fileid: @file ref);
xmlComments (unique int id: @xmlcomment,
varchar(3600) text: string ref,
int parentid: @xmlparent ref,
int fileid: @file ref);
xmlChars (unique int id: @xmlcharacters,
varchar(3600) text: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int isCDATA: int ref,
int fileid: @file ref);
@xmlparent = @file | @xmlelement;
@xmlnamespaceable = @xmlelement | @xmlattribute;
xmllocations(int xmlElement: @xmllocatable ref,
int location: @location_default ref);
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;

View File

@@ -1,3 +1,15 @@
## 0.0.9
### Bug Fixes
* The [View AST functionality](https://codeql.github.com/docs/codeql-for-visual-studio-code/exploring-the-structure-of-your-source-code/) no longer prints detailed information about regular expressions, greatly improving performance.
## 0.0.8
### Major Analysis Improvements
* User names and other account information is no longer considered to be sensitive data for the queries `py/clear-text-logging-sensitive-data` and `py/clear-text-storage-sensitive-data`, since this lead to many false positives.
## 0.0.7
## 0.0.6

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