Skip to content

Commit b9703b7

Browse files
author
Max Schaefer
authored
Merge pull request #1452 from markshannon/merge-121
Merge rc/1.21 into master.
2 parents 8354f81 + 77030c4 commit b9703b7

File tree

23 files changed

+274
-142
lines changed

23 files changed

+274
-142
lines changed

javascript/ql/src/semmle/javascript/dataflow/internal/AccessPaths.qll

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@ private newtype PropertyName =
2828
}
2929

3030
/**
31-
* Gets the representation of the property name of `pacc`, if any.
31+
* Gets an access to property `name` of access path `base` in basic block `bb`.
3232
*/
33-
private PropertyName getPropertyName(PropAccess pacc) {
34-
result = StaticPropertyName(pacc.getPropertyName())
35-
or
36-
exists(SsaVariable var |
37-
pacc.getPropertyNameExpr() = var.getAUse() and
38-
result = DynamicPropertyName(var)
33+
private PropAccess namedPropAccess(AccessPath base, PropertyName name, BasicBlock bb) {
34+
result.getBase() = base.getAnInstanceIn(bb) and
35+
(
36+
name = StaticPropertyName(result.getPropertyName())
37+
or
38+
exists(SsaVariable var |
39+
result.getPropertyNameExpr() = var.getAUse() and
40+
name = DynamicPropertyName(var)
41+
)
3942
)
4043
}
4144

@@ -76,10 +79,7 @@ private newtype TAccessPath =
7679
* A property access on an access path.
7780
*/
7881
MkAccessStep(AccessPath base, PropertyName name) {
79-
exists(PropAccess pacc |
80-
pacc.getBase() = base.getAnInstance() and
81-
getPropertyName(pacc) = name
82-
)
82+
exists(namedPropAccess(base, name, _))
8383
}
8484

8585
/**
@@ -108,24 +108,9 @@ class AccessPath extends TAccessPath {
108108
this_.getBasicBlock() = bb
109109
)
110110
or
111-
exists(PropertyName name |
112-
result = getABaseInstanceIn(bb, name) and
113-
getPropertyName(result) = name
114-
)
115-
}
116-
117-
/**
118-
* Gets a property access in `bb` whose base is represented by the
119-
* base of this access path, and where `name` is bound to the last
120-
* component of this access path.
121-
*
122-
* This is an auxiliary predicate that's needed to enforce a better
123-
* join order in `getAnInstanceIn` above.
124-
*/
125-
pragma[noinline]
126-
private PropAccess getABaseInstanceIn(BasicBlock bb, PropertyName name) {
127-
exists(AccessPath base | this = MkAccessStep(base, name) |
128-
result.getBase() = base.getAnInstanceIn(bb)
111+
exists(AccessPath base, PropertyName name |
112+
this = MkAccessStep(base, name) and
113+
result = namedPropAccess(base, name, bb)
129114
)
130115
}
131116

javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -271,16 +271,19 @@ module ReflectedXss {
271271
* a content type that does not (case-insensitively) contain the string "html". This
272272
* is to prevent us from flagging plain-text or JSON responses as vulnerable.
273273
*/
274-
private class HttpResponseSink extends Sink {
275-
HttpResponseSink() {
276-
exists(HTTP::ResponseSendArgument sendarg | sendarg = asExpr() |
277-
forall(HTTP::HeaderDefinition hd |
278-
hd = sendarg.getRouteHandler().getAResponseHeader("content-type")
279-
|
280-
exists(string tp | hd.defines("content-type", tp) | tp.toLowerCase().matches("%html%"))
281-
)
282-
)
283-
}
274+
private class HttpResponseSink extends Sink, DataFlow::ValueNode {
275+
override HTTP::ResponseSendArgument astNode;
276+
277+
HttpResponseSink() { not nonHtmlContentType(astNode.getRouteHandler()) }
278+
}
279+
280+
/**
281+
* Holds if `h` may send a response with a content type other than HTML.
282+
*/
283+
private predicate nonHtmlContentType(HTTP::RouteHandler h) {
284+
exists(HTTP::HeaderDefinition hd | hd = h.getAResponseHeader("content-type") |
285+
not exists(string tp | hd.defines("content-type", tp) | tp.regexpMatch("(?i).*html.*"))
286+
)
284287
}
285288

286289
/**

python/ql/src/semmle/python/objects/Callables.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,10 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
270270
}
271271

272272
override predicate neverReturns() {
273-
this = Module::named("sys").attr("exit")
273+
exists(ModuleObjectInternal sys |
274+
sys.getName() = "sys" and
275+
sys.attribute("exit", this, _)
276+
)
274277
}
275278

276279
override predicate functionAndOffset(CallableObjectInternal function, int offset) {

python/ql/src/semmle/python/objects/Classes.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ private import semmle.python.types.Builtins
1111
/** Class representing classes */
1212
abstract class ClassObjectInternal extends ObjectInternal {
1313

14-
string getName() {
14+
override string getName() {
1515
result = this.getClassDeclaration().getName()
1616
}
1717

python/ql/src/semmle/python/objects/Constants.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ abstract class ConstantObjectInternal extends ObjectInternal {
6767
this = instance
6868
}
6969

70+
override string getName() { none() }
71+
7072
}
7173

7274
private abstract class BooleanObjectInternal extends ConstantObjectInternal {

python/ql/src/semmle/python/objects/Descriptors.qll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ private import semmle.python.types.Builtins
1111
class PropertyInternal extends ObjectInternal, TProperty {
1212

1313
/** Gets the name of this property */
14-
string getName() {
14+
override string getName() {
1515
result = this.getGetter().getName()
1616
}
1717

@@ -172,6 +172,10 @@ class ClassMethodObjectInternal extends ObjectInternal, TClassMethod {
172172

173173
override int length() { none() }
174174

175+
override string getName() {
176+
result = this.getFunction().getName()
177+
}
178+
175179
}
176180

177181
class StaticMethodObjectInternal extends ObjectInternal, TStaticMethod {
@@ -239,4 +243,8 @@ class StaticMethodObjectInternal extends ObjectInternal, TStaticMethod {
239243

240244
override int length() { none() }
241245

246+
override string getName() {
247+
result = this.getFunction().getName()
248+
}
249+
242250
}

python/ql/src/semmle/python/objects/Instances.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ abstract class InstanceObject extends ObjectInternal {
4949
/** Holds if `init` in the context `callee` is the initializer of this instance */
5050
abstract predicate initializer(PythonFunctionObjectInternal init, Context callee);
5151

52+
override string getName() { none() }
53+
5254
}
5355

5456
private predicate self_variable_reaching_init_exit(EssaVariable self) {
@@ -362,6 +364,8 @@ class UnknownInstanceInternal extends TUnknownInstance, ObjectInternal {
362364
result = lengthFromClass(this.getClass())
363365
}
364366

367+
override string getName() { none() }
368+
365369
}
366370

367371
private int lengthFromClass(ClassObjectInternal cls) {
@@ -461,5 +465,7 @@ class SuperInstance extends TSuperInstance, ObjectInternal {
461465
none()
462466
}
463467

468+
override string getName() { none() }
469+
464470
}
465471

python/ql/src/semmle/python/objects/Modules.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ private import semmle.python.types.Builtins
1010
/** A class representing modules */
1111
abstract class ModuleObjectInternal extends ObjectInternal {
1212

13-
/** Gets the name of this module */
14-
abstract string getName();
15-
1613
/** Gets the source scope of this module, if it has one. */
1714
abstract Module getSourceModule();
1815

@@ -408,5 +405,8 @@ class AbsentModuleAttributeObjectInternal extends ObjectInternal, TAbsentModuleA
408405
any()
409406
}
410407

408+
/* We know what this is called, but not its innate name */
409+
override string getName() { none() }
410+
411411
}
412412

0 commit comments

Comments
 (0)