Python: Port sensitive data modeling

No longer using points-to 🎉
This commit is contained in:
Rasmus Wriedt Larsen
2021-06-03 14:17:29 +02:00
parent 3b68c87b6c
commit 00a71a1c41
3 changed files with 110 additions and 17 deletions

View File

@@ -2,19 +2,32 @@ import python
import semmle.python.dataflow.new.DataFlow
import TestUtilities.InlineExpectationsTest
import semmle.python.dataflow.new.SensitiveDataSources
private import semmle.python.ApiGraphs
class SensitiveDataSourcesTest extends InlineExpectationsTest {
SensitiveDataSourcesTest() { this = "SensitiveDataSourcesTest" }
override string getARelevantTag() { result = "SensitiveDataSource" }
override string getARelevantTag() { result in ["SensitiveDataSource", "SensitiveUse"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(SensitiveDataSource source |
location = source.getLocation() and
element = source.toString() and
value = source.getClassification() and
tag = "SensitiveDataSource"
(
location = source.getLocation() and
element = source.toString() and
value = source.getClassification() and
tag = "SensitiveDataSource"
)
or
exists(DataFlow::Node use |
use = API::builtin("print").getACall().getArg(_) and
DataFlow::localFlow(source, use) and
location = use.getLocation() and
element = use.toString() and
value = source.getClassification() and
tag = "SensitiveUse"
)
)
}
}

View File

@@ -1,5 +1,6 @@
from not_found import get_passwd, account_id
from not_found import get_passwd # $ SensitiveDataSource=password
from not_found import account_id # $ SensitiveDataSource=id
def get_password():
pass
@@ -30,7 +31,7 @@ foo.username # $ SensitiveDataSource=id
# plain variables
password = some_function()
print(password) # $ MISSING: SensitiveDataSource=password
print(password) # $ MISSING: SensitiveUse=password
# Special handling of lookups of sensitive properties
request.args["password"], # $ MISSING: SensitiveDataSource=password
@@ -41,3 +42,6 @@ request.args.get(x) # $ SensitiveDataSource=password
# I don't think handling `getlist` is super important, just included it to show what we don't handle
request.args.getlist("password")[0] # $ MISSING: SensitiveDataSource=password
from not_found import password2 as foo # $ SensitiveDataSource=password
print(foo) # $ SensitiveUse=password