Skip to content

Commit

Permalink
Merge pull request #37 from mpast/dev
Browse files Browse the repository at this point in the history
Include top 10 mobile risk reference
  • Loading branch information
mpast authored May 16, 2021
2 parents e852f28 + ec5cfbb commit afd50e0
Show file tree
Hide file tree
Showing 22 changed files with 1,453 additions and 34 deletions.
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ Image is based on python buster. Link to [Docker Hub image](https://hub.docker.c
- [x] Uses Docker for easy deployment in multiplatform environment
- [x] Extract all information of the APK
- [x] Analyze all the source code searching for weaknesses
- [x] All findings are categorized and follows CWE standards
- [x] Also highlight the Best Practices in Secure Android Implementation in the APK
- [x] The findings can be edited and the false positives can be triaged and deleted
- [x] All scan results can be exported to PDF
- [x] All findings are categorized and follows **CWE standards**
- [x] All findings are categorized and include **Mobile Top 10 Risk**
- [x] Also highlight the **Best Practices in Secure Android Implementation** in the APK
- [x] The findings can be edited and the **false positives can be triaged and deleted**
- [x] All scan results can be **exported to PDF**
- [x] User authentication and user management
- [x] API v1 with Swagger and ReDoc
- [x] TLS
Expand All @@ -93,7 +94,14 @@ These can be activated and deactivated in `/patterns`

Note: some of the hardcoded patterns are from [apkleaks](https://github.com/dwisiswant0/apkleaks)

### Integrations
### Models
The application has an created models for each of the entities of the scans' information to be able to create relations an abtain the best conclusions for each of the apks.

![Models](app/static/models_snippet.png)

To see the whole model schema, go to [models](app/static/models.png)

### Integrations

#### Virus Total (API v3)

Expand Down
4 changes: 1 addition & 3 deletions app/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ def get_tree_dir(scan):

def find_patterns(i, prev_line, line, name, dir, scan):
patterns = Pattern.objects.filter(active=True)
findings = list()
url = ''
m = ''
for p in patterns:
Expand Down Expand Up @@ -301,11 +300,11 @@ def find_patterns(i, prev_line, line, name, dir, scan):
severity = p.default_severity,
mitigation = p.default_mitigation,
cwe = p.default_cwe,
risk = p.default_risk,
user = scan.user
)
finding.save()
scan.findings = int(scan.findings) + 1
findings.append(finding)
scan.save()
if (type != ''):
s = String(type = type, value = match_str, scan = scan, finding = finding)
Expand All @@ -319,7 +318,6 @@ def find_patterns(i, prev_line, line, name, dir, scan):
except Exception as e:
logger.debug(e)

return findings

def get_lines(finding='', path=''):
formatter = HtmlFormatter(linenos=False, cssclass="source")
Expand Down
1 change: 1 addition & 0 deletions app/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_extensions',
'bootstrap4',
'widget_tweaks',
'fontawesome_5',
Expand Down
2 changes: 1 addition & 1 deletion app/fixtures/data.json

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion app/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class CweModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return "CWE #%s - %s" % (obj.cwe, obj.description)

class RiskModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return "OWASP M%s - %s" % (obj.risk, obj.description)

class SignUpForm(UserCreationForm):
first_name = forms.CharField(max_length=100, help_text='Last Name')
last_name = forms.CharField(max_length=100, help_text='Last Name')
Expand Down Expand Up @@ -48,6 +52,7 @@ class Meta:
class FindingForm(forms.ModelForm):
scan = ScanModelChoiceField(queryset=Scan.objects.all())
cwe = CweModelChoiceField(queryset=Cwe.objects.all())
risk = RiskModelChoiceField(queryset=Risk.objects.all())
class Meta:
model = Finding
fields = ('scan', 'name', 'description', 'severity', 'status', 'path', 'line_number', 'line', 'snippet', 'cwe', 'mitigation', 'defectdojo_id')
fields = ('scan', 'name', 'description', 'severity', 'status', 'path', 'line_number', 'line', 'snippet', 'cwe', 'risk', 'mitigation', 'defectdojo_id')
2 changes: 1 addition & 1 deletion app/integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def create_finding_on_dojo(finding):
'active': True,
#'verified': verified,
'mitigation': finding.mitigation if finding.mitigation != '' else 'N/A',
#'references': references,
'references': finding.risk.reference,
#'build_id' : build,
'line' : finding.line_number,
'file_path' : finding.path,
Expand Down
34 changes: 34 additions & 0 deletions app/migrations/0003_auto_20210509_1408.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 3.2.2 on 2021-05-09 12:08

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('app', '0002_scan_task'),
]

operations = [
migrations.CreateModel(
name='Risk',
fields=[
('risk', models.IntegerField(primary_key=True, serialize=False)),
('description', models.TextField()),
('reference', models.TextField()),
('created_on', models.DateTimeField(auto_now_add=True, null=True)),
('updated_on', models.DateTimeField(auto_now=True, null=True)),
],
),
migrations.AddField(
model_name='finding',
name='risk',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='app.risk'),
),
migrations.AddField(
model_name='pattern',
name='default_risk',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='app.risk'),
),
]
9 changes: 9 additions & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,17 @@ class Cwe(models.Model):
created_on = models.DateTimeField(auto_now_add=True, null=True)
updated_on = models.DateTimeField(auto_now=True, null=True)

