perf: some risk example file path

pull/15272/head
ibuler 2025-07-30 14:49:12 +08:00 committed by Bryan
parent 1406437d4e
commit 4e33b5b478
17 changed files with 83 additions and 62 deletions

View File

@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _
from common.db.fields import JSONManyToManyField
from common.db.models import JMSBaseModel
from common.utils import contains_ip
from common.utils.time_period import contains_time_period
from common.utils.timezone import contains_time_period
from orgs.mixins.models import OrgModelMixin, OrgManager
from ..const import ActionChoices

View File

@ -10,10 +10,12 @@ from django.core.files.storage import default_storage
from django.db import transaction
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.utils._os import safe_join
from common.const.crontab import CRONTAB_AT_AM_TWO
from common.storage.ftp_file import FTPFileStorageHandler
from common.utils import get_log_keep_day, get_logger
from common.utils.safe import safe_run_cmd
from ops.celery.decorator import register_as_period_task
from ops.models import CeleryTaskExecution
from orgs.utils import tmp_to_root_org
@ -57,14 +59,12 @@ def clean_ftp_log_period():
now = timezone.now()
days = get_log_keep_day('FTP_LOG_KEEP_DAYS')
expired_day = now - datetime.timedelta(days=days)
file_store_dir = os.path.join(default_storage.base_location, FTPLog.upload_to)
file_store_dir = safe_join(default_storage.base_location, FTPLog.upload_to)
FTPLog.objects.filter(date_start__lt=expired_day).delete()
command = "find %s -mtime +%s -type f -exec rm -f {} \\;" % (
file_store_dir, days
)
subprocess.call(command, shell=True)
command = "find %s -type d -empty -delete;" % file_store_dir
subprocess.call(command, shell=True)
command = "find %s -mtime +%s -type f -exec rm -f {} \\;"
safe_run_cmd(command, (file_store_dir, days))
command = "find %s -type d -empty -delete;"
safe_run_cmd(command, (file_store_dir,))
logger.info("Clean FTP file done")
@ -76,12 +76,11 @@ def clean_celery_tasks_period():
tasks.delete()
tasks = CeleryTaskExecution.objects.filter(date_start__isnull=True)
tasks.delete()
command = "find %s -mtime +%s -name '*.log' -type f -exec rm -f {} \\;" % (
settings.CELERY_LOG_DIR, expire_days
)
subprocess.call(command, shell=True)
command = "echo > {}".format(os.path.join(settings.LOG_DIR, 'celery.log'))
subprocess.call(command, shell=True)
command = "find %s -mtime +%s -name '*.log' -type f -exec rm -f {} \\;"
safe_run_cmd(command, (settings.CELERY_LOG_DIR, expire_days))
celery_log_path = safe_join(settings.LOG_DIR, 'celery.log')
command = "echo > {}".format(celery_log_path)
safe_run_cmd(command, (celery_log_path,))
def batch_delete(queryset, batch_size=3000):
@ -119,15 +118,15 @@ def clean_expired_session_period():
expired_sessions = Session.objects.filter(date_start__lt=expire_date)
timestamp = expire_date.timestamp()
expired_commands = Command.objects.filter(timestamp__lt=timestamp)
replay_dir = os.path.join(default_storage.base_location, 'replay')
replay_dir = safe_join(default_storage.base_location, 'replay')
batch_delete(expired_sessions)
logger.info("Clean session item done")
batch_delete(expired_commands)
logger.info("Clean session command done")
remove_files_by_days(replay_dir, days)
command = "find %s -type d -empty -delete;" % replay_dir
subprocess.call(command, shell=True)
command = "find %s -type d -empty -delete;"
safe_run_cmd(command, (replay_dir,))
logger.info("Clean session replay done")

View File

@ -0,0 +1,9 @@
import re
import subprocess
import shlex
def safe_run_cmd(cmd_str, cmd_args=(), shell=True):
cmd_args = [shlex.quote(arg) for arg in cmd_args]
cmd = cmd_str % tuple(cmd_args)
return subprocess.run(cmd, shell=shell)

View File

@ -1,24 +0,0 @@
from common.utils.timezone import local_now
def contains_time_period(time_periods, ctime=None):
"""
time_periods: [{"id": 1, "value": "00:00~07:30、10:00~13:00"}, {"id": 2, "value": "00:00~00:00"}]
"""
if not time_periods:
return None
if ctime is None:
ctime = local_now()
current_time = ctime.strftime('%H:%M')
today_time_period = next(filter(lambda x: str(x['id']) == local_now().strftime("%w"), time_periods))
today_time_period = today_time_period['value']
if not today_time_period:
return False
for time in today_time_period.split(''):
start, end = time.split('~')
end = "24:00" if end == "00:00" else end
if start <= current_time <= end:
return True
return False

View File

