Skip to content

Commit

Permalink
Merge pull request #213 from AikidoSec/update-sql-injection-algo-to-t…
Browse files Browse the repository at this point in the history
…okenizer

Use zen_internals sql tokenizer
  • Loading branch information
willem-delbare authored Nov 26, 2024
2 parents d3e2c7d + 941b377 commit 22518e0
Show file tree
Hide file tree
Showing 34 changed files with 343 additions and 781 deletions.
9 changes: 2 additions & 7 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ jobs:
- name: Add local.aikido.io to /etc/hosts
run: |
sudo echo "127.0.0.1 local.aikido.io" | sudo tee -a /etc/hosts
- name: Install poetry
run: pip install poetry
- name: Install dependencies
run: poetry install
- name: Installation
run: make install
- name: Run Pylint
run: |
poetry run pylint --fail-under=9 --rcfile=.pylintrc aikido_zen/
Expand Down Expand Up @@ -50,9 +48,6 @@ jobs:
- uses: actions/checkout@v4
- name: Install poetry
run: pip install poetry
- name: Install dependencies
run: poetry install

- name: Publish to PyPI
env:
POETRY_HTTP_BASIC_PYPI_USERNAME: __token__
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/test-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ jobs:
- name: Add local.aikido.io to /etc/hosts
run: |
sudo echo "127.0.0.1 local.aikido.io" | sudo tee -a /etc/hosts
- name: Install poetry
run: pip install poetry
- name: Install dependencies
run: poetry install
- name: Installation
run: make install
- name: Run Pylint
run: |
poetry run pylint --fail-under=9 --rcfile=.pylintrc aikido_zen/
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ jobs:
run: |
python -m pip install --upgrade pip
make install
- name: Run tests with coverage
run: |
make cov
Expand Down
33 changes: 26 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.PHONY: build
build:
build: binaries _build
_build:
poetry build

.PHONY: clean
Expand All @@ -11,14 +11,12 @@ lint:
poetry run black aikido_zen/
poetry run pylint aikido_zen/

.PHONY: install
install:
install: binaries
pip install poetry
poetry install

.PHONY: dev_install
dev_install:
pip install poetry
dev_install: install _dev_install
_dev_install:
poetry install --with=dev


Expand All @@ -37,3 +35,24 @@ cov:
.PHONY: benchmark
benchmark:
k6 run -q ./benchmarks/flask-mysql-benchmarks.js

BASE_URL = https://github.com/AikidoSec/zen-internals/releases/download/v0.1.31
FILES = \
libzen_internals_aarch64-apple-darwin.dylib \
libzen_internals_aarch64-apple-darwin.dylib.sha256sum \
libzen_internals_aarch64-unknown-linux-gnu.so \
libzen_internals_aarch64-unknown-linux-gnu.so.sha256sum \
libzen_internals_x86_64-apple-darwin.dylib \
libzen_internals_x86_64-apple-darwin.dylib.sha256sum \
libzen_internals_x86_64-pc-windows-gnu.dll \
libzen_internals_x86_64-pc-windows-gnu.dll.sha256sum \
libzen_internals_x86_64-unknown-linux-gnu.so \
libzen_internals_x86_64-unknown-linux-gnu.so.sha256sum

binaries: binaries_make_dir $(addprefix aikido_zen/lib/, $(FILES))
binaries_make_dir:
rm -rf aikido_zen/lib
mkdir -p aikido_zen/lib/
aikido_zen/lib/%:
@echo "Downloading $*..."
curl -L -o $@ $(BASE_URL)/$*
7 changes: 3 additions & 4 deletions aikido_zen/sinks/asyncpg.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import copy
import aikido_zen.importhook as importhook
from aikido_zen.vulnerabilities.sql_injection.dialects import Postgres
from aikido_zen.background_process.packages import pkg_compat_check
import aikido_zen.vulnerabilities as vulns
from aikido_zen.helpers.logging import logger
Expand Down Expand Up @@ -36,7 +35,7 @@ def aikido_new__execute(_self, query, *args, **kwargs):
vulns.run_vulnerability_scan(
kind="sql_injection",
op="asyncpg.connection.Connection._execute",
args=(query, Postgres()),
args=(query, "postgres"),
)