class Risk(models.Model):
risk = models.IntegerField(primary_key=True)
description = models.TextField()
reference = models.TextField()
created_on = models.DateTimeField(auto_now_add=True, null=True)
updated_on = models.DateTimeField(auto_now=True, null=True)

class Pattern(models.Model):
id = models.AutoField(primary_key=True)
default_cwe = models.ForeignKey(Cwe, on_delete=models.CASCADE)
default_risk = models.ForeignKey(Risk, on_delete=models.CASCADE, null=True)
default_name = models.TextField()
default_description = models.TextField(blank=True)
default_severity = models.CharField(
Expand Down Expand Up @@ -127,6 +135,7 @@ class Finding(models.Model):
description = models.TextField()
mitigation = models.TextField(blank=True, null=True)
cwe = models.ForeignKey(Cwe, on_delete=models.CASCADE)
risk = models.ForeignKey(Risk, on_delete=models.CASCADE, null=True)
user = models.ForeignKey(User, on_delete=models.PROTECT)
defectdojo_id = models.IntegerField(blank=True, default=0)
created_on = models.DateTimeField(auto_now_add=True, null=True)
Expand Down
38 changes: 38 additions & 0 deletions app/static/django_extensions/css/jquery.autocomplete.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* @fileOverview CSS for jquery-autocomplete, the jQuery Autocompleter
* @author <a href="mailto:[email protected]">Dylan Verheul</a>
* @license MIT | GPL | Apache 2.0, see LICENSE.txt
* @see https://github.com/dyve/jquery-autocomplete
*/
.acResults {
padding: 0px;
border: 1px solid WindowFrame;
background-color: Window;
overflow: hidden;
}

.acResults ul {
margin: 0px;
padding: 0px;
list-style-position: outside;
list-style: none;
}

.acResults ul li {
margin: 0px;
padding: 2px 5px;
cursor: pointer;
display: block;
font: menu;
font-size: 12px;
overflow: hidden;
}

.acLoading {
background : url('../img/indicator.gif') right center no-repeat;
}

.acSelect {
background-color: Highlight;
color: HighlightText;
}
Binary file added app/static/django_extensions/img/indicator.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
119 changes: 119 additions & 0 deletions app/static/django_extensions/js/jquery.ajaxQueue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/**
* Ajax Queue Plugin
*
* Homepage: http://jquery.com/plugins/project/ajaxqueue
* Documentation: http://docs.jquery.com/AjaxQueue
*/

/**
<script>
$(function(){
jQuery.ajaxQueue({
url: "test.php",
success: function(html){ jQuery("ul").append(html); }
});
jQuery.ajaxQueue({
url: "test.php",
success: function(html){ jQuery("ul").append(html); }
});
jQuery.ajaxSync({
url: "test.php",
success: function(html){ jQuery("ul").append("<b>"+html+"</b>"); }
});
jQuery.ajaxSync({
url: "test.php",
success: function(html){ jQuery("ul").append("<b>"+html+"</b>"); }
});
});
</script>
<ul style="position: absolute; top: 5px; right: 5px;"></ul>
*/
/*
* Queued Ajax requests.
* A new Ajax request won't be started until the previous queued
* request has finished.
*/

/*
* Synced Ajax requests.
* The Ajax request will happen as soon as you call this method, but
* the callbacks (success/error/complete) won't fire until all previous
* synced requests have been completed.
*/


(function(jQuery) {

var ajax = jQuery.ajax;

var pendingRequests = {};

var synced = [];
var syncedData = [];

jQuery.ajax = function(settings) {
// create settings for compatibility with ajaxSetup
settings = jQuery.extend(settings, jQuery.extend({}, jQuery.ajaxSettings, settings));

var port = settings.port;

switch(settings.mode) {
case "abort":
if ( pendingRequests[port] ) {
pendingRequests[port].abort();
}
return pendingRequests[port] = ajax.apply(this, arguments);
case "queue":
var _old = settings.complete;
settings.complete = function(){
if ( _old )
_old.apply( this, arguments );
jQuery([ajax]).dequeue("ajax" + port );;
};

jQuery([ ajax ]).queue("ajax" + port, function(){
ajax( settings );
});
return;
case "sync":
var pos = synced.length;

synced[ pos ] = {
error: settings.error,
success: settings.success,
complete: settings.complete,
done: false
};

syncedData[ pos ] = {
error: [],
success: [],
complete: []
};

settings.error = function(){ syncedData[ pos ].error = arguments; };
settings.success = function(){ syncedData[ pos ].success = arguments; };
settings.complete = function(){
syncedData[ pos ].complete = arguments;
synced[ pos ].done = true;

if ( pos == 0 || !synced[ pos-1 ] )
for ( var i = pos; i < synced.length && synced[i].done; i++ ) {
if ( synced[i].error ) synced[i].error.apply( jQuery, syncedData[i].error );
if ( synced[i].success ) synced[i].success.apply( jQuery, syncedData[i].success );
if ( synced[i].complete ) synced[i].complete.apply( jQuery, syncedData[i].complete );

synced[i] = null;
syncedData[i] = null;
}
};
}
return ajax.apply(this, arguments);
};

})((typeof window.jQuery == 'undefined' && typeof window.django != 'undefined')
? django.jQuery
: jQuery
);
Loading

0 comments on commit afd50e0

Please sign in to comment.