Merge branch 'main' into js-insecure-http-parser

This commit is contained in:
Nate Johnson
2023-04-18 00:45:32 -04:00
895 changed files with 135227 additions and 114780 deletions

View File

@@ -2069,6 +2069,7 @@ public class Parser {
pi.value = this.parseMethod(pi.isGenerator, pi.isAsync);
} else if (this.options.ecmaVersion() >= 5
&& !pi.computed
&& !pi.isPattern
&& pi.key instanceof Identifier
&& (((Identifier) pi.key).getName().equals("get")
|| ((Identifier) pi.key).getName().equals("set"))

View File

@@ -1239,16 +1239,15 @@ protected DependencyInstallationResult preparePackagesAndDependencies(Set<Path>
String msg = "A parse error occurred: " + StringUtil.quoteWithBackticks(err.getMessage().trim())
+ ". Check the syntax of the file. If the file is invalid, correct the error or [exclude](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/customizing-code-scanning) the file from analysis.";
// file, relative to the source root
String relativeFilePath = null;
DiagnosticLocation.Builder builder = DiagnosticLocation.builder();
if (file.startsWith(LGTM_SRC)) {
relativeFilePath = file.subpath(LGTM_SRC.getNameCount(), file.getNameCount()).toString();
builder = builder.setFile(file.subpath(LGTM_SRC.getNameCount(), file.getNameCount()).toString());
}
DiagnosticLocation diagLoc = DiagnosticLocation.builder()
.setFile(relativeFilePath)
DiagnosticLocation diagLoc = builder
.setStartLine(err.getPosition().getLine())
.setStartColumn(err.getPosition().getColumn())
.setStartColumn(err.getPosition().getColumn() + 1) // convert from 0-based to 1-based
.setEndLine(err.getPosition().getLine())
.setEndColumn(err.getPosition().getColumn())
.setEndColumn(err.getPosition().getColumn() + 1) // convert from 0-based to 1-based
.build();
writeDiagnostics(msg, JSDiagnosticKind.PARSE_ERROR, diagLoc);
}

View File

@@ -0,0 +1,4 @@
var { get, set } = x;
var { get = 1 } = x;
var { set = 1 } = x;
var { get = 1, set = 1 } = x;

View File

@@ -0,0 +1,528 @@
#10000=@"/patterns.js;sourcefile"
files(#10000,"/patterns.js")
#10001=@"/;folder"
folders(#10001,"/")
containerparent(#10001,#10000)
#10002=@"loc,{#10000},0,0,0,0"
locations_default(#10002,#10000,0,0,0,0)
hasLocation(#10000,#10002)
#20000=@"global_scope"
scopes(#20000,0)
#20001=@"script;{#10000},1,1"
#20002=*
lines(#20002,#20001,"var { get, set } = x;","
")
#20003=@"loc,{#10000},1,1,1,21"
locations_default(#20003,#10000,1,1,1,21)
hasLocation(#20002,#20003)
#20004=*
lines(#20004,#20001,"var { get = 1 } = x;","
")
#20005=@"loc,{#10000},2,1,2,20"
locations_default(#20005,#10000,2,1,2,20)
hasLocation(#20004,#20005)
#20006=*
lines(#20006,#20001,"var { set = 1 } = x;","
")
#20007=@"loc,{#10000},3,1,3,20"
locations_default(#20007,#10000,3,1,3,20)
hasLocation(#20006,#20007)
#20008=*
lines(#20008,#20001,"var { get = 1, set = 1 } = x;","
")
#20009=@"loc,{#10000},4,1,4,29"
locations_default(#20009,#10000,4,1,4,29)
hasLocation(#20008,#20009)
numlines(#20001,4,4,0)
#20010=*
tokeninfo(#20010,7,#20001,0,"var")
#20011=@"loc,{#10000},1,1,1,3"
locations_default(#20011,#10000,1,1,1,3)
hasLocation(#20010,#20011)
#20012=*
tokeninfo(#20012,8,#20001,1,"{")
#20013=@"loc,{#10000},1,5,1,5"
locations_default(#20013,#10000,1,5,1,5)
hasLocation(#20012,#20013)
#20014=*
tokeninfo(#20014,6,#20001,2,"get")
#20015=@"loc,{#10000},1,7,1,9"
locations_default(#20015,#10000,1,7,1,9)
hasLocation(#20014,#20015)
#20016=*
tokeninfo(#20016,8,#20001,3,",")
#20017=@"loc,{#10000},1,10,1,10"
locations_default(#20017,#10000,1,10,1,10)
hasLocation(#20016,#20017)
#20018=*
tokeninfo(#20018,6,#20001,4,"set")
#20019=@"loc,{#10000},1,12,1,14"
locations_default(#20019,#10000,1,12,1,14)
hasLocation(#20018,#20019)
#20020=*
tokeninfo(#20020,8,#20001,5,"}")
#20021=@"loc,{#10000},1,16,1,16"
locations_default(#20021,#10000,1,16,1,16)
hasLocation(#20020,#20021)
#20022=*
tokeninfo(#20022,8,#20001,6,"=")
#20023=@"loc,{#10000},1,18,1,18"
locations_default(#20023,#10000,1,18,1,18)
hasLocation(#20022,#20023)
#20024=*
tokeninfo(#20024,6,#20001,7,"x")
#20025=@"loc,{#10000},1,20,1,20"
locations_default(#20025,#10000,1,20,1,20)
hasLocation(#20024,#20025)
#20026=*
tokeninfo(#20026,8,#20001,8,";")
#20027=@"loc,{#10000},1,21,1,21"
locations_default(#20027,#10000,1,21,1,21)
hasLocation(#20026,#20027)
#20028=*
tokeninfo(#20028,7,#20001,9,"var")
#20029=@"loc,{#10000},2,1,2,3"
locations_default(#20029,#10000,2,1,2,3)
hasLocation(#20028,#20029)
#20030=*
tokeninfo(#20030,8,#20001,10,"{")
#20031=@"loc,{#10000},2,5,2,5"
locations_default(#20031,#10000,2,5,2,5)
hasLocation(#20030,#20031)
#20032=*
tokeninfo(#20032,6,#20001,11,"get")
#20033=@"loc,{#10000},2,7,2,9"
locations_default(#20033,#10000,2,7,2,9)
hasLocation(#20032,#20033)
#20034=*
tokeninfo(#20034,8,#20001,12,"=")
#20035=@"loc,{#10000},2,11,2,11"
locations_default(#20035,#10000,2,11,2,11)
hasLocation(#20034,#20035)
#20036=*
tokeninfo(#20036,3,#20001,13,"1")
#20037=@"loc,{#10000},2,13,2,13"
locations_default(#20037,#10000,2,13,2,13)
hasLocation(#20036,#20037)
#20038=*
tokeninfo(#20038,8,#20001,14,"}")
#20039=@"loc,{#10000},2,15,2,15"
locations_default(#20039,#10000,2,15,2,15)
hasLocation(#20038,#20039)
#20040=*
tokeninfo(#20040,8,#20001,15,"=")
#20041=@"loc,{#10000},2,17,2,17"
locations_default(#20041,#10000,2,17,2,17)
hasLocation(#20040,#20041)
#20042=*
tokeninfo(#20042,6,#20001,16,"x")
#20043=@"loc,{#10000},2,19,2,19"
locations_default(#20043,#10000,2,19,2,19)
hasLocation(#20042,#20043)
#20044=*
tokeninfo(#20044,8,#20001,17,";")
#20045=@"loc,{#10000},2,20,2,20"
locations_default(#20045,#10000,2,20,2,20)
hasLocation(#20044,#20045)
#20046=*
tokeninfo(#20046,7,#20001,18,"var")
#20047=@"loc,{#10000},3,1,3,3"
locations_default(#20047,#10000,3,1,3,3)
hasLocation(#20046,#20047)
#20048=*
tokeninfo(#20048,8,#20001,19,"{")
#20049=@"loc,{#10000},3,5,3,5"
locations_default(#20049,#10000,3,5,3,5)
hasLocation(#20048,#20049)
#20050=*
tokeninfo(#20050,6,#20001,20,"set")
#20051=@"loc,{#10000},3,7,3,9"
locations_default(#20051,#10000,3,7,3,9)
hasLocation(#20050,#20051)
#20052=*
tokeninfo(#20052,8,#20001,21,"=")
#20053=@"loc,{#10000},3,11,3,11"
locations_default(#20053,#10000,3,11,3,11)
hasLocation(#20052,#20053)
#20054=*
tokeninfo(#20054,3,#20001,22,"1")
#20055=@"loc,{#10000},3,13,3,13"
locations_default(#20055,#10000,3,13,3,13)
hasLocation(#20054,#20055)
#20056=*
tokeninfo(#20056,8,#20001,23,"}")
#20057=@"loc,{#10000},3,15,3,15"
locations_default(#20057,#10000,3,15,3,15)
hasLocation(#20056,#20057)
#20058=*
tokeninfo(#20058,8,#20001,24,"=")
#20059=@"loc,{#10000},3,17,3,17"
locations_default(#20059,#10000,3,17,3,17)
hasLocation(#20058,#20059)
#20060=*
tokeninfo(#20060,6,#20001,25,"x")
#20061=@"loc,{#10000},3,19,3,19"
locations_default(#20061,#10000,3,19,3,19)
hasLocation(#20060,#20061)
#20062=*
tokeninfo(#20062,8,#20001,26,";")
#20063=@"loc,{#10000},3,20,3,20"
locations_default(#20063,#10000,3,20,3,20)
hasLocation(#20062,#20063)
#20064=*
tokeninfo(#20064,7,#20001,27,"var")
#20065=@"loc,{#10000},4,1,4,3"
locations_default(#20065,#10000,4,1,4,3)
hasLocation(#20064,#20065)
#20066=*
tokeninfo(#20066,8,#20001,28,"{")
#20067=@"loc,{#10000},4,5,4,5"
locations_default(#20067,#10000,4,5,4,5)
hasLocation(#20066,#20067)
#20068=*
tokeninfo(#20068,6,#20001,29,"get")
#20069=@"loc,{#10000},4,7,4,9"
locations_default(#20069,#10000,4,7,4,9)
hasLocation(#20068,#20069)
#20070=*
tokeninfo(#20070,8,#20001,30,"=")
#20071=@"loc,{#10000},4,11,4,11"
locations_default(#20071,#10000,4,11,4,11)
hasLocation(#20070,#20071)
#20072=*
tokeninfo(#20072,3,#20001,31,"1")
#20073=@"loc,{#10000},4,13,4,13"
locations_default(#20073,#10000,4,13,4,13)
hasLocation(#20072,#20073)
#20074=*
tokeninfo(#20074,8,#20001,32,",")
#20075=@"loc,{#10000},4,14,4,14"
locations_default(#20075,#10000,4,14,4,14)
hasLocation(#20074,#20075)
#20076=*
tokeninfo(#20076,6,#20001,33,"set")
#20077=@"loc,{#10000},4,16,4,18"
locations_default(#20077,#10000,4,16,4,18)
hasLocation(#20076,#20077)
#20078=*
tokeninfo(#20078,8,#20001,34,"=")
#20079=@"loc,{#10000},4,20,4,20"
locations_default(#20079,#10000,4,20,4,20)
hasLocation(#20078,#20079)
#20080=*
tokeninfo(#20080,3,#20001,35,"1")
#20081=@"loc,{#10000},4,22,4,22"
locations_default(#20081,#10000,4,22,4,22)
hasLocation(#20080,#20081)
#20082=*
tokeninfo(#20082,8,#20001,36,"}")
#20083=@"loc,{#10000},4,24,4,24"
locations_default(#20083,#10000,4,24,4,24)
hasLocation(#20082,#20083)
#20084=*
tokeninfo(#20084,8,#20001,37,"=")
#20085=@"loc,{#10000},4,26,4,26"
locations_default(#20085,#10000,4,26,4,26)
hasLocation(#20084,#20085)
#20086=*
tokeninfo(#20086,6,#20001,38,"x")
#20087=@"loc,{#10000},4,28,4,28"
locations_default(#20087,#10000,4,28,4,28)
hasLocation(#20086,#20087)
#20088=*
tokeninfo(#20088,8,#20001,39,";")
#20089=@"loc,{#10000},4,29,4,29"
locations_default(#20089,#10000,4,29,4,29)
hasLocation(#20088,#20089)
#20090=*
tokeninfo(#20090,0,#20001,40,"")
#20091=@"loc,{#10000},5,1,5,0"
locations_default(#20091,#10000,5,1,5,0)
hasLocation(#20090,#20091)
toplevels(#20001,0)
#20092=@"loc,{#10000},1,1,5,0"
locations_default(#20092,#10000,1,1,5,0)
hasLocation(#20001,#20092)
#20093=@"var;{get};{#20000}"
variables(#20093,"get",#20000)
#20094=@"var;{set};{#20000}"
variables(#20094,"set",#20000)
#20095=*
stmts(#20095,18,#20001,0,"var { g ... } = x;")
hasLocation(#20095,#20003)
stmt_containers(#20095,#20001)
#20096=*
exprs(#20096,64,#20095,0,"{ get, set } = x")
#20097=@"loc,{#10000},1,5,1,20"
locations_default(#20097,#10000,1,5,1,20)
hasLocation(#20096,#20097)
enclosing_stmt(#20096,#20095)
expr_containers(#20096,#20001)
#20098=*
exprs(#20098,68,#20096,0,"{ get, set }")
#20099=@"loc,{#10000},1,5,1,16"
locations_default(#20099,#10000,1,5,1,16)
hasLocation(#20098,#20099)
enclosing_stmt(#20098,#20095)
expr_containers(#20098,#20001)
#20100=*
properties(#20100,#20098,0,0,"get")
hasLocation(#20100,#20015)
#20101=*
exprs(#20101,0,#20100,0,"get")
hasLocation(#20101,#20015)
enclosing_stmt(#20101,#20095)
expr_containers(#20101,#20001)
literals("get","get",#20101)
#20102=*
exprs(#20102,78,#20100,1,"get")
hasLocation(#20102,#20015)
enclosing_stmt(#20102,#20095)
expr_containers(#20102,#20001)
literals("get","get",#20102)
decl(#20102,#20093)
#20103=*
properties(#20103,#20098,1,0,"set")
hasLocation(#20103,#20019)
#20104=*
exprs(#20104,0,#20103,0,"set")
hasLocation(#20104,#20019)
enclosing_stmt(#20104,#20095)
expr_containers(#20104,#20001)
literals("set","set",#20104)
#20105=*
exprs(#20105,78,#20103,1,"set")
hasLocation(#20105,#20019)
enclosing_stmt(#20105,#20095)
expr_containers(#20105,#20001)
literals("set","set",#20105)
decl(#20105,#20094)
#20106=*
exprs(#20106,79,#20096,1,"x")
hasLocation(#20106,#20025)
enclosing_stmt(#20106,#20095)
expr_containers(#20106,#20001)
literals("x","x",#20106)
#20107=@"var;{x};{#20000}"
variables(#20107,"x",#20000)
bind(#20106,#20107)
#20108=*
stmts(#20108,18,#20001,1,"var { get = 1 } = x;")
hasLocation(#20108,#20005)
stmt_containers(#20108,#20001)
#20109=*
exprs(#20109,64,#20108,0,"{ get = 1 } = x")
#20110=@"loc,{#10000},2,5,2,19"
locations_default(#20110,#10000,2,5,2,19)
hasLocation(#20109,#20110)
enclosing_stmt(#20109,#20108)
expr_containers(#20109,#20001)
#20111=*
exprs(#20111,68,#20109,0,"{ get = 1 }")
#20112=@"loc,{#10000},2,5,2,15"
locations_default(#20112,#10000,2,5,2,15)
hasLocation(#20111,#20112)
enclosing_stmt(#20111,#20108)
expr_containers(#20111,#20001)
#20113=*
properties(#20113,#20111,0,0,"get = 1")
#20114=@"loc,{#10000},2,7,2,13"
locations_default(#20114,#10000,2,7,2,13)
hasLocation(#20113,#20114)
#20115=*
exprs(#20115,0,#20113,0,"get")
hasLocation(#20115,#20033)
enclosing_stmt(#20115,#20108)
expr_containers(#20115,#20001)
literals("get","get",#20115)
#20116=*
exprs(#20116,78,#20113,1,"get")
hasLocation(#20116,#20033)
enclosing_stmt(#20116,#20108)
expr_containers(#20116,#20001)
literals("get","get",#20116)
decl(#20116,#20093)
#20117=*
exprs(#20117,3,#20113,2,"1")
hasLocation(#20117,#20037)
enclosing_stmt(#20117,#20108)
expr_containers(#20117,#20001)
literals("1","1",#20117)
#20118=*
exprs(#20118,79,#20109,1,"x")
hasLocation(#20118,#20043)
enclosing_stmt(#20118,#20108)
expr_containers(#20118,#20001)
literals("x","x",#20118)
bind(#20118,#20107)
#20119=*
stmts(#20119,18,#20001,2,"var { set = 1 } = x;")
hasLocation(#20119,#20007)
stmt_containers(#20119,#20001)
#20120=*
exprs(#20120,64,#20119,0,"{ set = 1 } = x")
#20121=@"loc,{#10000},3,5,3,19"
locations_default(#20121,#10000,3,5,3,19)
hasLocation(#20120,#20121)
enclosing_stmt(#20120,#20119)
expr_containers(#20120,#20001)
#20122=*
exprs(#20122,68,#20120,0,"{ set = 1 }")
#20123=@"loc,{#10000},3,5,3,15"
locations_default(#20123,#10000,3,5,3,15)
hasLocation(#20122,#20123)
enclosing_stmt(#20122,#20119)
expr_containers(#20122,#20001)
#20124=*
properties(#20124,#20122,0,0,"set = 1")
#20125=@"loc,{#10000},3,7,3,13"
locations_default(#20125,#10000,3,7,3,13)
hasLocation(#20124,#20125)
#20126=*
exprs(#20126,0,#20124,0,"set")
hasLocation(#20126,#20051)
enclosing_stmt(#20126,#20119)
expr_containers(#20126,#20001)
literals("set","set",#20126)
#20127=*
exprs(#20127,78,#20124,1,"set")
hasLocation(#20127,#20051)
enclosing_stmt(#20127,#20119)
expr_containers(#20127,#20001)
literals("set","set",#20127)
decl(#20127,#20094)
#20128=*
exprs(#20128,3,#20124,2,"1")
hasLocation(#20128,#20055)
enclosing_stmt(#20128,#20119)
expr_containers(#20128,#20001)
literals("1","1",#20128)
#20129=*
exprs(#20129,79,#20120,1,"x")
hasLocation(#20129,#20061)
enclosing_stmt(#20129,#20119)
expr_containers(#20129,#20001)
literals("x","x",#20129)
bind(#20129,#20107)
#20130=*
stmts(#20130,18,#20001,3,"var { g ... } = x;")
hasLocation(#20130,#20009)
stmt_containers(#20130,#20001)
#20131=*
exprs(#20131,64,#20130,0,"{ get = ... 1 } = x")
#20132=@"loc,{#10000},4,5,4,28"
locations_default(#20132,#10000,4,5,4,28)
hasLocation(#20131,#20132)
enclosing_stmt(#20131,#20130)
expr_containers(#20131,#20001)
#20133=*
exprs(#20133,68,#20131,0,"{ get = 1, set = 1 }")
#20134=@"loc,{#10000},4,5,4,24"
locations_default(#20134,#10000,4,5,4,24)
hasLocation(#20133,#20134)
enclosing_stmt(#20133,#20130)
expr_containers(#20133,#20001)
#20135=*
properties(#20135,#20133,0,0,"get = 1")
#20136=@"loc,{#10000},4,7,4,13"
locations_default(#20136,#10000,4,7,4,13)
hasLocation(#20135,#20136)
#20137=*
exprs(#20137,0,#20135,0,"get")
hasLocation(#20137,#20069)
enclosing_stmt(#20137,#20130)
expr_containers(#20137,#20001)
literals("get","get",#20137)
#20138=*
exprs(#20138,78,#20135,1,"get")
hasLocation(#20138,#20069)
enclosing_stmt(#20138,#20130)
expr_containers(#20138,#20001)
literals("get","get",#20138)
decl(#20138,#20093)
#20139=*
exprs(#20139,3,#20135,2,"1")
hasLocation(#20139,#20073)
enclosing_stmt(#20139,#20130)
expr_containers(#20139,#20001)
literals("1","1",#20139)
#20140=*
properties(#20140,#20133,1,0,"set = 1")
#20141=@"loc,{#10000},4,16,4,22"
locations_default(#20141,#10000,4,16,4,22)
hasLocation(#20140,#20141)
#20142=*
exprs(#20142,0,#20140,0,"set")
hasLocation(#20142,#20077)
enclosing_stmt(#20142,#20130)
expr_containers(#20142,#20001)
literals("set","set",#20142)
#20143=*
exprs(#20143,78,#20140,1,"set")
hasLocation(#20143,#20077)
enclosing_stmt(#20143,#20130)
expr_containers(#20143,#20001)
literals("set","set",#20143)
decl(#20143,#20094)
#20144=*
exprs(#20144,3,#20140,2,"1")
hasLocation(#20144,#20081)
enclosing_stmt(#20144,#20130)
expr_containers(#20144,#20001)
literals("1","1",#20144)
#20145=*
exprs(#20145,79,#20131,1,"x")
hasLocation(#20145,#20087)
enclosing_stmt(#20145,#20130)
expr_containers(#20145,#20001)
literals("x","x",#20145)
bind(#20145,#20107)
#20146=*
entry_cfg_node(#20146,#20001)
#20147=@"loc,{#10000},1,1,1,0"
locations_default(#20147,#10000,1,1,1,0)
hasLocation(#20146,#20147)
#20148=*
exit_cfg_node(#20148,#20001)
hasLocation(#20148,#20091)
successor(#20130,#20145)
successor(#20133,#20137)
successor(#20144,#20140)
successor(#20143,#20144)
successor(#20142,#20143)
successor(#20140,#20131)
successor(#20139,#20135)
successor(#20138,#20139)
successor(#20137,#20138)
successor(#20135,#20142)
successor(#20145,#20133)
successor(#20131,#20148)
successor(#20119,#20129)
successor(#20122,#20126)
successor(#20128,#20124)
successor(#20127,#20128)
successor(#20126,#20127)
successor(#20124,#20120)
successor(#20129,#20122)
successor(#20120,#20130)
successor(#20108,#20118)
successor(#20111,#20115)
successor(#20117,#20113)
successor(#20116,#20117)
successor(#20115,#20116)
successor(#20113,#20109)
successor(#20118,#20111)
successor(#20109,#20119)
successor(#20095,#20106)
successor(#20098,#20101)
successor(#20105,#20103)
successor(#20104,#20105)
successor(#20103,#20096)
successor(#20102,#20100)
successor(#20101,#20102)
successor(#20100,#20104)
successor(#20106,#20098)
successor(#20096,#20108)
successor(#20146,#20095)
numlines(#10000,4,4,0)
filetype(#10000,"javascript")

View File

@@ -1,9 +1,9 @@
{
"location": {
"endColumn": 4,
"endColumn": 5,
"endLine": 1,
"file": "bad.js",
"startColumn": 4,
"startColumn": 5,
"startLine": 1
},
"markdownMessage": "A parse error occurred: `Unexpected token`. Check the syntax of the file. If the file is invalid, correct the error or [exclude](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/customizing-code-scanning) the file from analysis.",

View File

@@ -1,3 +1,7 @@
## 0.5.2
No user-facing changes.
## 0.5.1
### Minor Analysis Improvements

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* `router.push` and `router.replace` in `Next.js` are now considered as XSS sink.

View File

@@ -0,0 +1,3 @@
## 0.5.2
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.1
lastReleaseVersion: 0.5.2

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-all
version: 0.5.2-dev
version: 0.6.0-dev
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript

View File

@@ -347,6 +347,46 @@ module API {
result = this.getASuccessor(Label::promisedError())
}
/**
* Gets a node representing a function that is a wrapper around the function represented by this node.
*
* Concretely, a function that forwards all its parameters to a call to `f` and returns the result of that call
* is considered a wrapper around `f`.
*
* Examples:
* ```js
* function f(x) {
* return g(x); // f = g.getForwardingFunction()
* }
*
* function doExec(x) {
* console.log(x);
* return exec(x); // doExec = exec.getForwardingFunction()
* }
*
* function doEither(x, y) {
* if (x > y) {
* return foo(x, y); // doEither = foo.getForwardingFunction()
* } else {
* return bar(x, y); // doEither = bar.getForwardingFunction()
* }
* }
*
* function wrapWithLogging(f) {
* return (x) => {
* console.log(x);
* return f(x); // f.getForwardingFunction() = anonymous arrow function
* }
* }
* wrapWithLogging(g); // g.getForwardingFunction() = wrapWithLogging(g)
* ```
*/
cached
Node getForwardingFunction() {
Stages::ApiStage::ref() and
result = this.getASuccessor(Label::forwardingFunction())
}
/**
* Gets any class that has this value as a decorator.
*
@@ -901,6 +941,9 @@ module API {
or
lbl = Label::return() and
ref = pred.getAnInvocation()
or
lbl = Label::forwardingFunction() and
DataFlow::functionForwardingStep(pred.getALocalUse(), ref)
)
or
exists(DataFlow::Node def, DataFlow::FunctionNode fn |
@@ -1431,6 +1474,9 @@ module API {
/** Gets the `return` edge label. */
LabelReturn return() { any() }
/** Gets the label representing a function wrapper that forwards to an underlying function. */
LabelForwardingFunction forwardingFunction() { any() }
/** Gets the `promised` edge label connecting a promise to its contained value. */
LabelPromised promised() { any() }
@@ -1483,6 +1529,7 @@ module API {
MkLabelDecoratedClass() or
MkLabelDecoratedMember() or
MkLabelDecoratedParameter() or
MkLabelForwardingFunction() or
MkLabelEntryPoint(API::EntryPoint e)
/** A label for an entry-point. */
@@ -1566,6 +1613,11 @@ module API {
override string toString() { result = "getReceiver()" }
}
/** A label for a function that is a wrapper around another function. */
class LabelForwardingFunction extends ApiLabel, MkLabelForwardingFunction {
override string toString() { result = "getForwardingFunction()" }
}
/** A label for a class decorated by the current value. */
class LabelDecoratedClass extends ApiLabel, MkLabelDecoratedClass {
override string toString() { result = "getADecoratedClass()" }

View File

@@ -157,10 +157,12 @@ private class FunctionalExtendCallShallow extends ExtendCall {
}
/**
* A taint propagating data flow edge from the objects flowing into an extend call to its return value
* A value-preserving data flow edge from the objects flowing into an extend call to its return value
* and to the source of the destination object.
*
* Since all object properties are preserved, we model this as a value-preserving step.
*/
private class ExtendCallTaintStep extends TaintTracking::SharedTaintStep {
private class ExtendCallStep extends PreCallGraphStep {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(ExtendCall extend |
pred = extend.getASourceOperand() and succ = extend.getDestinationOperand().getALocalSource()

View File

@@ -806,6 +806,10 @@ private predicate basicFlowStepNoBarrier(
callStep(pred, succ) and
summary = PathSummary::call()
or
// Implied receiver flow
CallGraph::impliedReceiverStep(pred, succ) and
summary = PathSummary::call()
or
// Flow out of function
returnStep(pred, succ) and
summary = PathSummary::return()

View File

@@ -241,22 +241,26 @@ module CallGraph {
)
}
private predicate shouldTrackObjectWithMethods(DataFlow::SourceNode node) {
private DataFlow::FunctionNode getAMethodOnPlainObject(DataFlow::SourceNode node) {
(
(
node instanceof DataFlow::ObjectLiteralNode
or
node instanceof DataFlow::FunctionNode
) and
node.getAPropertySource() instanceof DataFlow::FunctionNode
result = node.getAPropertySource()
or
exists(node.(DataFlow::ObjectLiteralNode).getPropertyGetter(_))
result = node.(DataFlow::ObjectLiteralNode).getPropertyGetter(_)
or
exists(node.(DataFlow::ObjectLiteralNode).getPropertySetter(_))
result = node.(DataFlow::ObjectLiteralNode).getPropertySetter(_)
) and
not node.getTopLevel().isExterns()
}
private predicate shouldTrackObjectWithMethods(DataFlow::SourceNode node) {
exists(getAMethodOnPlainObject(node))
}
/**
* Gets a step summary for tracking object literals.
*
@@ -273,4 +277,22 @@ module CallGraph {
or
StepSummary::step(getAnAllocationSiteRef(node), result, objectWithMethodsStep())
}
/**
* Holds if `pred` is assumed to flow to `succ` because a method is stored on an object that is assumed
* to be the receiver of calls to that method.
*
* For example, object literal below is assumed to flow to the receiver of the `foo` function:
* ```js
* let obj = {};
* obj.foo = function() {}
* ```
*/
cached
predicate impliedReceiverStep(DataFlow::SourceNode pred, DataFlow::SourceNode succ) {
exists(DataFlow::SourceNode host |
pred = getAnAllocationSiteRef(host) and
succ = getAMethodOnPlainObject(host).getReceiver()
)
}
}

View File

@@ -94,6 +94,10 @@ private module Cached {
DataFlow::localFieldStep(pred, succ) and
summary = LevelStep()
or
// Implied flow of host object into 'this' of a method
CallGraph::impliedReceiverStep(pred, succ) and
summary = CallStep()
or
exists(string prop |
basicStoreStep(pred, succ, prop) and
summary = StoreStep(prop)

View File

@@ -985,7 +985,9 @@ module Redux {
*/
private module ReactRedux {
/** Gets an API node referring to the `useSelector` function. */
API::Node useSelector() { result = API::moduleImport("react-redux").getMember("useSelector") }
API::Node useSelector() {
result = API::moduleImport("react-redux").getMember("useSelector").getForwardingFunction*()
}
/**
* A step out of a `useSelector` call, such as from `state.x` to the result of `useSelector(state => state.x)`.
@@ -994,7 +996,7 @@ module Redux {
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
exists(API::CallNode call |
call = useSelector().getACall() and
pred = call.getParameter(0).getReturn().asSink() and
pred = call.getCallback(0).getReturnNode() and
succ = call
)
}
@@ -1231,4 +1233,9 @@ module Redux {
}
}
}
/** For testing only. */
module Internal {
predicate getRootStateAccessPath = rootStateAccessPath/1;
}
}

View File

@@ -277,6 +277,7 @@ module Stages {
.getUnknownMember()
.getInstance()
.getReceiver()
.getForwardingFunction()
.getPromisedError()
.getADecoratedClass()
.getADecoratedMember()

View File

@@ -222,6 +222,8 @@ module ClientSideUrlRedirect {
HistoryWriteUrlSink() {
this = History::getBrowserHistory().getMember(["push", "replace"]).getACall().getArgument(0)
}
override predicate isXssSink() { any() }
}
/**
@@ -231,6 +233,8 @@ module ClientSideUrlRedirect {
NextRoutePushUrlSink() {
this = NextJS::nextRouter().getAMemberCall(["push", "replace"]).getArgument(0)
}
override predicate isXssSink() { any() }
}
private class SinkFromModel extends Sink {

View File

@@ -55,6 +55,22 @@ class Configuration extends TaintTracking::Configuration {
)
}
override predicate isSanitizerEdge(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel lbl
) {
// Suppress the value-preserving step src -> dst in `extend(dst, src)`. This is modeled as a value-preserving
// step because it preserves all properties, but the destination is not actually Object.prototype.
exists(ExtendCall call |
pred = call.getASourceOperand() and
(
succ = call.getDestinationOperand().getALocalSource()
or
succ = call
) and
lbl instanceof ObjectPrototype
)
}
override predicate isAdditionalFlowStep(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel inlbl, DataFlow::FlowLabel outlbl
) {

View File

@@ -31,6 +31,13 @@ module UnsafeJQueryPlugin {
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* The receiver of a function, seen as a sanitizer.
*
* Plugins often do `$(this)` to coerce an existing DOM element to a jQuery object.
*/
private class ThisSanitizer extends Sanitizer instanceof DataFlow::ThisNode { }
/**
* An argument that may act as an HTML fragment rather than a CSS selector, as a sink for remote unsafe jQuery plugins.
*/

View File

@@ -1,3 +1,7 @@
## 0.5.6
No user-facing changes.
## 0.5.5
### Minor Analysis Improvements

View File

@@ -37,7 +37,7 @@
the hash of a password.
</p>
<sample src="examples/InsufficientPasswordHash_NodeJS.js"/>
<sample src="examples/InsufficientPasswordHash.js"/>
<p>
This is not secure, since the password can be efficiently
@@ -46,7 +46,7 @@
algorithm:
</p>
<sample src="examples/InsufficientPasswordHash_NodeJS_fixed.js"/>
<sample src="examples/InsufficientPasswordHash_fixed.js"/>
</example>
<references>

View File

@@ -1,8 +0,0 @@
const crypto = require('crypto-js')
function hashPassword(email, password) {
var algo = crypto.algo.SHA512.create()
algo.update(password, 'utf-8') // BAD
algo.update(email.toLowerCase(), 'utf-8')
var hash = algo.finalize()
return hash.toString(crypto.enc.Base64)
}

View File

@@ -1,8 +0,0 @@
const crypto = require('crypto-js')
function hashPassword(email, password) {
var algo = crypto.algo.PBKDF2.create()
algo.update(password, 'utf-8') // GOOD
algo.update(email.toLowerCase(), 'utf-8')
var hash = algo.finalize()
return hash.toString(crypto.enc.Base64)
}

View File

@@ -0,0 +1,5 @@
---
category: fix
---
* Fixed a bug where a destructuring pattern could not be parsed if it had a property
named `get` or `set` with a default value.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Improved the call graph to better handle the case where a function is stored on
a plain object and subsequently copied to a new host object via an `extend` call.

View File

@@ -0,0 +1,3 @@
## 0.5.6
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.5
lastReleaseVersion: 0.5.6

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-queries
version: 0.5.6-dev
version: 0.6.0-dev
groups:
- javascript
- queries

View File

@@ -0,0 +1,15 @@
import { useSelector } from 'react-redux';
function useSelectorWrapped(fn) {
return useSelector(fn);
}
function MyComponent(props) {
const x1 = useSelectorWrapped(state => state.x1);
const x2 = useSelectorWrapped(state => state.x2);
const x3 = useSelectorWrapped(state => state.x3);
const x4 = useSelectorWrapped(state => state.x4);
const x5 = useSelectorWrapped(state => state.x5);
return <span>X</span>;
}

View File

@@ -113,9 +113,11 @@ taintFlow
| react-redux.jsx:69:31:69:38 | source() | react-redux.jsx:76:10:76:36 | props.p ... Action3 |
| react-redux.jsx:70:30:70:37 | source() | react-redux.jsx:77:10:77:28 | props.propFromAsync |
reactComponentRef
| accessPaths.js:7:1:15:1 | functio ... pan>;\\n} | accessPaths.js:7:1:15:1 | functio ... pan>;\\n} |
| react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} | react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} |
| react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} | react-redux.jsx:94:28:94:84 | connect ... ponent) |
| react-redux.jsx:64:1:80:1 | functio ... r}}/>\\n} | react-redux.jsx:97:12:97:12 | c |
ambiguousAccessPath
getAffectedStateAccessPath
| react-redux.jsx:12:33:17:9 | (state, ... } | toolkit |
| react-redux.jsx:18:41:23:9 | (state, ... } | toolkit |
@@ -163,3 +165,24 @@ reducerToStateStep
| react-redux.jsx:35:45:35:58 | action.payload | react-redux.jsx:86:31:86:54 | state.m ... alValue |
| react-redux.jsx:39:42:39:55 | action.payload | react-redux.jsx:87:32:87:56 | state.m ... lValue2 |
| react-redux.jsx:44:27:46:14 | [1, 2, ... }) | react-redux.jsx:88:32:88:56 | state.m ... lValue3 |
getRootStateAccessPath
| manual | react-redux.jsx:86:31:86:42 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual") |
| manual | react-redux.jsx:87:32:87:43 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual") |
| manual | react-redux.jsx:88:32:88:43 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual") |
| manual.manualValue | react-redux.jsx:86:31:86:54 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual").getMember("manualValue") |
| manual.manualValue2 | react-redux.jsx:87:32:87:56 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual").getMember("manualValue2") |
| manual.manualValue3 | react-redux.jsx:88:32:88:56 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("manual").getMember("manualValue3") |
| toolkit | react-redux.jsx:84:32:84:44 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("toolkit") |
| toolkit | react-redux.jsx:85:24:85:36 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("toolkit") |
| toolkit.asyncValue | react-redux.jsx:85:24:85:47 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("toolkit").getMember("asyncValue") |
| toolkit.value | react-redux.jsx:84:32:84:50 | use entryPoint("react-redux-connect").getParameter(0).getParameter(0).getMember("toolkit").getMember("value") |
| x1 | accessPaths.js:8:16:8:52 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getForwardingFunction().getReturn() |
| x1 | accessPaths.js:8:44:8:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x1") |
| x2 | accessPaths.js:9:16:9:52 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getForwardingFunction().getReturn() |
| x2 | accessPaths.js:9:44:9:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x2") |
| x3 | accessPaths.js:10:16:10:52 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getForwardingFunction().getReturn() |
| x3 | accessPaths.js:10:44:10:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x3") |
| x4 | accessPaths.js:11:16:11:52 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getForwardingFunction().getReturn() |
| x4 | accessPaths.js:11:44:11:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x4") |
| x5 | accessPaths.js:12:16:12:52 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getForwardingFunction().getReturn() |
| x5 | accessPaths.js:12:44:12:51 | use moduleImport("react-redux").getMember("exports").getMember("useSelector").getParameter(0).getParameter(0).getMember("x5") |

View File

@@ -63,3 +63,10 @@ query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) {
query DataFlow::SourceNode reactComponentRef(ReactComponent component) {
result = component.getAComponentCreatorReference()
}
query predicate ambiguousAccessPath(API::Node node, string path) {
count(string accessPath | Redux::Internal::getRootStateAccessPath(accessPath) = node) > 1 and
Redux::Internal::getRootStateAccessPath(path) = node
}
query predicate getRootStateAccessPath = Redux::Internal::getRootStateAccessPath/1;

View File

@@ -36,6 +36,8 @@ nodes
| tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted |
| tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted |
| tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted |
| tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} |
| tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} |
| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} |
| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} |
| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted |
@@ -83,6 +85,8 @@ edges
| tst-UntrustedDataToExternalAPI.js:24:21:24:41 | JSON.pa ... rusted) | tst-UntrustedDataToExternalAPI.js:24:20:24:42 | [JSON.p ... usted)] |
| tst-UntrustedDataToExternalAPI.js:24:21:24:41 | JSON.pa ... rusted) | tst-UntrustedDataToExternalAPI.js:24:20:24:42 | [JSON.p ... usted)] |
| tst-UntrustedDataToExternalAPI.js:24:32:24:40 | untrusted | tst-UntrustedDataToExternalAPI.js:24:21:24:41 | JSON.pa ... rusted) |
| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} |
| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} |
| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} |
| tst-UntrustedDataToExternalAPI.js:42:8:42:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} |
| tst-UntrustedDataToExternalAPI.js:43:8:43:16 | untrusted | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} |
@@ -101,4 +105,5 @@ edges
| tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:30:13:30:30 | getDeepUntrusted() | Call to external-lib() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name |
| tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:33:14:33:22 | untrusted | Call to external-lib.get.[callback].[param 'res'].send() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name |
| tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:34:34:34:42 | untrusted | Call to external-lib.get.[callback].[param 'req'].app.locals.something.foo() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name |
| tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:41:7:41:8 | {} | Call to lodash.merge() [param 0] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name |
| tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | tst-UntrustedDataToExternalAPI.js:41:11:45:1 | {\\n x ... usted\\n} | Call to lodash.merge() [param 1] with untrusted data from $@. | tst-UntrustedDataToExternalAPI.js:3:17:3:27 | window.name | window.name |

View File

@@ -560,6 +560,25 @@ nodes
| react-use-context.js:16:26:16:36 | window.name |
| react-use-context.js:16:26:16:36 | window.name |
| react-use-context.js:16:26:16:36 | window.name |
| react-use-router.js:4:9:4:28 | router |
| react-use-router.js:4:18:4:28 | useRouter() |
| react-use-router.js:8:21:8:26 | router |
| react-use-router.js:8:21:8:32 | router.query |
| react-use-router.js:8:21:8:32 | router.query |
| react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:11:24:11:29 | router |
| react-use-router.js:11:24:11:35 | router.query |
| react-use-router.js:11:24:11:35 | router.query |
| react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:22:15:22:24 | router |
| react-use-router.js:22:17:22:22 | router |
| react-use-router.js:23:43:23:48 | router |
| react-use-router.js:23:43:23:54 | router.query |
| react-use-router.js:23:43:23:54 | router.query |
| react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-state.js:4:9:4:49 | state |
| react-use-state.js:4:9:4:49 | state |
| react-use-state.js:4:10:4:14 | state |
@@ -1096,6 +1115,14 @@ nodes
| tst.js:491:23:491:35 | location.hash |
| tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash |
| tst.js:494:18:494:30 | location.hash |
| tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash |
| tst.js:501:43:501:62 | window.location.hash |
| typeahead.js:20:13:20:45 | target |
| typeahead.js:20:22:20:45 | documen ... .search |
| typeahead.js:20:22:20:45 | documen ... .search |
@@ -1700,6 +1727,28 @@ edges
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
| react-use-context.js:10:22:10:32 | window.name | react-use-context.js:10:22:10:32 | window.name |
| react-use-context.js:16:26:16:36 | window.name | react-use-context.js:16:26:16:36 | window.name |
| react-use-router.js:4:9:4:28 | router | react-use-router.js:8:21:8:26 | router |
| react-use-router.js:4:9:4:28 | router | react-use-router.js:11:24:11:29 | router |
| react-use-router.js:4:18:4:28 | useRouter() | react-use-router.js:4:9:4:28 | router |
| react-use-router.js:8:21:8:26 | router | react-use-router.js:8:21:8:32 | router.query |
| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:39 | router.query.foobar | react-use-router.js:4:18:4:28 | useRouter() |
| react-use-router.js:11:24:11:29 | router | react-use-router.js:11:24:11:35 | router.query |
| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:22:15:22:24 | router | react-use-router.js:23:43:23:48 | router |
| react-use-router.js:22:17:22:22 | router | react-use-router.js:22:15:22:24 | router |
| react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query |
| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:22:17:22:22 | router |
| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state |
| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state |
| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state |
@@ -2222,6 +2271,14 @@ edges
| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target |
| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target |
| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target |
@@ -2386,6 +2443,10 @@ edges
| react-native.js:9:27:9:33 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:9:27:9:33 | tainted | Cross-site scripting vulnerability due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
| react-use-context.js:10:22:10:32 | window.name | react-use-context.js:10:22:10:32 | window.name | react-use-context.js:10:22:10:32 | window.name | Cross-site scripting vulnerability due to $@. | react-use-context.js:10:22:10:32 | window.name | user-provided value |
| react-use-context.js:16:26:16:36 | window.name | react-use-context.js:16:26:16:36 | window.name | react-use-context.js:16:26:16:36 | window.name | Cross-site scripting vulnerability due to $@. | react-use-context.js:16:26:16:36 | window.name | user-provided value |
| react-use-router.js:8:21:8:39 | router.query.foobar | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar | Cross-site scripting vulnerability due to $@. | react-use-router.js:8:21:8:32 | router.query | user-provided value |
| react-use-router.js:11:24:11:42 | router.query.foobar | react-use-router.js:8:21:8:32 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | Cross-site scripting vulnerability due to $@. | react-use-router.js:8:21:8:32 | router.query | user-provided value |
| react-use-router.js:11:24:11:42 | router.query.foobar | react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar | Cross-site scripting vulnerability due to $@. | react-use-router.js:11:24:11:35 | router.query | user-provided value |
| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar | Cross-site scripting vulnerability due to $@. | react-use-router.js:23:43:23:54 | router.query | user-provided value |
| react-use-state.js:5:51:5:55 | state | react-use-state.js:4:38:4:48 | window.name | react-use-state.js:5:51:5:55 | state | Cross-site scripting vulnerability due to $@. | react-use-state.js:4:38:4:48 | window.name | user-provided value |
| react-use-state.js:11:51:11:55 | state | react-use-state.js:10:14:10:24 | window.name | react-use-state.js:11:51:11:55 | state | Cross-site scripting vulnerability due to $@. | react-use-state.js:10:14:10:24 | window.name | user-provided value |
| react-use-state.js:17:51:17:55 | state | react-use-state.js:16:20:16:30 | window.name | react-use-state.js:17:51:17:55 | state | Cross-site scripting vulnerability due to $@. | react-use-state.js:16:20:16:30 | window.name | user-provided value |
@@ -2505,6 +2566,8 @@ edges
| tst.js:476:20:476:22 | url | tst.js:471:13:471:36 | documen ... .search | tst.js:476:20:476:22 | url | Cross-site scripting vulnerability due to $@. | tst.js:471:13:471:36 | documen ... .search | user-provided value |
| tst.js:486:22:486:24 | url | tst.js:471:13:471:36 | documen ... .search | tst.js:486:22:486:24 | url | Cross-site scripting vulnerability due to $@. | tst.js:471:13:471:36 | documen ... .search | user-provided value |
| tst.js:491:23:491:45 | locatio ... bstr(1) | tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | Cross-site scripting vulnerability due to $@. | tst.js:491:23:491:35 | location.hash | user-provided value |
| tst.js:494:18:494:40 | locatio ... bstr(1) | tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | Cross-site scripting vulnerability due to $@. | tst.js:494:18:494:30 | location.hash | user-provided value |
| tst.js:501:33:501:63 | decodeU ... n.hash) | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | Cross-site scripting vulnerability due to $@. | tst.js:501:43:501:62 | window.location.hash | user-provided value |
| typeahead.js:25:18:25:20 | val | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:25:18:25:20 | val | Cross-site scripting vulnerability due to $@. | typeahead.js:20:22:20:45 | documen ... .search | user-provided value |
| v-html.vue:2:8:2:23 | v-html=tainted | v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | Cross-site scripting vulnerability due to $@. | v-html.vue:6:42:6:58 | document.location | user-provided value |
| various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |

View File

@@ -572,6 +572,25 @@ nodes
| react-use-context.js:16:26:16:36 | window.name |
| react-use-context.js:16:26:16:36 | window.name |
| react-use-context.js:16:26:16:36 | window.name |
| react-use-router.js:4:9:4:28 | router |
| react-use-router.js:4:18:4:28 | useRouter() |
| react-use-router.js:8:21:8:26 | router |
| react-use-router.js:8:21:8:32 | router.query |
| react-use-router.js:8:21:8:32 | router.query |
| react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:11:24:11:29 | router |
| react-use-router.js:11:24:11:35 | router.query |
| react-use-router.js:11:24:11:35 | router.query |
| react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:22:15:22:24 | router |
| react-use-router.js:22:17:22:22 | router |
| react-use-router.js:23:43:23:48 | router |
| react-use-router.js:23:43:23:54 | router.query |
| react-use-router.js:23:43:23:54 | router.query |
| react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-state.js:4:9:4:49 | state |
| react-use-state.js:4:9:4:49 | state |
| react-use-state.js:4:10:4:14 | state |
@@ -1108,6 +1127,14 @@ nodes
| tst.js:491:23:491:35 | location.hash |
| tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash |
| tst.js:494:18:494:30 | location.hash |
| tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash |
| tst.js:501:43:501:62 | window.location.hash |
| typeahead.js:9:28:9:30 | loc |
| typeahead.js:9:28:9:30 | loc |
| typeahead.js:9:28:9:30 | loc |
@@ -1762,6 +1789,28 @@ edges
| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted |
| react-use-context.js:10:22:10:32 | window.name | react-use-context.js:10:22:10:32 | window.name |
| react-use-context.js:16:26:16:36 | window.name | react-use-context.js:16:26:16:36 | window.name |
| react-use-router.js:4:9:4:28 | router | react-use-router.js:8:21:8:26 | router |
| react-use-router.js:4:9:4:28 | router | react-use-router.js:11:24:11:29 | router |
| react-use-router.js:4:18:4:28 | useRouter() | react-use-router.js:4:9:4:28 | router |
| react-use-router.js:8:21:8:26 | router | react-use-router.js:8:21:8:32 | router.query |
| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:32 | router.query | react-use-router.js:8:21:8:39 | router.query.foobar |
| react-use-router.js:8:21:8:39 | router.query.foobar | react-use-router.js:4:18:4:28 | useRouter() |
| react-use-router.js:11:24:11:29 | router | react-use-router.js:11:24:11:35 | router.query |
| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:11:24:11:35 | router.query | react-use-router.js:11:24:11:42 | router.query.foobar |
| react-use-router.js:22:15:22:24 | router | react-use-router.js:23:43:23:48 | router |
| react-use-router.js:22:17:22:22 | router | react-use-router.js:22:15:22:24 | router |
| react-use-router.js:23:43:23:48 | router | react-use-router.js:23:43:23:54 | router.query |
| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:54 | router.query | react-use-router.js:23:43:23:61 | router.query.foobar |
| react-use-router.js:23:43:23:61 | router.query.foobar | react-use-router.js:22:17:22:22 | router |
| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state |
| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state |
| react-use-state.js:4:9:4:49 | state | react-use-state.js:5:51:5:55 | state |
@@ -2284,6 +2333,14 @@ edges
| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc |
| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc |
| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc |

View File

@@ -0,0 +1,25 @@
import { useRouter } from 'next/router'
export function nextRouter() {
const router = useRouter();
return (
<div>
<span onClick={() => {
router.push(router.query.foobar) // NOT OK
}}>Click to XSS 1</span>
<span onClick={() => {
router.replace(router.query.foobar) // NOT OK
}}>Click to XSS 2</span>
<span onClick={() => {
router.push('/?foobar=' + router.query.foobar) // OK
}}>Safe Link</span>
</div>
)
}
import { withRouter } from 'next/router'
function Page({ router }) {
return <span onClick={() => router.push(router.query.foobar)}>Click to XSS 3</span> // NOT OK
}
export const pageWithRouter = withRouter(Page);

View File

@@ -313,7 +313,7 @@ function basicExceptions() {
}
function handlebarsSafeString() {
return new Handlebars.SafeString(location); // NOT OK!
return new Handlebars.SafeString(location); // NOT OK!
}
function test2() {
@@ -355,15 +355,15 @@ function thisNodes() {
var target = document.location.search
this.html(target); // NOT OK. (this is a jQuery object)
this.innerHTML = target // OK. (this is a jQuery object)
this.each(function (i, e) {
this.innerHTML = target; // NOT OK. (this is a DOM-node);
this.html(target); // OK. (this is a DOM-node);
e.innerHTML = target; // NOT OK.
});
}
$.fn[pluginName] = myPlugin;
$.fn[pluginName] = myPlugin;
}
@@ -380,7 +380,7 @@ function test() {
function test() {
var target = document.location.search
$('myId').html(target); // NOT OK
$('myId').html(target.taint); // NOT OK
@@ -401,7 +401,7 @@ function test() {
if (random()) {return;}
$('myId').html(target.taint6); // OK
if (random()) {target.taint7 = "safe";}
$('myId').html(target.taint7); // NOT OK
@@ -489,4 +489,17 @@ function urlStuff() {
window.open(location.hash.substr(1)); // OK - any JavaScript is executed in another context
navigation.navigate(location.hash.substr(1)); // NOT OK
const myHistory = require('history').createBrowserHistory();
myHistory.push(location.hash.substr(1)); // NOT OK
}
function Foo() {
this.foo = document;
var obj = {
bar: function() {
this.foo.body.innerHTML = decodeURI(window.location.hash); // NOT OK
}
};
Object.assign(this, obj);
}

View File

@@ -188,8 +188,18 @@
}
// extending options
options = $.extend( {}, options );
var target = $( options.of ); // NOT OK
console.log(target);
};
$.fn.blockReceiver = function( options ) {
$.extend({
foo() {
$(this); // OK
}
},
options,
);
};
});

View File

@@ -103,11 +103,23 @@ app.get('/bar', (req, res) => {
let object = {};
object[taint][taint] = taint; // NOT OK
const bad = ["__proto__", "constructor"];
if (bad.includes(taint)) {
return;
}
object[taint][taint] = taint; // OK
});
});
app.get('/assign', (req, res) => {
let taint = String(req.query.data);
let plainObj = {};
let object = Object.assign({}, plainObj[taint]);
object[taint] = taint; // OK - 'object' is not Object.prototype itself (but possibly a copy)
let dest = {};
Object.assign(dest, plainObj[taint]);
dest[taint] = taint; // OK - 'dest' is not Object.prototype itself (but possibly a copy)
});