-
-
Notifications
You must be signed in to change notification settings - Fork 46
Security Export: Issues, Dependabot & CodeScan Alerts #153
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
Changes from all commits
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,37 @@ | ||
| # Repository: LazyOwn | ||
|
|
||
| **Description:** LazyOwn RedTeam/APT Framework is the first RedTeam Framework with an AI-powered C&C, featuring rootkits to conceal campaigns, undetectable malleable implants compatible with Windows/Linux/Mac OSX, and self-configuring backdoors. With its Web interface and powerful Console Client, it is the best combination for your Autonomous RedTeam/APT campaigns. | ||
|
|
||
| | Metric | Value | | ||
| |--------|-------| | ||
| | ⭐ Stars | 212 | | ||
| | 📥 Clones (last 14 days) | 691 | | ||
| | 🟢 Open Issues | 1 | | ||
| | 📋 Total Issues | 4 | | ||
| | 🛡 Dependabot Open Alerts | 3 | | ||
| | 🔍 CodeScan Open Alerts | 10 | | ||
|
|
||
| ## Issues | ||
| - [#84](./issue_84.md) - Lazynmap failing to execute (closed) | ||
| - [#30](./issue_30.md) - Please remove ngrok as a tunneling option as this tool violates the terms of service (closed) | ||
| - [#17](./issue_17.md) - Fix code scanning alert - Flask app is run in debug mode (closed) | ||
| - [#16](./issue_16.md) - Fix code scanning alert - Information exposure through an exception (closed) | ||
|
|
||
| ## Dependabot Alerts | ||
| - [Dependabot #47](./dependabot/alert_47.md) - python-socketio (high) - open | ||
| - [Dependabot #46](./dependabot/alert_46.md) - python-engineio (high) - open | ||
| - [Dependabot #45](./dependabot/alert_45.md) - python-engineio (high) - open | ||
|
|
||
| ## Code Scanning Alerts | ||
| - [CodeScan #781](./codescan/alert_781.md) - py/incomplete-url-substring-sanitization (warning) - open | ||
| - [CodeScan #780](./codescan/alert_780.md) - py/incomplete-url-substring-sanitization (warning) - open | ||
| - [CodeScan #779](./codescan/alert_779.md) - py/incomplete-url-substring-sanitization (warning) - open | ||
| - [CodeScan #778](./codescan/alert_778.md) - py/incomplete-url-substring-sanitization (warning) - open | ||
| - [CodeScan #777](./codescan/alert_777.md) - py/incomplete-url-substring-sanitization (warning) - open | ||
| - [CodeScan #776](./codescan/alert_776.md) - py/overly-large-range (warning) - open | ||
| - [CodeScan #775](./codescan/alert_775.md) - py/overly-large-range (warning) - open | ||
| - [CodeScan #767](./codescan/alert_767.md) - py/bind-socket-all-network-interfaces (error) - open | ||
| - [CodeScan #766](./codescan/alert_766.md) - py/bind-socket-all-network-interfaces (error) - open | ||
| - [CodeScan #765](./codescan/alert_765.md) - py/bind-socket-all-network-interfaces (error) - open | ||
|
|
||
| Total issues downloaded: 4 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #765: py/bind-socket-all-network-interfaces | ||
|
|
||
| - **State:** open | ||
| - **Severity:** error | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-05-21T04:27:05Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/765 | ||
|
|
||
| ## Description | ||
| Binding a socket to all network interfaces | ||
|
Comment on lines
+1
to
+10
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. [CRITICAL_BUG] Multiple code-scan alerts (alert_765/766/767) indicate 'bind-socket-all-network-interfaces' which is a high-risk issue (exposes services broadly). Instead of only recording the alert, include: (1) the affected source file(s) and line numbers; (2) recommended fix (bind to specific interface or use configuration to restrict address, avoid 0.0.0.0, and apply firewall rules); and (3) a change/PR reference that implements the fix. Make sure any network-facing services default to localhost or explicitly configured interfaces. # Code Scanning Alert #765: py/bind-socket-all-network-interfaces
- **State:** open
- **Severity:** error
- **Tool:** CodeQL
- **Created:** 2026-05-21T04:27:05Z
- **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/765
- **Affected file:** `lazyown/server/network.py`
- **Location:** line 142 (`server.bind(("0.0.0.0", port))`)
- **Proposed fix PR:** `refs/heads/fix-bind-all-interfaces-765`
## Description
Binding a socket to all network interfaces
## Recommended remediation
- Replace binding to all interfaces with a specific interface or a configurable bind address.
- Default to `127.0.0.1` for local-only control traffic.
- Document how to override the bind address via configuration for legitimate remote use.
### Example configuration-driven fix (illustrative)
```python
# lazyown/server/network.py
import os
def get_bind_host() -> str:
# Default to localhost; allow explicit override for controlled deployments
return os.getenv("LAZYOWN_BIND_HOST", "127.0.0.1")
...
bind_host = get_bind_host()
server.bind((bind_host, port)) |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #766: py/bind-socket-all-network-interfaces | ||
|
|
||
| - **State:** open | ||
| - **Severity:** error | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-05-21T04:27:05Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/766 | ||
|
|
||
| ## Description | ||
| Binding a socket to all network interfaces |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #767: py/bind-socket-all-network-interfaces | ||
|
|
||
| - **State:** open | ||
| - **Severity:** error | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-05-21T04:27:05Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/767 | ||
|
|
||
| ## Description | ||
| Binding a socket to all network interfaces |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #775: py/overly-large-range | ||
|
|
||
| - **State:** open | ||
| - **Severity:** warning | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-06-29T08:37:57Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/775 | ||
|
|
||
| ## Description | ||
| Overly permissive regular expression range |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #776: py/overly-large-range | ||
|
|
||
| - **State:** open | ||
| - **Severity:** warning | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-06-29T08:37:57Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/776 | ||
|
|
||
| ## Description | ||
| Overly permissive regular expression range |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #777: py/incomplete-url-substring-sanitization | ||
|
|
||
| - **State:** open | ||
| - **Severity:** warning | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-06-30T22:45:30Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/777 | ||
|
|
||
| ## Description | ||
| Incomplete URL substring sanitization | ||
|
Comment on lines
+1
to
+10
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. [VALIDATION] Several 'incomplete-url-substring-sanitization' alerts (alert_777..781) are recorded but lack remediation steps. Recommend updating these entries to explain correct handling: use urllib.parse / urljoin for canonicalization, strict validation of hostnames and schemes, avoid naive substring checks, and include unit tests for malicious URL inputs. Point to the exact code locations to make triage actionable. # Code Scanning Alert #777: py/incomplete-url-substring-sanitization
- **State:** open
- **Severity:** warning
- **Tool:** CodeQL
- **Created:** 2026-06-30T22:45:30Z
- **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/777
## Description
Incomplete URL substring sanitization. The application appears to validate or sanitize URLs using substring or prefix checks instead of robust URL parsing. This can allow crafted URLs (e.g. using different schemes, encoded characters, or subdomains) to bypass filters.
## Recommended Remediation
- Replace naive string/substring checks on URLs with `urllib.parse`.
- Canonicalize and validate URLs before use.
- Enforce an allow‑list of schemes (e.g. `http`, `https`) and trusted hostnames.
- Avoid relying on `startswith` or substring checks for security decisions.
### Example (conceptual fix)
```py
from urllib.parse import urlparse, urljoin
ALLOWED_SCHEMES = {"http", "https"}
ALLOWED_HOSTS = {"example.com", "api.example.com"}
def is_safe_redirect(target: str, host_url: str = "https://example.com") -> bool:
# Build absolute URL
absolute_target = urljoin(host_url, target)
parsed = urlparse(absolute_target)
if parsed.scheme not in ALLOWED_SCHEMES:
return False
if parsed.hostname not in ALLOWED_HOSTS:
return False
return TrueNext Steps
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #778: py/incomplete-url-substring-sanitization | ||
|
|
||
| - **State:** open | ||
| - **Severity:** warning | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-06-30T22:45:30Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/778 | ||
|
|
||
| ## Description | ||
| Incomplete URL substring sanitization |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #779: py/incomplete-url-substring-sanitization | ||
|
|
||
| - **State:** open | ||
| - **Severity:** warning | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-06-30T22:45:30Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/779 | ||
|
|
||
| ## Description | ||
| Incomplete URL substring sanitization |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #780: py/incomplete-url-substring-sanitization | ||
|
|
||
| - **State:** open | ||
| - **Severity:** warning | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-06-30T22:45:30Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/780 | ||
|
|
||
| ## Description | ||
| Incomplete URL substring sanitization |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Code Scanning Alert #781: py/incomplete-url-substring-sanitization | ||
|
|
||
| - **State:** open | ||
| - **Severity:** warning | ||
| - **Tool:** CodeQL | ||
| - **Created:** 2026-06-30T22:45:30Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/code-scanning/781 | ||
|
|
||
| ## Description | ||
| Incomplete URL substring sanitization |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Dependabot Alert #45: python-engineio | ||
|
|
||
| - **State:** open | ||
| - **Severity:** high | ||
| - **CVE:** CVE-2026-48809 | ||
| - **Created:** 2026-06-29T09:59:20Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/dependabot/45 | ||
|
|
||
| ## Summary | ||
| python-engineio has possible denial of service due to maximum payload size sometimes not being enforced | ||
|
|
||
| ## Description | ||
| ### Impact | ||
| There are two specific configurations of the python-engineio server in which the size of incoming messages is not checked before the messages are loaded into memory. An attacker can take advantage of these to cause unnecessary memory allocations in the python-engineio server. The two cases are: | ||
|
|
||
| - POST requests, when using ASGI with the long polling transport | ||
| - WebSocket messages, when using Aiohttp with the WebSocket transport | ||
|
|
||
| ### Patches | ||
| Version 4.13.2 addresses this issue as follows: | ||
|
|
||
| - ASGI severs now only load the body of incoming requests into memory after the client is confirmed to be known and authenticated, and the payload size is below the maximum allowed size. Requests that do not comply with these requirements are discarded. | ||
| - Aiohttp servers configure the maximum payload size in the underlying WebSocket layer from Aiohttp, so that large messages are discarded by Aiohttp before they are delivered to python-engineio. | ||
|
Comment on lines
+20
to
+23
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. [VALIDATION] The alert describes fixes in version 4.13.2 but doesn't give an explicit recommended action. Add a clear remediation line such as: 'Action: upgrade python-engineio to >= 4.13.2 and test ASGI/aiohttp stacks; update requirements.txt/PyPI pinned versions and rebuild images.' Also include a brief note about testing compatibility/behavior changes. # Dependabot Alert #45: python-engineio
- **State:** open
- **Severity:** high
- **CVE:** CVE-2026-48809
- **Created:** 2026-06-29T09:59:20Z
- **URL:** https://github.com/grisuno/LazyOwn/security/dependabot/45
## Summary
python-engineio has possible denial of service due to maximum payload size sometimes not being enforced
## Description
### Impact
There are two specific configurations of the python-engineio server in which the size of incoming messages is not checked before the messages are loaded into memory. An attacker can take advantage of these to cause unnecessary memory allocations in the python-engineio server. The two cases are:
- POST requests, when using ASGI with the long polling transport
- WebSocket messages, when using Aiohttp with the WebSocket transport
### Patches
Version 4.13.2 addresses this issue as follows:
- ASGI severs now only load the body of incoming requests into memory after the client is confirmed to be known and authenticated, and the payload size is below the maximum allowed size. Requests that do not comply with these requirements are discarded.
- Aiohttp servers configure the maximum payload size in the underlying WebSocket layer from Aiohttp, so that large messages are discarded by Aiohttp before they are delivered to python-engineio.
### Recommended action
- Upgrade all python-engineio dependencies to `>= 4.13.2` in `requirements.txt` and any pinned dependency files.
- Rebuild and redeploy application images/containers that include python-engineio.
- For ASGI long-polling deployments, validate that `max_http_buffer_size` (or equivalent) is explicitly configured and that authentication is enforced before large payloads are read.
- For aiohttp WebSocket deployments, verify that the WebSocket `max_msg_size` (or equivalent) is aligned with the expected maximum payload and that oversized payloads are rejected.
- Regression-test ASGI and aiohttp stacks for connection establishment, authentication, and large payload handling to detect any behavior changes introduced by the upgrade. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| # Dependabot Alert #46: python-engineio | ||
|
|
||
| - **State:** open | ||
| - **Severity:** high | ||
| - **CVE:** CVE-2026-48802 | ||
| - **Created:** 2026-06-29T09:59:21Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/dependabot/46 | ||
|
|
||
| ## Summary | ||
| python-engineio has unbound thread allocation that can cause denial of service | ||
|
|
||
| ## Description | ||
| ### Impact | ||
| An attacker can cause the creation of unnecessary background threads in the python-engineio server by exploiting the heartbeat mechanism, which launches a thread when a new connection is received, and when the client sends a PONG packet. | ||
|
|
||
| Note: this issue primarily affects synchronous servers. Asynchronous servers allocate background tasks instead of physical threads, which are lightweight and less likely to cause denial of service. However, the fix that was implemented was also applied to the asynchronous case. | ||
|
|
||
| ### Patches | ||
| Version 4.13.2 addresses this issue as follows: | ||
|
|
||
| - The initial background thread (or async task( for heartbeat management is only launched if a client passes authentication in the `connect` handler. | ||
| - The server now ensures that there is only one background heatbeat thread (or async task) per client at a given point in time. Out of sequence PONG packets are now discarded when an active heartbeat thread is already running. | ||
|
Comment on lines
+21
to
+22
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. [NITPICK] There are typos and a parenthesis mismatch in the remediation text: 'async task(' should be 'async task)' and 'heatbeat' should be 'heartbeat'. Also 'ASGI severs' -> 'ASGI servers'. Fix these to avoid confusion. 21- - The initial background thread (or async task) for heartbeat management is only launched if a client passes authentication in the `connect` handler.
22- - The server now ensures that there is only one background heartbeat thread (or async task) per client at a given point in time. Out of sequence PONG packets are now discarded when an active heartbeat thread is already running. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Dependabot Alert #47: python-socketio | ||
|
|
||
| - **State:** open | ||
| - **Severity:** high | ||
| - **CVE:** CVE-2026-48804 | ||
| - **Created:** 2026-06-29T09:59:21Z | ||
| - **URL:** https://github.com/grisuno/LazyOwn/security/dependabot/47 | ||
|
|
||
| ## Summary | ||
| python-socketio: Binary attachment accumulation can cause denial of service | ||
|
|
||
| ## Description | ||
| ### Impact | ||
| The python-socketio server stores binary `EVENT` and `ACK` messages in memory while it waits to receive their binary attachments. Once all the attachments are received, these messages are then processed. An attacker can submit a binary message and intentionally omit sending one or more of its attachments to cause the message along with the partial list of received attachments to stay in memory for a long time. | ||
|
|
||
| ### Patches | ||
| Version 5.16.2 takes the following measures to address this issue: | ||
| - Binary packets are only accepted from authenticated clients. | ||
| - When a client disconnects, the server checks if there is a partial binary message being held for the client and deletes it. | ||
|
Comment on lines
+17
to
+19
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. [VALIDATION] The patch description references fixes in 5.16.2 but there's no explicit 'Action' guidance. Add an explicit remediation recommendation: 'Upgrade python-socketio to >= 5.16.2, ensure binary packets are only accepted after authentication, and add unit/integration tests to validate that partial binary messages are cleaned up on disconnect.' ### Patches
Version 5.16.2 takes the following measures to address this issue:
- Binary packets are only accepted from authenticated clients.
- When a client disconnects, the server checks if there is a partial binary message being held for the client and deletes it.
### Recommended Action
Upgrade `python-socketio` to version **5.16.2 or later**, ensure that binary packets are only accepted after clients are authenticated, and add automated tests (unit and/or integration) to verify that partial binary messages are cleaned up correctly on client disconnect. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Issue #16: Fix code scanning alert - Information exposure through an exception | ||
|
|
||
| - **State:** closed | ||
| - **Created:** 2024-06-09T07:07:45Z | ||
| - **Updated:** 2024-06-09T07:12:42Z | ||
| - **Labels:** None | ||
|
|
||
| --- | ||
|
|
||
| <!-- Warning: The suggested title contains the alert rule name. This can expose security information. --> | ||
|
|
||
| Tracking issue for: | ||
| - [x] https://github.com/grisuno/LazyOwn/security/code-scanning/6 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Issue #17: Fix code scanning alert - Flask app is run in debug mode | ||
|
|
||
| - **State:** closed | ||
| - **Created:** 2024-06-09T07:08:21Z | ||
| - **Updated:** 2024-06-09T07:09:28Z | ||
| - **Labels:** None | ||
|
|
||
| --- | ||
|
|
||
| <!-- Warning: The suggested title contains the alert rule name. This can expose security information. --> | ||
|
|
||
| Tracking issue for: | ||
| - [x] https://github.com/grisuno/LazyOwn/security/code-scanning/5 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # Issue #30: Please remove ngrok as a tunneling option as this tool violates the terms of service | ||
|
|
||
| - **State:** closed | ||
| - **Created:** 2024-09-03T16:49:02Z | ||
| - **Updated:** 2024-09-05T05:06:42Z | ||
| - **Labels:** None | ||
|
|
||
| --- | ||
|
|
||
| PM for ngrok here. This tool directly violates the ngrok Terms of Service even when used for educational purposes only. We kindly request that ngrok be removed as an option in your tool. Please consider replacing it with other options [from this list](https://github.com/anderspitman/awesome-tunneling). | ||
|
|
||
| To learn more about how ngrok combats abuse, see https://ngrok.com/abuse and https://ngrok.com/tos . | ||
|
|
||
| - ngrok is not anonymous and can not be used to hide your identity. | ||
| - ngrok directly exposes your public IP address to anyone who sees the ngrok url you send them and in an http header. | ||
| - ngrok will ban your account if you use this tool. | ||
| - ngrok adds an interstitial page to all requests warning anyone viewing the page that the site is hosted by ngrok. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # Issue #84: Lazynmap failing to execute | ||
|
|
||
| - **State:** closed | ||
| - **Created:** 2025-01-31T17:03:11Z | ||
| - **Updated:** 2025-02-05T03:16:37Z | ||
| - **Labels:** None | ||
|
|
||
| --- | ||
|
|
||
| **Describe the bug** | ||
| When executing the `run lazynmap` command, an error is generated indicating that `No such file or directory` is present in /home/USER/LazyOwn/sessions/logs/command_/home/USER/LazyOwn/modules/lazynmap.shoutputBigBang.htb.txt | ||
|
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. [CRITICAL_BUG] The reported error message includes an absolute filesystem path with a username-like placeholder (/home/USER/...). When archiving issues or publishing snapshots, redact or generalize absolute paths and any PII to avoid leaking environment-specific information. **Describe the bug**
When executing the `run lazynmap` command, an error is generated indicating that `No such file or directory` is present in a user-specific LazyOwn log path (redacted for privacy). |
||
|
|
||
| **To Reproduce** | ||
| Steps to reproduce the behavior: | ||
| 1. Assign RHOST IP | ||
| 2. Execute `run lazynmap` | ||
|
|
||
|
|
||
| **Expected behavior** | ||
| LazyNmap should run successfully | ||
|
|
||
| **Screenshots** | ||
| N/A | ||
|
|
||
| **Desktop (please complete the following information):** | ||
| - OS: Ubuntu 24.04.1 LTS | ||
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.
[CRITICAL_BUG] The repository description (line 3) promotes a RedTeam/APT framework with rootkits and backdoors. Publishing or distributing such content publicly can create legal, policy and platform-compliance issues and may facilitate abuse. Before merging: either remove or reword the description to clearly state defensive/research intent, or keep this snapshot in a private/internal location. Add explicit legal/acceptable-use notes and consult your legal/compliance team.