Merge branch 'main' into main

This commit is contained in:
Raul Garcia
2023-03-29 20:27:03 -07:00
committed by GitHub
512 changed files with 20623 additions and 5243 deletions

View File

@@ -0,0 +1,12 @@
edges
| TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature |
| TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() |
nodes
| TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | semmle.label | ControlFlowNode for signature |
| TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() |
subpaths
#select
| TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | Possible Timing attack against $@ validation. | signature | message |
| TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | MAC | message |

View File

@@ -0,0 +1 @@
experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Desc Timing Attack Against Hash
"""
import hashlib
import hmac
from cryptography.hazmat.primitives import cmac
from cryptography.hazmat.primitives.ciphers import algorithms
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
def UnsafeCmacCheck(actualCmac):
expected = cmac.CMAC(algorithms.AES(key))
expected.update(b"message to authenticate")
expected.finalize()
return actualCmac == expected
def UnsafeCheckSignature(expected):
message = b'To be signed'
key = RSA.import_key(open('private_key.der').read())
h = SHA256.new(message)
signature = pkcs1_15.new(key).sign(h)
return expected == signature
def sign(pre_key, msg, alg):
return hmac.new(pre_key, msg, alg).digest()
def verifyGood(msg, sig):
return constant_time_string_compare(sig, sign(key, msg, hashlib.sha256)) #good
def verifyBad(msg, sig):
key = "e179017a-62b0-4996-8a38-e91aa9f1"
return sig == sign(key, msg, hashlib.sha256) #bad
def constant_time_string_compare(a, b):
if len(a) != len(b):
return False
result = 0
for x, y in zip(a, b):
result |= ord(x) ^ ord(y)
return result == 0

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Desc Timing Attack Against Header
"""
from flask import Flask
from flask import request
import hmac
app = Flask(__name__)
@app.route('/bad')
def bad():
if not request.headers.get('X-Auth-Token') == "token":
raise Exception('bad token')
return 'bad'
@app.route('/good')
def good():
tok = request.headers.get('X-Auth-Token')
if not hmac.compare_digest(tok, "token"):
raise Exception('bad token')
return 'good'
if __name__ == '__main__':
app.debug = True
app.run()

View File

@@ -0,0 +1,6 @@
edges
nodes
| TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
subpaths
#select
| TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | Timing attack against $@ validation. | TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | client-supplied token |

View File

@@ -0,0 +1 @@
experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql

View File

@@ -0,0 +1,33 @@
edges
| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request |
| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request |
| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | TimingAttackAgainstSensitiveInfo.py:20:8:20:14 | ControlFlowNode for request |
| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | TimingAttackAgainstSensitiveInfo.py:21:20:21:26 | ControlFlowNode for request |
| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | ControlFlowNode for ImportMember | TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request |
| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request |
| TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute |
| TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute |
| TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | TimingAttackAgainstSensitiveInfo.py:15:20:15:38 | ControlFlowNode for Subscript |
| TimingAttackAgainstSensitiveInfo.py:15:20:15:38 | ControlFlowNode for Subscript | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password |
| TimingAttackAgainstSensitiveInfo.py:20:8:20:14 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:21:20:21:31 | ControlFlowNode for Attribute |
| TimingAttackAgainstSensitiveInfo.py:21:20:21:26 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:21:20:21:31 | ControlFlowNode for Attribute |
| TimingAttackAgainstSensitiveInfo.py:21:20:21:31 | ControlFlowNode for Attribute | TimingAttackAgainstSensitiveInfo.py:21:20:21:38 | ControlFlowNode for Subscript |
| TimingAttackAgainstSensitiveInfo.py:21:20:21:38 | ControlFlowNode for Subscript | TimingAttackAgainstSensitiveInfo.py:22:38:22:45 | ControlFlowNode for password |
nodes
| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | semmle.label | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request |
| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | semmle.label | GSSA Variable request |
| TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| TimingAttackAgainstSensitiveInfo.py:15:20:15:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
| TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
| TimingAttackAgainstSensitiveInfo.py:20:8:20:14 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| TimingAttackAgainstSensitiveInfo.py:21:20:21:26 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| TimingAttackAgainstSensitiveInfo.py:21:20:21:31 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| TimingAttackAgainstSensitiveInfo.py:21:20:21:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| TimingAttackAgainstSensitiveInfo.py:22:38:22:45 | ControlFlowNode for password | semmle.label | ControlFlowNode for password |
subpaths
#select
| TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | Timing attack against $@ validation. | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | client-supplied token |

View File

@@ -0,0 +1 @@
experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql

View File