return former__execute(_self, query, *args, **kwargs)
Expand All @@ -46,15 +45,15 @@ def aikido_new_executemany(_self, query, *args, **kwargs):
vulns.run_vulnerability_scan(
kind="sql_injection",
op="asyncpg.connection.Connection.executemany",
args=(query, Postgres()),
args=(query, "postgres"),
)
return former_executemany(_self, query, *args, **kwargs)

def aikido_new_execute(_self, query, *args, **kwargs):
vulns.run_vulnerability_scan(
kind="sql_injection",
op="asyncpg.connection.Connection.execute",
args=(query, Postgres()),
args=(query, "postgres"),
)
return former_execute(_self, query, *args, **kwargs)

Expand Down
5 changes: 2 additions & 3 deletions aikido_zen/sinks/mysqlclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import copy
import aikido_zen.importhook as importhook
from aikido_zen.vulnerabilities.sql_injection.dialects import MySQL
from aikido_zen.background_process.packages import pkg_compat_check
from aikido_zen.helpers.logging import logger
import aikido_zen.vulnerabilities as vulns
Expand All @@ -31,13 +30,13 @@ def aikido_new_execute(self, query, args=None):
logger.debug("Query is bytearray, normally comes from executemany.")
return prev_execute_func(self, query, args)
vulns.run_vulnerability_scan(
kind="sql_injection", op="MySQLdb.Cursor.execute", args=(query, MySQL())
kind="sql_injection", op="MySQLdb.Cursor.execute", args=(query, "mysql")
)
return prev_execute_func(self, query, args)

def aikido_new_executemany(self, query, args):
op = "MySQLdb.Cursor.executemany"
vulns.run_vulnerability_scan(kind="sql_injection", op=op, args=(query, MySQL()))
vulns.run_vulnerability_scan(kind="sql_injection", op=op, args=(query, "mysql"))
return prev_executemany_func(self, query, args)

setattr(mysql.Cursor, "execute", aikido_new_execute)
Expand Down
7 changes: 3 additions & 4 deletions aikido_zen/sinks/psycopg.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import copy
import aikido_zen.importhook as importhook
from aikido_zen.vulnerabilities.sql_injection.dialects import Postgres
from aikido_zen.background_process.packages import pkg_compat_check
import aikido_zen.vulnerabilities as vulns

Expand All @@ -27,19 +26,19 @@ def on_psycopg_import(psycopg):
def aikido_copy(self, statement, params=None, *args, **kwargs):
sql = statement
vulns.run_vulnerability_scan(
kind="sql_injection", op="psycopg.Cursor.copy", args=(sql, Postgres())
kind="sql_injection", op="psycopg.Cursor.copy", args=(sql, "postgres")
)
return former_copy_funtcion(self, statement, params, *args, **kwargs)

def aikido_execute(self, query, params=None, *args, **kwargs):
sql = query
vulns.run_vulnerability_scan(
kind="sql_injection", op="psycopg.Cursor.execute", args=(sql, Postgres())
kind="sql_injection", op="psycopg.Cursor.execute", args=(sql, "postgres")
)
return former_execute_function(self, query, params, *args, **kwargs)

def aikido_executemany(self, query, params_seq):
args = (query, Postgres())
args = (query, "postgres")
op = "psycopg.Cursor.executemany"
vulns.run_vulnerability_scan(kind="sql_injection", op=op, args=args)
return former_executemany_function(self, query, params_seq)
Expand Down
5 changes: 2 additions & 3 deletions aikido_zen/sinks/psycopg2.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import copy
import aikido_zen.importhook as importhook
from aikido_zen.vulnerabilities.sql_injection.dialects import Postgres
from aikido_zen.background_process.packages import pkg_compat_check
import aikido_zen.vulnerabilities as vulns

