-
-
Notifications
You must be signed in to change notification settings - Fork 102
Implement fuzztesting. #1139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Implement fuzztesting. #1139
Changes from all commits
bc40efb
6c18da7
4a17780
75aa9fe
625cc0e
b078e92
f1f6718
c0ed1f9
998bd29
6b240b4
f060510
ab68f1a
d1d48ea
54f7fbe
12b5139
21283f7
c47b9fd
de81b25
5f79854
8330865
1ed4452
dd36f25
0a9068d
c5363db
ccc28c8
ef20adb
845e1c1
8755056
6637d8c
decec65
672f097
ed62759
49fa5f8
e1533ab
dcba769
5e85b0b
70312c5
751f105
4cb975a
47daeda
5e08107
de6bf2e
d908fcf
d3f2987
d3fd074
7d5c20d
03ecb0c
cf07402
e0459d4
54ce26a
deaf1d0
2236c73
8ada3b9
013537b
8ec969f
3839ef1
f1e2c56
2fabe70
56acd52
a2436f5
25b98f5
eb8c087
e27ce00
8d8e3fe
303f825
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
FROM python:3.13-alpine AS builder | ||
|
||
SHELL ["/bin/sh", "-o", "pipefail", "-c"] | ||
|
||
ENV APK_CACHE_DIR="/home/owasp/.cache/apk" \ | ||
APK_SYMLINK_DIR="/etc/apk/cache" \ | ||
OWASP_GID=1000 \ | ||
OWASP_UID=1000 \ | ||
PIP_CACHE_DIR="/home/owasp/.cache/pip" \ | ||
POETRY_CACHE_DIR="/home/owasp/.cache/pypoetry" \ | ||
POETRY_VIRTUALENVS_IN_PROJECT=true \ | ||
PYTHONUNBUFFERED=1 | ||
|
||
RUN mkdir -p ${APK_CACHE_DIR} ${POETRY_CACHE_DIR} && \ | ||
ln -fns ${APK_CACHE_DIR} ${APK_SYMLINK_DIR} | ||
|
||
RUN --mount=type=cache,target=${APK_CACHE_DIR} \ | ||
apk update && apk upgrade && \ | ||
addgroup -S -g ${OWASP_GID} owasp && \ | ||
adduser -S -h /home/owasp -u ${OWASP_UID} -G owasp owasp && \ | ||
chown -R owasp:owasp /home/owasp | ||
|
||
RUN --mount=type=cache,target=${PIP_CACHE_DIR} \ | ||
python -m pip install poetry --cache-dir ${PIP_CACHE_DIR} | ||
|
||
WORKDIR /home/owasp | ||
USER owasp | ||
|
||
# Copy Poetry configuration and install dependencies | ||
COPY --chmod=444 poetry.lock pyproject.toml ./ | ||
RUN --mount=type=cache,target=${POETRY_CACHE_DIR},uid=${OWASP_UID},gid=${OWASP_GID} \ | ||
poetry install --no-root | ||
|
||
# Copy application files | ||
COPY apps apps | ||
COPY manage.py wsgi.py ./ | ||
COPY settings settings | ||
COPY static static | ||
COPY templates templates | ||
COPY fuzz_tests fuzz_tests | ||
COPY data data | ||
COPY fuzz_tests/.env .env | ||
COPY docker/entrypoint_fuzz.sh entrypoint.sh | ||
|
||
FROM python:3.13-alpine | ||
|
||
SHELL ["/bin/sh", "-o", "pipefail", "-c"] | ||
|
||
# Install runtime dependencies | ||
RUN addgroup -S owasp && \ | ||
adduser -S -h /home/owasp -G owasp owasp && \ | ||
mkdir -p /home/owasp && \ | ||
chown owasp:owasp /home/owasp | ||
|
||
ENV FORCE_COLOR=1 \ | ||
PATH="/home/owasp/.venv/bin:$PATH" \ | ||
PYTHONUNBUFFERED=1 | ||
|
||
WORKDIR /home/owasp | ||
USER owasp | ||
|
||
# Copy built application from the builder stage | ||
COPY --from=builder --chmod=555 --chown=owasp:owasp /home/owasp /home/owasp | ||
|
||
RUN touch /home/owasp/fuzz_tests.db && \ | ||
chmod +x /home/owasp/fuzz_tests.db /home/owasp/entrypoint.sh | ||
|
||
|
||
# Expose the running port | ||
EXPOSE 8000 | ||
|
||
# Run fuzz tests | ||
|
||
CMD ["/home/owasp/entrypoint.sh"] |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,41 @@ | ||||||||||||||||
FROM python:3.12-alpine | ||||||||||||||||
|
||||||||||||||||
ENV APK_CACHE_DIR="/home/owasp/.cache/apk" \ | ||||||||||||||||
APK_SYMLINK_DIR="/etc/apk/cache" \ | ||||||||||||||||
OWASP_GID=1000 \ | ||||||||||||||||
OWASP_UID=1000 \ | ||||||||||||||||
PIP_CACHE_DIR="/home/owasp/.cache/pip" \ | ||||||||||||||||
POETRY_VIRTUALENVS_IN_PROJECT=true \ | ||||||||||||||||
PYTHONUNBUFFERED=1 | ||||||||||||||||
|
||||||||||||||||
RUN mkdir -p ${APK_CACHE_DIR} && \ | ||||||||||||||||
ln -fns ${APK_CACHE_DIR} ${APK_SYMLINK_DIR} | ||||||||||||||||
|
||||||||||||||||
RUN --mount=type=cache,target=${APK_CACHE_DIR} \ | ||||||||||||||||
apk update && apk upgrade && \ | ||||||||||||||||
addgroup -S -g ${OWASP_GID} owasp && \ | ||||||||||||||||
adduser -S -h /home/owasp -u ${OWASP_UID} -G owasp owasp && \ | ||||||||||||||||
chown -R owasp:owasp /home/owasp | ||||||||||||||||
|
||||||||||||||||
RUN --mount=type=cache,target=${APK_CACHE_DIR},uid=${OWASP_UID},gid=${OWASP_GID} \ | ||||||||||||||||
apk add curl jq gcc musl-dev libffi-dev linux-headers | ||||||||||||||||
|
||||||||||||||||
RUN --mount=type=cache,target=${PIP_CACHE_DIR} \ | ||||||||||||||||
pip install graphqler --cache-dir ${PIP_CACHE_DIR} | ||||||||||||||||
|
||||||||||||||||
WORKDIR /home/owasp | ||||||||||||||||
|
||||||||||||||||
COPY docker/entrypoint_graphql_fuzz.sh entrypoint.sh | ||||||||||||||||
|
||||||||||||||||
RUN touch /home/owasp/config.toml && \ | ||||||||||||||||
chmod +x /home/owasp/config.toml && \ | ||||||||||||||||
chown owasp:owasp /home/owasp/config.toml | ||||||||||||||||
Comment on lines
+30
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don’t - RUN touch /home/owasp/config.toml && \
- chmod +x /home/owasp/config.toml && \
- chown owasp:owasp /home/owasp/config.toml
+ COPY config.toml /home/owasp/config.toml
+ RUN chmod 600 /home/owasp/config.toml && \
+ chown owasp:owasp /home/owasp/config.toml Adjust source path to your repo structure. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents (early access)
|
||||||||||||||||
|
||||||||||||||||
# Create the graphql output dir and give permissions to the owasp user | ||||||||||||||||
RUN mkdir -p /home/owasp/fuzzing_results && \ | ||||||||||||||||
chmod +x /home/owasp/fuzzing_results /home/owasp/entrypoint.sh && \ | ||||||||||||||||
chown owasp:owasp /home/owasp/fuzzing_results /home/owasp/entrypoint.sh | ||||||||||||||||
|
||||||||||||||||
USER owasp | ||||||||||||||||
|
||||||||||||||||
CMD ["/home/owasp/entrypoint.sh"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/bin/sh | ||
|
||
python manage.py migrate | ||
python manage.py collectstatic --noinput | ||
|
||
# Load initial data | ||
python manage.py load_data | ||
|
||
pytest fuzz_tests | ||
|
||
python manage.py runserver 0.0.0.0:8000 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/bin/sh | ||
|
||
echo "Retrieving CSRF token..." | ||
|
||
CSRF_TOKEN=$(curl -s http://backend:8000/csrf/ | jq -r '.csrftoken') | ||
|
||
if [ -z "$CSRF_TOKEN" ]; then | ||
echo "Failed to retrieve CSRF token" | ||
exit 1 | ||
fi | ||
|
||
echo "CSRF token retrieved successfully: $CSRF_TOKEN" | ||
|
||
cat > /home/owasp/config.toml << EOF | ||
[CUSTOM_HEADERS] | ||
X-CSRF-Token = "$CSRF_TOKEN" | ||
EOF | ||
|
||
echo "Custom headers configuration file created successfully" | ||
|
||
sleep 5 | ||
|
||
echo "Starting fuzzing tests..." | ||
python -m graphqler --config /home/owasp/config.toml --url http://backend:8000/graphql/ --mode run --path /home/owasp/fuzzing_results |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
"""Test Slack contribute event handler.""" | ||
|
||
from unittest.mock import MagicMock, patch | ||
|
||
from django.conf import settings | ||
from hypothesis import given | ||
from hypothesis import strategies as st | ||
|
||
from apps.slack.constants import ( | ||
OWASP_CONTRIBUTE_CHANNEL_ID, | ||
) | ||
from apps.slack.events.member_joined_channel.contribute import Contribute | ||
|
||
|
||
class TestContributeEventHandler: | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""Test cases for the Contribute Slack event handler.""" | ||
|
||
@given( | ||
events_enabled=st.booleans(), | ||
project_count=st.integers(), | ||
issue_count=st.integers(), | ||
) | ||
@patch("apps.owasp.models.project.Project.active_projects_count") | ||
@patch("apps.github.models.issue.Issue.open_issues_count") | ||
def test_handler_responses( | ||
self, | ||
mock_open_issues_count, | ||
mock_active_projects_count, | ||
events_enabled, | ||
project_count, | ||
issue_count, | ||
): | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""Test the contribute event handler responses.""" | ||
settings.SLACK_EVENTS_ENABLED = events_enabled | ||
mock_active_projects_count.return_value = project_count | ||
mock_open_issues_count.return_value = issue_count | ||
mock_slack_event = {"user": "U123456", "channel": OWASP_CONTRIBUTE_CHANNEL_ID} | ||
mock_slack_client = MagicMock() | ||
mock_slack_client.conversations_open.return_value = {"channel": {"id": "C123456"}} | ||
|
||
contribute = Contribute() | ||
|
||
contribute.handler(event=mock_slack_event, client=mock_slack_client, ack=MagicMock()) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Test cases for the GSOC Slack event handler.""" | ||
|
||
from unittest.mock import MagicMock | ||
|
||
from django.conf import settings | ||
from hypothesis import given | ||
from hypothesis import strategies as st | ||
|
||
from apps.slack.constants import OWASP_GSOC_CHANNEL_ID | ||
from apps.slack.events.member_joined_channel.gsoc import Gsoc | ||
|
||
|
||
class TestGsocEventHandler: | ||
"""Test cases for the GSOC Slack event handler.""" | ||
|
||
@given( | ||
channel_id=st.text(), | ||
) | ||
def test_check_gsoc_handler(self, channel_id): | ||
"""Test the check_gsoc_handler function.""" | ||
gsoc_module = __import__( | ||
"apps.slack.events.member_joined_channel.gsoc", | ||
fromlist=["gsoc_handler"], | ||
) | ||
check_gsoc_handler = getattr( | ||
gsoc_module, | ||
"check_gsoc_handler", | ||
lambda x: x.get("channel") == OWASP_GSOC_CHANNEL_ID, | ||
) | ||
|
||
check_gsoc_handler({"channel": channel_id}) | ||
|
||
@given( | ||
events_enabled=st.booleans(), | ||
) | ||
def test_handler_responses(self, events_enabled): | ||
"""Test the GSOC event handler responses.""" | ||
settings.SLACK_EVENTS_ENABLED = events_enabled | ||
mock_slack_event = {"user": "U123456", "channel": OWASP_GSOC_CHANNEL_ID} | ||
mock_slack_client = MagicMock() | ||
mock_slack_client.conversations_open.return_value = {"channel": {"id": "C123456"}} | ||
|
||
gsoc = Gsoc() | ||
gsoc.handler(event=mock_slack_event, client=mock_slack_client, ack=MagicMock()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Pin
graphqler
version and verify integrity.Installing without a version or hash risks breakage or supply-chain attacks. Pin to a tested version and consider
--require-hashes
.📝 Committable suggestion
🤖 Prompt for AI Agents (early access)