Python: urlsplit sanitizer handles `in [KNOWN_VALUE]`

This commit is contained in:
Rasmus Wriedt Larsen 2020-02-21 16:03:29 +01:00
Родитель 798db91f71
Коммит bfa7553095
3 изменённых файлов: 23 добавлений и 6 удалений

Просмотреть файл

@ -230,6 +230,8 @@ class UrlsplitUrlparseTempSanitizer extends Sanitizer {
private predicate clears_taint(ControlFlowNode final_test, ControlFlowNode tainted, ControlFlowNode test, boolean sense) {
test_equality_with_const(final_test, tainted, sense)
or
test_in_const_seq(final_test, tainted, sense)
or
test.(UnaryExprNode).getNode().getOp() instanceof Not and
exists(ControlFlowNode nested_test |
nested_test = test.(UnaryExprNode).getOperand() and
@ -238,19 +240,34 @@ class UrlsplitUrlparseTempSanitizer extends Sanitizer {
}
/** holds for `== "KNOWN_VALUE"` on `true` edge, and `!= "KNOWN_VALUE"` on `false` edge */
private predicate test_equality_with_const(CompareNode cmp, ControlFlowNode operand, boolean sense) {
private predicate test_equality_with_const(CompareNode cmp, ControlFlowNode tainted, boolean sense) {
exists(ControlFlowNode const, Cmpop op |
const.getNode() instanceof StrConst
|
(
cmp.operands(const, op, operand)
cmp.operands(const, op, tainted)
or
cmp.operands(operand, op, const)
) and (
cmp.operands(tainted, op, const)
) and
(
op instanceof Eq and sense = true
or
op instanceof NotEq and sense = false
)
)
}
/** holds for `in ["KNOWN_VALUE", ...]` on `true` edge, and `not in ["KNOWN_VALUE", ...]` on `false` edge */
private predicate test_in_const_seq(CompareNode cmp, ControlFlowNode tainted, boolean sense) {
exists(SequenceNode const_seq, Cmpop op |
forall(ControlFlowNode elem | elem = const_seq.getAnElement() | elem.getNode() instanceof StrConst)
|
cmp.operands(tainted, op, const_seq) and
(
op instanceof In and sense = true
or
op instanceof NotIn and sense = false
)
)
}
}

Просмотреть файл

@ -6,7 +6,7 @@
| test.py:20 | test_sanitizer | Attribute | NO TAINT |
| test.py:23 | test_sanitizer | Subscript | NO TAINT |
| test.py:26 | test_sanitizer | Attribute | NO TAINT |
| test.py:29 | test_sanitizer | Attribute | externally controlled string |
| test.py:29 | test_sanitizer | Attribute | NO TAINT |
| test.py:32 | test_sanitizer | Attribute | externally controlled string |
| test.py:42 | test_namedtuple | a | NO TAINT |
| test.py:42 | test_namedtuple | b | NO TAINT |

Просмотреть файл

@ -26,7 +26,7 @@ def test_sanitizer():
test(urlsplit_res.path) # FN
if urlsplit_res.netloc in ["OK"]:
test(urlsplit_res.netloc) # FP
test(urlsplit_res.netloc)
if urlsplit_res.netloc in ["OK", non_constant()]:
test(urlsplit_res.netloc) # should be tainted