Skip to content
This repository was archived by the owner on Apr 20, 2022. It is now read-only.

Commit 89420d3

Browse files
authored
Merge pull request #205 from luzhongyang/main
fix sca url bug
2 parents 6e38f98 + 381096c commit 89420d3

File tree

10 files changed

+247
-78
lines changed

10 files changed

+247
-78
lines changed

AgentServer/settings.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
'rest_framework.authtoken',
4747
'dongtai',
4848
'apiserver',
49+
'sca',
4950
'drf_spectacular'
5051
]
5152

@@ -167,6 +168,9 @@
167168
ENGINE_URL = config.get("engine", "url")
168169
HEALTH_ENGINE_URL = urljoin(ENGINE_URL, "/api/engine/health")
169170
BASE_ENGINE_URL = config.get("engine", "url") + '/api/engine/run?method_pool_id={id}'
171+
SCA_ENGINE_URL = config.get("engine","url") + '/api/engine/sca?agent_id={agent_id}' \
172+
+ '&package_path={package_path}&package_signature={package_signature}' \
173+
+ '&package_name={package_name}&package_algorithm={package_algorithm}'
170174
REPLAY_ENGINE_URL = config.get("engine", "url") + '/api/engine/run?method_pool_id={id}&model=replay'
171175

172176
LOGGING = {
@@ -194,7 +198,7 @@
194198
'backupCount': 5,
195199
'maxBytes': 1024 * 1024 * 10,
196200
'formatter': 'verbose',
197-
'encoding':'utf8',
201+
'encoding': 'utf8',
198202
},
199203
},
200204
'loggers': {
@@ -231,9 +235,5 @@
231235
IGNORE = 4
232236
SOLVED = 5
233237

234-
# SCA_URL
235-
SCA_URL = config.get("sca", 'url')
236-
237238
if os.getenv('environment', None) == 'DEV' or os.getenv('PYTHONAGENT', None) == 'TRUE':
238-
MIDDLEWARE.append('dongtai_agent_python.middlewares.django_middleware.FireMiddleware')
239-
239+
MIDDLEWARE.append('dongtai_agent_python.middlewares.django_middleware.FireMiddleware')

AgentServer/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
urlpatterns = [
2323
path('api/v1/', include('apiserver.urls'), name='OpenAPI'),
24+
path('sca/v1/', include('sca.urls'), name='ScaAPI'),
2425
]
2526

2627
if settings.DEBUG:

apiserver/report/handler/sca_handler.py

Lines changed: 18 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -35,79 +35,28 @@ def parse(self):
3535
self.package_name = self.detail.get('packageName')
3636
self.package_algorithm = self.detail.get('packageAlgorithm')
3737

38+
@staticmethod
39+
def send_to_engine(agent_id, package_path, package_signature, package_name, package_algorithm):
40+
try:
41+
logger.info(f'[+] send sca package [{agent_id} {package_path} {package_signature} {package_name} {package_algorithm}] to engine')
42+
requests.get(
43+
url=settings.SCA_ENGINE_URL.format(
44+
agent_id=agent_id,
45+
package_path=package_path,
46+
package_signature=package_signature,
47+
package_name=package_name,
48+
package_algorithm=package_algorithm,
49+
)
50+
)
51+
except Exception as e:
52+
logger.info(f'[-] Failure: sca package [{agent_id} {package_path} {package_signature} {package_name} {package_algorithm}], Error: {e}')
53+
3854
def save(self):
3955
if all([self.agent_id, self.package_path, self.package_name]) is False:
4056
logger.warning(_("Data is incomplete, data: {}").format(json.dumps(self.report)))
4157
else:
42-
search_query = ""
43-
if self.agent.language == "JAVA":
44-
version = self.package_name.split('/')[-1].replace('.jar', '').split('-')[-1]
45-
search_query = "hash=" + self.package_signature
46-
elif self.agent.language == "PYTHON":
47-
# @todo agent上报版本 or 捕获全量pip库
48-
version = self.package_name.split('/')[-1].split('-')[-1]
49-
name = self.package_name.replace("-" + version, "")
50-
search_query = "ecosystem={}&name={}&version={}".format("PyPI", name, version)
51-
if search_query != "":
52-
package_name = self.package_name
53-
level = 'info'
54-
try:
55-
url = settings.SCA_URL + "/api/package_vul/?" + search_query
56-
resp = requests.get(url=url)
57-
resp = json.loads(resp.content)
58-
maven_model = resp.get("data", {}).get("package", {})
59-
if maven_model is None:
60-
maven_model = {}
61-
vul_list = resp.get("data", {}).get("vul_list", {})
62-
package_name = maven_model.get('aql', self.package_name)
63-
version = maven_model.get('version', version)
64-
vul_count = len(vul_list)
65-
levels = []
66-
for vul in vul_list:
67-
_level = vul.get("vul_package", {}).get("severity", "none")
68-
if _level and _level not in levels:
69-
levels.append(_level)
70-
if len(levels) > 0:
71-
levels = [_['vul_level'] for _ in levels]
72-
if 'high' in levels:
73-
level = 'high'
74-
elif 'high' in levels:
75-
level = 'high'
76-
elif 'medium' in levels:
77-
level = 'medium'
78-
elif 'low' in levels:
79-
level = 'low'
80-
else:
81-
level = 'info'
82-
83-
except Exception as e:
84-
logger.info("get package_vul failed:{}".format(e))
85-
86-
try:
87-
level = IastVulLevel.objects.get(name=level)
88-
current_version_agents = self.get_project_agents(self.agent)
89-
asset_count = 0
90-
if current_version_agents:
91-
asset_count = Asset.objects.values("id").filter(signature_value=self.package_signature,
92-
agent__in=current_version_agents).count()
93-
94-
if asset_count == 0:
95-
Asset.objects.create(
96-
package_name=package_name,
97-
package_path=self.package_path,
98-
signature_algorithm=self.package_algorithm,
99-
signature_value=self.package_signature,
100-
dt=time.time(),
101-
version=version,
102-
level=level,
103-
vul_count=vul_count,
104-
agent=self.agent
105-
)
106-
project = IastProject.objects.filter(pk=self.agent.bind_project_id).first()
107-
if project:
108-
project.update_latest()
109-
except Exception as e:
110-
logger.error(_('SCA data resolution failed, reasons: {}').format(e))
58+
# post to dongtai engine async deal
59+
ScaHandler.send_to_engine(self.agent_id, self.package_path, self.package_signature, self.package_name, self.package_algorithm)
11160

11261
@ReportHandler.register(const.REPORT_SCA + 1)
11362
class ScaBulkHandler(ScaHandler):

conf/config.ini.example

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,3 @@ from_addr = from_add
2222
ssl = ssl
2323
cc_addr = cc_addr
2424

25-
[sca]
26-
url = http://52.80.75.225:8000
27-

sca/__init__.py

Whitespace-only changes.

sca/apps.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.apps import AppConfig
2+
3+
4+
class ScaConfig(AppConfig):
5+
name = 'sca'

sca/models.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from django.db import models
2+
3+
# Create your models here.
4+
5+
from django.db import models
6+
7+
8+
class Package(models.Model):
9+
aql = models.CharField(max_length=255, blank=True, null=True)
10+
hash = models.CharField(max_length=255, blank=True, null=True)
11+
ecosystem = models.CharField(max_length=50, blank=True, null=True)
12+
name = models.CharField(max_length=255, blank=True, null=True)
13+
version = models.CharField(max_length=255, blank=True, null=True)
14+
license = models.CharField(max_length=50, blank=True, null=True)
15+
16+
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
17+
updated_at = models.DateTimeField(auto_now=True, blank=True, null=True)
18+
19+
class Meta:
20+
db_table = 'sca2_package'
21+
22+
23+
class Vul(models.Model):
24+
id = models.CharField(primary_key=True, max_length=50)
25+
summary = models.CharField(max_length=255, blank=True, null=True)
26+
details = models.TextField(blank=True, null=True)
27+
aliases = models.JSONField(blank=True, null=True)
28+
modified = models.DateTimeField(blank=True, null=True)
29+
published = models.DateTimeField(blank=True, null=True)
30+
withdrawn = models.DateTimeField(blank=True, null=True)
31+
references = models.JSONField(null=True)
32+
33+
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
34+
updated_at = models.DateTimeField(auto_now=True, blank=True, null=True)
35+
36+
class Meta:
37+
db_table = 'sca2_vul'
38+
39+
40+
class VulPackage(models.Model):
41+
vul_id = models.CharField(max_length=50, blank=True, null=True)
42+
ecosystem = models.CharField(max_length=255, blank=True, null=True)
43+
name = models.CharField(max_length=255, blank=True, null=True)
44+
cwe_ids = models.JSONField(blank=True, null=True)
45+
ghsa = models.CharField(max_length=255, blank=True, null=True)
46+
cvss_vector = models.CharField(max_length=255, blank=True, null=True)
47+
cvss_score = models.FloatField(default=0, blank=True, null=True)
48+
source = models.CharField(max_length=255, blank=True, null=True)
49+
severity = models.CharField(max_length=50, blank=True, null=True)
50+
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
51+
updated_at = models.DateTimeField(auto_now=True, blank=True, null=True)
52+
53+
class Meta:
54+
db_table = 'sca2_vul_package'
55+
56+
57+
class VulPackageRange(models.Model):
58+
vul_package_id = models.IntegerField(max_length=11, blank=True, null=True)
59+
ecosystem = models.CharField(max_length=255, blank=True, null=True)
60+
name = models.CharField(max_length=255, blank=True, null=True)
61+
type = models.CharField(max_length=50, blank=True, null=True)
62+
introduced = models.CharField(max_length=50, blank=True, null=True)
63+
fixed = models.CharField(max_length=50, blank=True, null=True)
64+
65+
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
66+
updated_at = models.DateTimeField(auto_now=True, blank=True, null=True)
67+
68+
class Meta:
69+
db_table = 'sca2_vul_package_range'
70+
71+
72+
class VulPackageVersion(models.Model):
73+
vul_package_id = models.IntegerField(max_length=11, blank=True, null=True)
74+
ecosystem = models.CharField(max_length=255, blank=True, null=True)
75+
name = models.CharField(max_length=255, blank=True, null=True)
76+
version = models.CharField(max_length=255, blank=True, null=True)
77+
78+
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
79+
updated_at = models.DateTimeField(auto_now=True, blank=True, null=True)
80+
81+
class Meta:
82+
db_table = 'sca2_vul_package_version'

sca/urls.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from django.urls import include, path
2+
from sca.views.package import PackageList
3+
from sca.views.package_vul import OnePackageVulList
4+
from rest_framework import routers
5+
router = routers.DefaultRouter()
6+
7+
urlpatterns = [
8+
path('package/', PackageList.as_view()),
9+
path('package_vul/', OnePackageVulList.as_view()),
10+
]
11+

sca/views/package.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from sca.models import Package
2+
from django.http import JsonResponse
3+
from rest_framework import views
4+
from django.core.paginator import Paginator
5+
from django.forms.models import model_to_dict
6+
7+
8+
class PackageList(views.APIView):
9+
10+
def get(self, request):
11+
filter_fields = ['hash', 'aql', 'ecosystem', 'name', 'version']
12+
_filter = Package.objects.filter().order_by("-updated_at")
13+
kwargs = {}
14+
for filter_field in filter_fields:
15+
_val = request.GET.get(filter_field, "")
16+
if _val != "":
17+
kwargs[filter_field] = request.GET.get(filter_field, "")
18+
_filter = _filter.filter(**kwargs)
19+
20+
page = int(request.GET.get("page", 1))
21+
page_size = int(request.GET.get("page_size", 5))
22+
23+
pageinfo = Paginator(_filter, per_page=page_size)
24+
result = {
25+
'data': [],
26+
'msg': 'success',
27+
'page': {
28+
'alltotal': pageinfo.count,
29+
'num_pages': pageinfo.num_pages,
30+
'page_size': pageinfo.per_page,
31+
},
32+
'status': 201
33+
}
34+
if page == 0 or page <= pageinfo.num_pages:
35+
rows = pageinfo.page(page).object_list
36+
37+
for row in rows:
38+
result['data'].append(model_to_dict(row))
39+
40+
return JsonResponse(result)

sca/views/package_vul.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
from sca.models import Package, VulPackageVersion, VulPackage, VulPackageRange, Vul
2+
from django.http import JsonResponse
3+
from rest_framework import views
4+
from django.forms.models import model_to_dict
5+
6+
class OnePackageVulList(views.APIView):
7+
8+
# 查找单个漏洞下,所有的修复的高版本
9+
def find_fixed_versions(self, vul_package_id, ecosystem, name, version):
10+
vul_package_ranges = VulPackageRange.objects.filter(
11+
vul_package_id=vul_package_id,
12+
ecosystem=ecosystem, name=name,
13+
type__in=['ECOSYSTEM', 'SEMVER'],
14+
# introduced__lte=version,
15+
fixed__gte=version
16+
).all()
17+
fixed_versions = []
18+
for vul_package_range in vul_package_ranges:
19+
fixed_versions.append(vul_package_range.fixed)
20+
return fixed_versions
21+
22+
def get(self, request):
23+
filter_fields = ['hash', 'aql', 'ecosystem', 'name', 'version']
24+
_filter = Package.objects.filter()
25+
kwargs = {}
26+
for filter_field in filter_fields:
27+
_val = request.GET.get(filter_field, "")
28+
if _val != "":
29+
kwargs[filter_field] = request.GET.get(filter_field, "")
30+
31+
ecosystem = request.GET.get('ecosystem', '')
32+
name = request.GET.get('name', '')
33+
version = request.GET.get('version', '')
34+
35+
package = _filter.filter(**kwargs).first()
36+
print(package)
37+
if package is not None:
38+
ecosystem = package.ecosystem
39+
name = package.name
40+
version = package.version
41+
42+
vul_list = []
43+
vul_package_ids = []
44+
vul_package_ranges = VulPackageRange.objects.filter(
45+
ecosystem=ecosystem, name=name, type="SEMVER",
46+
introduced__gte=version, fixed__lte=version
47+
).all()[0:1000]
48+
49+
for vul_package_range in vul_package_ranges:
50+
vul_package_ids.append(vul_package_range.vul_package_id)
51+
52+
vul_package_versions = VulPackageVersion.objects.filter(
53+
ecosystem=ecosystem, name=name, version=version
54+
).all()[0:1000]
55+
for vul_package_version in vul_package_versions:
56+
vul_package_ids.append(vul_package_version.vul_package_id)
57+
58+
for vul_package_id in vul_package_ids:
59+
vul_package = VulPackage.objects.get(pk=vul_package_id)
60+
vul = Vul.objects.get(pk=vul_package.vul_id)
61+
vul_list.append(
62+
{
63+
"vul": model_to_dict(vul),
64+
"vul_package": model_to_dict(vul_package),
65+
"fixed_versions": self.find_fixed_versions(
66+
vul_package_id,
67+
ecosystem,
68+
name,
69+
version
70+
)
71+
}
72+
)
73+
if package is not None:
74+
package = model_to_dict(package)
75+
76+
result = {
77+
'data': {
78+
"vul_list": vul_list,
79+
"package": package,
80+
},
81+
'msg': 'success',
82+
'status': 201
83+
}
84+
return JsonResponse(result)

0 commit comments

Comments
 (0)