mirror of https://github.com/jumpserver/jumpserver
fix: 过滤 localhost 注入问题
parent
854e0f5fe0
commit
011535a02a
|
@ -10,7 +10,7 @@ __all__ = ['JMSInventory']
|
|||
|
||||
class JMSInventory:
|
||||
def __init__(self, assets, account_policy='privileged_first',
|
||||
account_prefer='root,Administrator', host_callback=None):
|
||||
account_prefer='root,Administrator', host_callback=None, exclude_localhost=False):
|
||||
"""
|
||||
:param assets:
|
||||
:param account_prefer: account username name if not set use account_policy
|
||||
|
@ -21,6 +21,7 @@ class JMSInventory:
|
|||
self.account_policy = account_policy
|
||||
self.host_callback = host_callback
|
||||
self.exclude_hosts = {}
|
||||
self.exclude_localhost = exclude_localhost
|
||||
|
||||
@staticmethod
|
||||
def clean_assets(assets):
|
||||
|
@ -207,6 +208,8 @@ class JMSInventory:
|
|||
for host in hosts:
|
||||
name = host.pop('name')
|
||||
data['all']['hosts'][name] = host
|
||||
if self.exclude_localhost and data['all']['hosts'].__contains__('localhost'):
|
||||
data['all']['hosts'].update({'localhost': {'ansible_host': '255.255.255.255'}})
|
||||
return data
|
||||
|
||||
def write_to_file(self, path):
|
||||
|
|
|
@ -295,10 +295,20 @@ class JobExecution(JMSOrgBaseModel):
|
|||
task_id = current_task.request.root_id
|
||||
self.task_id = task_id
|
||||
|
||||
def check_danger_keywords(self):
|
||||
lines = self.job.playbook.check_dangerous_keywords()
|
||||
if len(lines) > 0:
|
||||
for line in lines:
|
||||
print('\033[31mThe {} line of the file \'{}\' contains the '
|
||||
'dangerous keyword \'{}\'\033[0m'.format(line['line'], line['file'], line['keyword']))
|
||||
raise Exception("Playbook contains dangerous keywords")
|
||||
|
||||
def start(self, **kwargs):
|
||||
self.date_start = timezone.now()
|
||||
self.set_celery_id()
|
||||
self.save()
|
||||
if self.job.type == 'playbook':
|
||||
self.check_danger_keywords()
|
||||
runner = self.get_runner()
|
||||
try:
|
||||
cb = runner.run(**kwargs)
|
||||
|
|
|
@ -9,6 +9,13 @@ from ops.const import CreateMethods
|
|||
from ops.exception import PlaybookNoValidEntry
|
||||
from orgs.mixins.models import JMSOrgBaseModel
|
||||
|
||||
dangerous_keywords = (
|
||||
'delegate_to:localhost',
|
||||
'delegate_to:127.0.0.1',
|
||||
'local_action',
|
||||
'connection:local',
|
||||
)
|
||||
|
||||
|
||||
class Playbook(JMSOrgBaseModel):
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
|
@ -20,6 +27,27 @@ class Playbook(JMSOrgBaseModel):
|
|||
verbose_name=_('CreateMethod'))
|
||||
vcs_url = models.CharField(max_length=1024, default='', verbose_name=_('VCS URL'), null=True, blank=True)
|
||||
|
||||
def check_dangerous_keywords(self):
|
||||
result = []
|
||||
for root, dirs, files in os.walk(self.work_dir):
|
||||
for f in files:
|
||||
if str(f).endswith('.yml') or str(f).endswith('.yaml'):
|
||||
lines = self.search_keywords(os.path.join(root, f))
|
||||
if len(lines) > 0:
|
||||
for line in lines:
|
||||
result.append({'file': f, 'line': line[0], 'keyword': line[1]})
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def search_keywords(file):
|
||||
result = []
|
||||
with open(file, 'r') as f:
|
||||
for line_num, line in enumerate(f):
|
||||
for keyword in dangerous_keywords:
|
||||
if keyword in line.replace(' ', ''):
|
||||
result.append((line_num, keyword))
|
||||
return result
|
||||
|
||||
@property
|
||||
def entry(self):
|
||||
work_dir = self.work_dir
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import uuid
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
|
@ -14,6 +16,14 @@ class JobSerializer(BulkOrgResourceModelSerializer, PeriodTaskSerializerMixin):
|
|||
run_after_save = serializers.BooleanField(label=_("Run after save"), default=False, required=False)
|
||||
nodes = serializers.ListField(required=False, child=serializers.CharField())
|
||||
date_last_run = serializers.DateTimeField(label=_('Date last run'), read_only=True)
|
||||
name = serializers.CharField(label=_('Name'), max_length=128, allow_blank=True, required=False)
|
||||
|
||||
def to_internal_value(self, data):
|
||||
instant = data.get('instant', False)
|
||||
if instant:
|
||||
_uid = str(uuid.uuid4()).split('-')[-1]
|
||||
data['name'] = f'job-{_uid}'
|
||||
return super().to_internal_value(data)
|
||||
|
||||
def get_request_user(self):
|
||||
request = self.context.get('request')
|
||||
|
|
Loading…
Reference in New Issue