2 Commits

Author SHA1 Message Date
e48b0c90f3 Potential fix for code scanning alert no. 3: DOM text reinterpreted as HTML
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-05-18 23:37:40 +02:00
9d8322064b Potential fix for code scanning alert no. 1: URL redirection from remote source
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-05-18 23:35:18 +02:00
10 changed files with 70 additions and 168 deletions

View File

@ -1,7 +1,5 @@
#!/usr/bin/env bash
export UV_LINK_MODE=copy;
sudo apt update
sudo apt full-upgrade -y
sudo apt autoremove -y;
@ -74,7 +72,6 @@ fi
if [ -f ~/.cache/oh-my-posh-completion.bash ]; then
source ~/.cache/oh-my-posh-completion.bash
fi
export UV_LINK_MODE=copy;
EOF

View File

@ -6,17 +6,17 @@
version: 2
updates:
- package-ecosystem: "devcontainers"
directory: "/"
- package-ecosystem: devcontainers
directory: /
schedule:
interval: "weekly"
day: "tuesday"
time: "03:00"
timezone: "Europe/Amsterdam"
- package-ecosystem: "uv"
directory: "/"
interval: weekly
day: tuesday
time: 03:00
timezone: Europe/Amsterdam
- package-ecosystem: uv
directory: /
schedule:
interval: "weekly"
day: "tuesday"
time: "03:00"
timezone: "Europe/Amsterdam"
interval: weekly
day: tuesday
time: 03:00
timezone: Europe/Amsterdam

View File

@ -1,51 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# Bandit is a security linter designed to find common security issues in Python code.
# This action will run Bandit on your codebase.
# The results of the scan will be found under the Security tab of your repository.
# https://github.com/marketplace/actions/bandit-scan is ISC licensed, by abirismyname
# https://pypi.org/project/bandit/ is Apache v2.0 licensed, by PyCQA
name: Bandit
on:
push:
branches: ["master"]
pull_request:
# The branches below must be a subset of the branches above
branches: ["master"]
schedule:
- cron: "37 3 * * 3"
jobs:
bandit:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Bandit Scan
uses: shundor/python-bandit-scan@ab1d87dfccc5a0ffab88be3aaac6ffe35c10d6cd
with: # optional arguments
# exit with 0, even with results found
exit_zero: true # optional, default is DEFAULT
# Github token of the repository (automatically created by Github)
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information.
# File or directory to run bandit on
# path: # optional, default is .
# Report only issues of a given severity level or higher. Can be LOW, MEDIUM or HIGH. Default is UNDEFINED (everything)
# level: # optional, default is UNDEFINED
# Report only issues of a given confidence level or higher. Can be LOW, MEDIUM or HIGH. Default is UNDEFINED (everything)
# confidence: # optional, default is UNDEFINED
# comma-separated list of paths (glob patterns supported) to exclude from scan (note that these are in addition to the excluded paths provided in the config file) (default: .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg)
# excluded_paths: # optional, default is DEFAULT
# comma-separated list of test IDs to skip
# skips: # optional, default is DEFAULT
# path to a .bandit file that supplies command line arguments
# ini_path: # optional, default is DEFAULT

View File

@ -1,61 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow checks out code, performs a Codacy security scan
# and integrates the results with the
# GitHub Advanced Security code scanning feature. For more information on
# the Codacy security scan action usage and parameters, see
# https://github.com/codacy/codacy-analysis-cli-action.
# For more information on Codacy Analysis CLI in general, see
# https://github.com/codacy/codacy-analysis-cli.
name: Codacy Security Scan
on:
push:
branches: ["master"]
pull_request:
# The branches below must be a subset of the branches above
branches: ["master"]
schedule:
- cron: "36 10 * * 3"
permissions:
contents: read
jobs:
codacy-security-scan:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
name: Codacy Security Scan
runs-on: ubuntu-latest
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout code
uses: actions/checkout@v4
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI
uses: codacy/codacy-analysis-cli-action@d840f886c4bd4edc059706d09c6a1586111c540b
with:
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
# You can also omit the token and run the tools that support default configurations
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
verbose: true
output: results.sarif
format: sarif
# Adjust severity of non-security issues
gh-code-scanning-compat: true
# Force 0 exit code to allow SARIF file generation
# This will handover control about PR rejection to the GitHub side
max-allowed-issues: 2147483647
# Upload the SARIF file generated in the previous step
- name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif

View File