@ -57,6 +57,29 @@ def is_date_more_than(d1, d2, threshold='1d'):
return d1 - d2 > delta
def contains_time_period(time_periods, ctime=None):
"""
time_periods: [{"id": 1, "value": "00:00~07:30、10:00~13:00"}, {"id": 2, "value": "00:00~00:00"}]
"""
if not time_periods:
return None
if ctime is None:
ctime = local_now()
current_time = ctime.strftime('%H:%M')
today_time_period = next(filter(lambda x: str(x['id']) == local_now().strftime("%w"), time_periods))
today_time_period = today_time_period['value']
if not today_time_period:
return False
for time in today_time_period.split(''):
start, end = time.split('~')
end = "24:00" if end == "00:00" else end
if start <= current_time <= end:
return True
return False
_rest_dt_field = DateTimeField()
dt_parser = _rest_dt_field.to_internal_value
dt_formatter = _rest_dt_field.to_representation

View File

@ -616,7 +616,7 @@
"Gateway": "Gateway",
"GatewayCreate": "Create gateway",
"GatewayList": "Gateways",
"GatewayPlatformHelpText": "Only platforms with names starting with Gateway can be used as gateways.",
"GatewayPlatformHelpText": "Only platforms with names starting with 'Gateway' can be used as gateways.",
"GatewayUpdate": "Update the gateway",
"General": "General",
"GeneralAccounts": "General accounts",

View File

@ -580,6 +580,10 @@
"FaviconTip": "提示:网站图标(建议图片大小为: 16px*16px",
"Features": "功能设置",
"FeiShu": "飞书",
"PasskeySummary": "无密码生物识别认证",
"Common": "通用",
"SSO": "单点登录",
"IdP": "身份提供者",
"FeiShuOAuth": "飞书认证",
"FeiShuTest": "测试",
"FieldRequiredError": "此字段是必填项",

View File

@ -1,9 +1,9 @@
# ~*~ coding: utf-8 ~*~
path_perms_map = {
'xpack': '*',
'settings': '*',
'img': '*',
'xpack': 'none',
'settings': 'none',
'img': 'none',
'replay': 'terminal.view_sessionreplay',
'applets': 'terminal.view_applet',
'virtual_apps': 'terminal.view_virtualapp',
@ -23,7 +23,8 @@ def allow_access(private_file):
return False
if not path_perm:
return False
if path_perm == '*' or request.user.has_perms([path_perm]):
if path_perm == 'none' or request.user.has_perms([path_perm]):
# 不需要权限检查,任何人都可以访问
return True
if path_perm == 'default':
return request.user.is_authenticated and request.user.is_staff

View File

@ -87,15 +87,23 @@ ALLOWED_DOMAINS.extend(DEBUG_HOST_PORTS)
# for host in ALLOWED_DOMAINS:
# print(' - ' + host.lstrip('.'))
ALLOWED_HOSTS = ['*']
ALLOWED_HOSTS = []
# https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS
CSRF_TRUSTED_ORIGINS = []
for host_port in ALLOWED_DOMAINS:
origin = host_port.strip('.')
if origin.startswith('http'):
CSRF_TRUSTED_ORIGINS.append(origin)
if not origin:
continue
if origin.startswith('http'):
origin = origin.replace('http://', '').replace('https://', '')
host = origin.split(':')[0]
if host not in ALLOWED_HOSTS:
ALLOWED_HOSTS.append(host)
is_local_origin = origin.split(':')[0] in DEBUG_HOSTS
for schema in ['https', 'http']:
if is_local_origin and schema == 'https':

View File

@ -16,10 +16,11 @@ class RBACBackend(JMSBaseAuthBackend):
return False
def has_perm(self, user_obj, perm, obj=None):
# 扫描软件对 * 毕竟敏感,所以改成 none, 虽说这个 * 是我们自定义的标识
if perm == 'none':
return True
if not user_obj.is_active or not perm:
raise PermissionDenied()
if perm == '*':
return True
if isinstance(perm, str):
perm_set = set(i.strip() for i in perm.split('|'))
elif isinstance(perm, (list, tuple, set)):

View File

@ -16,10 +16,10 @@ class RBACPermission(permissions.DjangoModelPermissions):
('bulk_update', '%(app_label)s.change_%(model_name)s'),
('partial_bulk_update', '%(app_label)s.change_%(model_name)s'),
('bulk_destroy', '%(app_label)s.delete_%(model_name)s'),
('render_to_json', '*'),
('metadata', '*'),
('render_to_json', 'none'),
('metadata', 'none'),
('GET', '%(app_label)s.view_%(model_name)s'),
('OPTIONS', '*'),
('OPTIONS', 'none'),
('HEAD', '%(app_label)s.view_%(model_name)s'),
('POST', '%(app_label)s.add_%(model_name)s'),
('PUT', '%(app_label)s.change_%(model_name)s'),