@@ -0,0 +1,26 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Desc timing attack against Secret
"""
from flask import Flask
from flask import request
from django.utils.crypto import constant_time_compare
app = Flask(__name__)
@app.route('/bad', methods = ['POST', 'GET'])
def bad():
if request.method == 'POST':
password = request.form['pwd']
return password == "1234"
@app.route('/good', methods = ['POST', 'GET'])
def good():
if request.method == 'POST':
password = request.form['pwd']
return constant_time_compare(password, "1234")
if __name__ == '__main__':
app.debug = True
app.run()

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,27 @@
import aiosqlite
# see https://pypi.org/project/aiosqlite/
async def test():
db = await aiosqlite.connect(...)
await db.execute("sql") # $ getSql="sql" constructedSql="sql"
await db.execute(sql="sql") # $ getSql="sql" constructedSql="sql"
cursor = await db.cursor()
cursor.execute("sql") # $ constructedSql="sql"
cursor = await db.execute("sql") # $ getSql="sql" constructedSql="sql"
cursor.execute("sql") # $ constructedSql="sql"
async with aiosqlite.connect(...) as db:
db.row_factory = aiosqlite.Row
async with db.execute("sql") as cursor: # $ getSql="sql" constructedSql="sql"
async for row in cursor:
print(row['column'])
# nonstandard
await db.execute_insert("sql") # $ getSql="sql" constructedSql="sql"
await db.execute_fetchall("sql") # $ getSql="sql" constructedSql="sql"
await db.executescript("sql") # $ getSql="sql" constructedSql="sql"
await db.executescript(sql_script="sql") # $ getSql="sql" constructedSql="sql"

View File

@@ -22,6 +22,9 @@ async def test_connection():
finally:
await conn.close()
conn = await asyncpg.connection.connect()
conn.execute("sql") # $ mad-sink[sql-injection]="sql"
async def test_prepared_statement():
conn = await asyncpg.connect()

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,12 @@
from cassandra.cluster import Cluster
cluster = Cluster(...)
session = cluster.connect()
session.execute("sql") # $ getSql="sql"
future = session.execute_async("sql") # $ constructedSql="sql"
future.result()
prepared = session.prepare("sql") # $ constructedSql="sql"
session.execute(prepared) # $ SPURIOUS: getSql=prepared

View File

@@ -6,3 +6,10 @@ db.execute("some sql", (42,)) # $ getSql="some sql"
cursor = db.cursor()
cursor.execute("some sql", (42,)) # $ getSql="some sql"
cursor.executescript("sql") # $ getSql="sql"
cursor.executescript(sql_script="sql") # $ getSql="sql"
import sqlite3.dbapi2
conn = sqlite3.dbapi2.connect()
cursor = conn.cursor()
cursor.execute("some sql") # $ getSql="some sql"

View File

@@ -18,15 +18,18 @@
| import_use.py:17:14:17:34 | ControlFlowNode for also_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_def.py:10:25:10:56 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv2 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context |
| pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context |
| pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context |
| pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context |
| pyOpenSSL_fluent.py:18:27:18:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv2 allowed by $@. | pyOpenSSL_fluent.py:15:15:15:44 | ControlFlowNode for Attribute() | call to SSL.Context |
| pyOpenSSL_fluent.py:18:27:18:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | pyOpenSSL_fluent.py:15:15:15:44 | ControlFlowNode for Attribute() | call to SSL.Context |
| pyOpenSSL_fluent.py:18:27:18:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | pyOpenSSL_fluent.py:15:15:15:44 | ControlFlowNode for Attribute() | call to SSL.Context |
| ssl_fluent.py:9:14:9:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:6:15:6:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:9:14:9:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:6:15:6:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:19:14:19:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:15:15:15:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:28:14:28:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:24:15:24:53 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:37:14:37:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:33:15:33:53 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:57:14:57:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv2 allowed by $@. | ssl_fluent.py:54:15:54:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:57:14:57:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | ssl_fluent.py:54:15:54:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:57:14:57:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:54:15:54:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:57:14:57:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:54:15:54:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:101:15:101:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext |
| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext |

View File

@@ -2,3 +2,4 @@
| test.py:9:14:9:29 | Str | test.py:9:27:9:29 | \\d+ | Strings starting with '0.9' and with many repetitions of '99' can start matching anywhere after the start of the preceeding \\d+ |
| test.py:11:22:11:33 | Str | test.py:11:31:11:33 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ |
| test.py:18:14:18:25 | Str | test.py:18:23:18:25 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ |
| test.py:20:23:20:274 | Str | test.py:20:273:20:274 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*Y |

View File

@@ -29,3 +29,4 @@ subpaths
| test.py:9:32:9:35 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with '0.9' and with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
| test.py:12:17:12:20 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:12:17:12:20 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:11:31:11:33 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
| test.py:16:24:16:30 | ControlFlowNode for my_text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:16:24:16:30 | ControlFlowNode for my_text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:18:23:18:25 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |
| test.py:21:18:21:21 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:21:18:21:21 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | test.py:20:273:20:274 | .* | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value |

View File

@@ -17,6 +17,6 @@ def code_execution():
indirect(r"^\s+|\s+$", text)
reg2 = re.compile(r"(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*")
reg2 = re.compile(r"(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*Y")
reg2.sub("", text) # NOT OK