Expand All @@ -21,7 +20,7 @@ def execute(self, *args, **kwargs):
vulns.run_vulnerability_scan(
kind="sql_injection",
op="psycopg2.Connection.Cursor.execute",
args=(args[0], Postgres()), # args[0] : sql
args=(args[0], "postgres"), # args[0] : sql
)
if former_cursor_factory and hasattr(former_cursor_factory, "execute"):
return former_cursor_factory.execute(self, *args, **kwargs)
Expand All @@ -33,7 +32,7 @@ def executemany(self, *args, **kwargs):
vulns.run_vulnerability_scan(
kind="sql_injection",
op="psycopg2.Connection.Cursor.executemany",
args=(sql, Postgres()),
args=(sql, "postgres"),
)
if former_cursor_factory and hasattr(former_cursor_factory, "executemany"):
return former_cursor_factory.executemany(self, *args, **kwargs)
Expand Down
5 changes: 2 additions & 3 deletions aikido_zen/sinks/pymysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import copy
import logging
import aikido_zen.importhook as importhook
from aikido_zen.vulnerabilities.sql_injection.dialects import MySQL
from aikido_zen.background_process.packages import pkg_compat_check
import aikido_zen.vulnerabilities as vulns

Expand Down Expand Up @@ -34,13 +33,13 @@ def aikido_new_execute(self, query, args=None):
logger.debug("Query is bytearray, normally comes from executemany.")
return prev_execute_func(self, query, args)
vulns.run_vulnerability_scan(
kind="sql_injection", op="pymysql.Cursor.execute", args=(query, MySQL())
kind="sql_injection", op="pymysql.Cursor.execute", args=(query, "mysql")
)
return prev_execute_func(self, query, args)

def aikido_new_executemany(self, query, args):
op = "pymysql.Cursor.executemany"
vulns.run_vulnerability_scan(kind="sql_injection", op=op, args=(query, MySQL()))
vulns.run_vulnerability_scan(kind="sql_injection", op=op, args=(query, "mysql"))
return prev_executemany_func(self, query, args)

setattr(mysql.Cursor, "execute", aikido_new_execute)
Expand Down
11 changes: 5 additions & 6 deletions aikido_zen/sinks/tests/asyncpg_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import aikido_zen.sinks.asyncpg
import aikido_zen.sinks.os
from aikido_zen.background_process.comms import reset_comms
from aikido_zen.vulnerabilities.sql_injection.dialects import Postgres

kind = "sql_injection"
op = "MySQLdb.connections.query"
Expand Down Expand Up @@ -33,7 +32,7 @@ async def test_conn_execute(database_conn):
called_with_op = mock_run_vulnerability_scan.call_args[1]["op"]
called_with_kind = mock_run_vulnerability_scan.call_args[1]["kind"]
assert called_with_args[0] == query
assert isinstance(called_with_args[1], Postgres)
assert called_with_args[1] == "postgres"
assert called_with_op == "asyncpg.connection.Connection.execute"
assert called_with_kind == "sql_injection"

Expand All @@ -52,7 +51,7 @@ async def test_conn_fetchrow(database_conn):

called_with_args = mock_run_vulnerability_scan.call_args[1]["args"]
assert called_with_args[0] == query
assert isinstance(called_with_args[1], Postgres)
assert called_with_args[1] == "postgres"

await conn.close()

Expand All @@ -69,7 +68,7 @@ async def test_conn_fetch(database_conn):

called_with_args = mock_run_vulnerability_scan.call_args[1]["args"]
assert called_with_args[0] == query
assert isinstance(called_with_args[1], Postgres)
assert called_with_args[1] == "postgres"

await conn.close()

Expand All @@ -86,7 +85,7 @@ async def test_conn_fetchval(database_conn):

called_with_args = mock_run_vulnerability_scan.call_args[1]["args"]
assert called_with_args[0] == query
assert isinstance(called_with_args[1], Postgres)
assert called_with_args[1] == "postgres"

await conn.close()

Expand Down Expand Up @@ -152,6 +151,6 @@ async def test_conn_cursor(database_conn):

