Skip to content

Commit 6b5b28a

Browse files
committed
Python: Add Value.getABooleanValue and Value.getDefiniteBooleanValue
Replacing `Value.booleanValue`. We wanted to match `Object.booleanValue` that only gives a result if it is either `true` or `false`, but also wanted to keep the flexibility to see if the Value _could_ be `true`/`false`. We don't have a motivating usecase, so let's see if we ever need it :P + fix modernisation regression on py/jinja2/autoescape-false
1 parent bd1f21f commit 6b5b28a

5 files changed

Lines changed: 16 additions & 6 deletions

File tree

python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ where
4343
not exists(getAutoEscapeParameter(call))
4444
or
4545
exists(Value isFalse |
46-
getAutoEscapeParameter(call).pointsTo(isFalse) and isFalse.booleanValue() = false
46+
getAutoEscapeParameter(call).pointsTo(isFalse) and
47+
isFalse.getDefiniteBooleanValue() = false
4748
)
4849
)
4950
select call, "Using jinja2 templates with autoescape=False can potentially allow XSS attacks."

python/ql/src/Security/CWE-215/FlaskDebug.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ from CallNode call, Value isTrue
1717
where
1818
call = theFlaskClass().declaredAttribute("run").(FunctionValue).getACall() and
1919
call.getArgByName("debug").pointsTo(isTrue) and
20-
isTrue.booleanValue() = true
20+
isTrue.getDefiniteBooleanValue() = true
2121
select call,
2222
"A Flask app appears to be run in debug mode. This may allow an attacker to run arbitrary code through the debugger."

python/ql/src/Security/CWE-295/RequestWithoutValidation.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import semmle.python.web.Http
1515
FunctionValue requestFunction() { result = Module::named("requests").attr(httpVerbLower()) }
1616

1717
/** requests treats None as the default and all other "falsey" values as False */
18-
predicate falseNotNone(Value v) { v.booleanValue() = false and not v = Value::none_() }
18+
predicate falseNotNone(Value v) { v.getDefiniteBooleanValue() = false and not v = Value::none_() }
1919

2020
from CallNode call, FunctionValue func, Value falsey, ControlFlowNode origin
2121
where

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,20 @@ class Value extends TObject {
118118
)
119119
}
120120

121-
/** Gets the boolean value of this value. */
122-
boolean booleanValue() {
121+
/** Gets the boolean interpretation of this value.
122+
* Could be both `true` and `false`, if we can't determine the result more precisely.
123+
*/
124+
boolean getABooleanValue() {
123125
result = this.(ObjectInternal).booleanValue()
124126
}
127+
128+
/** Gets the boolean interpretation of this value, only if we can determine the result preciely.
129+
* The result can be `none()`, but never both `true` and `false`.
130+
*/
131+
boolean getDefiniteBooleanValue() {
132+
result = getABooleanValue() and
133+
not (getABooleanValue() = true and getABooleanValue() = false)
134+
}
125135
}
126136

127137
/** Class representing modules in the Python program

python/ql/test/query-tests/Security/CWE-079/Jinja2WithoutEscaping.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@
22
| jinja2_escaping.py:41:5:41:29 | ControlFlowNode for Environment() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. |
33
| jinja2_escaping.py:43:1:43:3 | ControlFlowNode for E() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. |
44
| jinja2_escaping.py:44:1:44:15 | ControlFlowNode for E() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. |
5-
| jinja2_escaping.py:46:1:46:17 | ControlFlowNode for E() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. |
65
| jinja2_escaping.py:53:15:53:43 | ControlFlowNode for Template() | Using jinja2 templates with autoescape=False can potentially allow XSS attacks. |

0 commit comments

Comments
 (0)