@ -1,15 +1,8 @@
# default_install_hook_types:
# - pre-commit
# - post-checkout
# - post-merge
# - post-rewrite
ci:
skip: [django-check, django-check-migrations]
default_language_version:
node: 22.15.1
python: python3.13
default_install_hook_types:
- pre-commit
- post-checkout
- post-merge
- post-rewrite
repos:
- repo: https://github.com/adamchainz/django-upgrade
@ -41,21 +34,28 @@ repos:
- id: mixed-line-ending
args: [--fix=lf]
- repo: local
# - repo: https://github.com/psf/black
# rev: 22.10.0
# hooks:
# - id: black
# # HTML/Django template linting
# - repo: https://github.com/rtts/djhtml
# rev: 3.0.7
# hooks:
# - id: djhtml
# entry: djhtml --tabwidth 4
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
hooks:
- id: prettier-jinja
name: Prettier Jinja
language: node
- id: prettier
types_or: [javascript, jsx, ts, tsx, css, scss, html, json, yaml, markdown]
additional_dependencies:
- prettier
- prettier-plugin-jinja-template
types_or: [html, jinja]
entry: npx prettier --plugin=prettier-plugin-jinja-template --parser=jinja-template --write
- id: prettier-all
name: Prettier All
language: node
types_or: [javascript, jsx, ts, tsx, css, scss, json, yaml, markdown]
entry: npx prettier --write
# types_or: [javascript, jsx, ts, tsx, css, scss, json, yaml, markdown]
# exclude: '.*\.html$'
- repo: https://github.com/DavidAnson/markdownlint-cli2
rev: v0.18.1
@ -77,19 +77,17 @@ repos:
- id: django-check
name: Django Check
entry: uv run python dashboard_project/manage.py check
language: python
language: system
pass_filenames: false
types: [python]
always_run: true
additional_dependencies: [uv]
- id: django-check-migrations
name: Django Check Migrations
entry: uv run python dashboard_project/manage.py makemigrations --check --dry-run
language: python
language: system
pass_filenames: false
types: [python]
additional_dependencies: [uv]
# Security checks
- repo: https://github.com/pycqa/bandit
@ -97,7 +95,7 @@ repos:
hooks:
- id: bandit
args: [-c, pyproject.toml, -r, dashboard_project]
# additional_dependencies: ["bandit[toml]"]
additional_dependencies: ["bandit[toml]"]
# # Type checking
# - repo: https://github.com/pre-commit/mirrors-mypy

View File

@ -104,10 +104,10 @@ run-redis:
# Start all development services (web, redis, celery, celery-beat)
run-all:
foreman start
procfile:
foreman start
make run-redis & \
make run & \
make celery & \
make celery-beat
# Test Celery task
test-celery:
@ -122,3 +122,6 @@ init-data-integration:
# Setup development environment
setup-dev: venv install-dev migrate create_default_datasource
@echo "Development environment setup complete"
procfile:
foreman start

View File

@ -2,6 +2,7 @@ from django.contrib import messages
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import login_required, user_passes_test
from django.shortcuts import get_object_or_404, redirect
from django.utils.http import url_has_allowed_host_and_scheme
from .models import ExternalDataSource
from .tasks import periodic_fetch_chat_data, refresh_specific_source
@ -36,7 +37,10 @@ def manual_data_refresh(request):
)
except Exception as e:
messages.error(request, f"Failed to refresh data: {e}")
return redirect(request.headers.get("referer", "dashboard")) # Redirect to previous page or dashboard
referer = request.headers.get("referer", "")
if url_has_allowed_host_and_scheme(referer, allowed_hosts=None):
return redirect(referer)
return redirect("dashboard") # Redirect to a safe default
@staff_member_required
@ -51,4 +55,7 @@ def refresh_specific_datasource(request, source_id):
except Exception as e:
messages.error(request, f"Failed to refresh data source {source.name}: {e}")
return redirect(request.headers.get("referer", "/admin/data_integration/externaldatasource/"))
referer = request.headers.get("referer", "")
if url_has_allowed_host_and_scheme(referer, allowed_hosts=None):
return redirect(referer)
return redirect("/admin/data_integration/externaldatasource/") # Redirect to a safe default

View File

@ -299,6 +299,15 @@
});
function createToast(messageText, messageTags) {
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
let toastClass = "";
let autohide = true;
let delay = 5000;
@ -329,7 +338,7 @@
<button type="button" class="btn-close ${toastClass.includes("text-white") ? "btn-close-white" : ""}" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
${messageText}
${escapeHtml(messageText)}
</div>
</div>`;

View File

@ -392,9 +392,9 @@ ruff==0.11.10 \
--hash=sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523 \
--hash=sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1 \
--hash=sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2
setuptools==80.9.0 \
--hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \
--hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c
setuptools==80.7.1 \
--hash=sha256:ca5cc1069b85dc23070a6628e6bcecb3292acac802399c7f8edc0100619f9009 \
--hash=sha256:f6ffc5f0142b1bd8d0ca94ee91b30c0ca862ffd50826da1ea85258a06fd94552
# via pbr
six==1.17.0 \
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \

6
uv.lock generated
View File

@ -905,11 +905,11 @@ wheels = [
[[package]]
name = "setuptools"
version = "80.9.0"
version = "80.7.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" }
sdist = { url = "https://files.pythonhosted.org/packages/9e/8b/dc1773e8e5d07fd27c1632c45c1de856ac3dbf09c0147f782ca6d990cf15/setuptools-80.7.1.tar.gz", hash = "sha256:f6ffc5f0142b1bd8d0ca94ee91b30c0ca862ffd50826da1ea85258a06fd94552", size = 1319188, upload-time = "2025-05-15T02:41:00.955Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" },
{ url = "https://files.pythonhosted.org/packages/a1/18/0e835c3a557dc5faffc8f91092f62fc337c1dab1066715842e7a4b318ec4/setuptools-80.7.1-py3-none-any.whl", hash = "sha256:ca5cc1069b85dc23070a6628e6bcecb3292acac802399c7f8edc0100619f9009", size = 1200776, upload-time = "2025-05-15T02:40:58.887Z" },
]
[[package]]