called_with_args = mock_run_vulnerability_scan.call_args[1]["args"]
assert called_with_args[0] == "BEGIN;"
assert isinstance(called_with_args[1], Postgres)
assert called_with_args[1] == "postgres"

await conn.close()
9 changes: 4 additions & 5 deletions aikido_zen/sinks/tests/mysqlclient_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from unittest.mock import patch
import aikido_zen.sinks.mysqlclient
from aikido_zen.background_process.comms import reset_comms
from aikido_zen.vulnerabilities.sql_injection.dialects import MySQL

kind = "sql_injection"
op = "MySQLdb.connections.query"
Expand All @@ -25,7 +24,7 @@ def test_cursor_execute(database_conn):
cursor.execute(query)
called_with_args = mock_run_vulnerability_scan.call_args[1]["args"]
assert called_with_args[0] == query
assert isinstance(called_with_args[1], MySQL)
assert called_with_args[1] == "mysql"

mock_run_vulnerability_scan.assert_called_once()
cursor.fetchall()
Expand All @@ -51,7 +50,7 @@ def test_cursor_execute_no_args(database_conn):
called_with_args[0]
== 'INSERT INTO dogs (dog_name, isAdmin) VALUES ("Doggo", TRUE)'
)
assert isinstance(called_with_args[1], MySQL)
assert called_with_args[1] == "mysql"

mock_run_vulnerability_scan.assert_called_once()
cursor.fetchall()
Expand Down Expand Up @@ -79,7 +78,7 @@ def test_cursor_executemany(database_conn):
called_with_args[0]
== "INSERT INTO dogs (dog_name, isAdmin) VALUES (%s, %s)"
)
assert isinstance(called_with_args[1], MySQL)
assert called_with_args[1] == "mysql"
mock_run_vulnerability_scan.assert_called_once()
database_conn.commit()
mock_run_vulnerability_scan.assert_called_once()
Expand All @@ -105,7 +104,7 @@ def test_cursor_execute_with_fstring(database_conn):
assert (
called_with_args[0] == "INSERT INTO dogs (dog_name, isAdmin) VALUES (%s, 1)"
)
assert isinstance(called_with_args[1], MySQL)
assert called_with_args[1] == "mysql"
mock_run_vulnerability_scan.assert_called_once()
database_conn.commit()
mock_run_vulnerability_scan.assert_called_once()
Expand Down
7 changes: 3 additions & 4 deletions aikido_zen/sinks/tests/psycopg2_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from unittest.mock import patch
import aikido_zen.sinks.psycopg2
from aikido_zen.background_process.comms import reset_comms
from aikido_zen.vulnerabilities.sql_injection.dialects import Postgres

kind = "sql_injection"
op = "pymysql.connections.query"
Expand All @@ -28,7 +27,7 @@ def test_cursor_execute(database_conn):

called_with_args = mock_run_vulnerability_scan.call_args[1]["args"]
assert called_with_args[0] == query
assert isinstance(called_with_args[1], Postgres)
assert called_with_args[1] == "postgres"
mock_run_vulnerability_scan.assert_called_once()

cursor.fetchall()
Expand All @@ -47,7 +46,7 @@ def test_cursor_execute_parameterized(database_conn):

called_with_args = mock_run_vulnerability_scan.call_args[1]["args"]
assert called_with_args[0] == query
assert isinstance(called_with_args[1], Postgres)
assert called_with_args[1] == "postgres"
mock_run_vulnerability_scan.assert_called_once()

database_conn.commit()
Expand All @@ -72,7 +71,7 @@ def test_cursor_executemany(database_conn):
called_with_args[0]
== "INSERT INTO dogs (dog_name, isadmin) VALUES (%s, %s)"
)
assert isinstance(called_with_args[1], Postgres)
assert called_with_args[1] == "postgres"
mock_run_vulnerability_scan.assert_called_once()

database_conn.commit()
Expand Down
Loading

0 comments on commit 22518e0

Please sign in to comment.