Completed
Push — dev-skf ( b5d67b...388b3e )
by Glenn
01:14
created

skf.random_token()   A

Complexity

Conditions 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 7
rs 9.4286
1
# -*- coding: utf-8 -*-
2
"""
3
    Security Knowledge Framework is an expert system application 
4
    that uses OWASP Application Security Verification Standard, code examples,
5
    helps developers in pre-development and post-development.  
6
    Copyright (C) 2015  Glenn ten Cate, Riccardo ten Cate
7
8
    This program is free software: you can redistribute it and/or modify
9
    it under the terms of the GNU Affero General Public License as
10
    published by the Free Software Foundation, either version 3 of the
11
    License, or (at your option) any later version.
12
13
    This program is distributed in the hope that it will be useful,
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
    GNU Affero General Public License for more details.
17
18
    You should have received a copy of the GNU Affero General Public License
19
    along with this program. If not, see <http://www.gnu.org/licenses/>.
20
"""
21
22
import os, markdown, datetime, string, base64, re, sys, re, requests, mimetypes, smtplib
23
from OpenSSL import SSL, rand
24
from docx import Document
25
from BeautifulSoup import BeautifulSoup
26
from docx.enum.text import WD_ALIGN_PARAGRAPH
27
from docx.shared import Inches
28
from functools import wraps 
29
from sqlite3 import dbapi2 as sqlite3
30
from flask.ext.bcrypt import Bcrypt
31
from flask import Flask, request, session, g, redirect, url_for, abort, \
32
     render_template, flash, Markup, make_response
33
     
34
     
35
36
# create the application
37
app = Flask(__name__)
38
39
"""Set up bcrypt for passwords encrypting"""
40
bcrypt = Bcrypt(app)
41
42
def add_response_headers(headers={}):
43
    """This decorator adds the headers passed in to the response"""
44
    def decorator(f):
45
        @wraps(f)
46
        def decorated_function(*args, **kwargs):
47
            resp = make_response(f(*args, **kwargs))
48
            h = resp.headers
49
            for header, value in headers.items():
50
                h[header] = value
51
            return resp
52
        return decorated_function
53
    return decorator
54
55
def security(f):
56
    """This decorator passes multiple security headers and checks log file to block users"""
57
    return add_response_headers({'X-Frame-Options': 'deny', 'X-XSS-Protection': '1', 'X-Content-Type-Options': 'nosniff', 'Cache-Control': 'no-store, no-cache','Strict-Transport-Security': 'max-age=16070400; includeSubDomains', 'Server': 'Security Knowledge Framework'})(f)
58
59
def check_token():
60
    """Checks the submitted CSRF token"""
61
    if not session.get('csrf_token') == request.form['csrf_token']:
62
        log("User supplied not valid CSRF token", "FAIL", "HIGH")
63
        session.clear()
64
        return abort(500)(f)
65
66
def generate_pass():
67
    chars = string.letters + string.digits + '+/'
68
    assert 256 % len(chars) == 0  # non-biased later modulo
69
    PWD_LEN = 12
70
    generated_pass = ''.join(chars[ord(c) % len(chars)] for c in os.urandom(PWD_LEN))
71
    return generated_pass
72
73
def random_token(tokenBytes):
74
    #Create random token
75
    rand.cleanup()
76
    Random_token_raw = rand.bytes(int(tokenBytes))
77
    Random_token = base64.b64encode(Random_token_raw)
78
    result = re.sub("==", "", Random_token)
79
    return result
80
81
def log(message, value, threat):
82
    """Create log file and write events triggerd by the user
83
    The variables: message can be everything, value contains FAIL or SUCCESS and threat LOW MEDIUM HIGH"""
84
    now = datetime.datetime.now()
85
    dateLog = now.strftime("%Y-%m")
86
    dateTime = now.strftime("%Y-%m-%d %H:%M") 
87
    ip = request.remote_addr
88
    try:
89
        file = open('logs/'+dateLog+'.txt', 'a+')
90
    except IOError:
91
        # If not exists, create the file
92
        file = open('logs/'+dateLog+'.txt', 'w+')
93
    file.write(dateTime +' '+ message +' ' + ' ' + value + ' ' + threat + ' ' +ip + "\r\n")
94
    file.close() 
95
              
96
def valAlphaNum(value, countLevel):
97
    match = re.findall(r"[^ a-zA-Z0-9_.-]", value)
98
    if match:
99
        log("User supplied not an a-zA-Z0-9 value", "FAIL", "MEDIUM")
100
        countAttempts(countLevel)
101
        abort(406)
102
        return False
103
    else:
104
        return True
105
106
def valNum(value, countLevel):
107
    match = re.findall(r'[a-zA-Z_]', str(value))
108
    if match:
109
        log("malicious input found", "FAIL", "MEDIUM")
110
        countAttempts(countLevel)
111
        abort(406)
112
        return False
113
    else:
114
        return True
115
        
116
def encodeInput(html):
117
    """Encode evil chars..."""
118
    result = re.sub('"', "&quot;", html)
119
    result = re.sub("'", "&#39;", result)
120
    result = re.sub("&", "&amp;", result)
121
    result = re.sub("<", "&lt;", result)
122
    result = re.sub(">", "&gt;", result)
123
    log("User supplied input was encoded", "SUCCESS", "NULL")
124
    return result
125
    
126
#not tested yet, made draft did not needed it so far
127
def whiteList(allowed, input, countlevel):
128
    splitted = string.split(allowed, ',')
129
    bool = False
130
    for val in splitted:
131
        if val in input:
132
            bool = True
133
    if bool == False:
134
        log("User is tampering whitelist values", "FAIL", "HIGH")
135
        countAttempts(countLevel)
136
        abort(401)
137
    if bool == True:
138
        return bool
139
140
141
#secret key for flask internal session use
142
rand.cleanup()
143
secret_key = rand.bytes(512)
144
145
mimetypes.add_type('image/svg+xml', '.svg')
146
bindaddr = '127.0.0.1';
147
148
# Load default config and override config from an environment variable
149
# You can also replace password with static password:  PASSWORD='pass!@#example'
150
app.config.update(dict(
151
    DATABASE=os.path.join(app.root_path, 'skf.db'),
152
    DEBUG=True,
153
    SECRET_KEY=secret_key,
154
    SESSION_COOKIE_SECURE=True,
155
    SESSION_COOKIE_HTTPONLY = True
156
))
157
158
@app.context_processor
159
def inject_year():
160
    return dict(year=datetime.datetime.now().strftime("%Y"))
161
162
def connect_db():
163
    """Connects to the specific database."""
164
    rv = sqlite3.connect(app.config['DATABASE'])
165
    rv.row_factory = sqlite3.Row
166
    return rv
167
168
169
def init_db():
170
    """Initializes the database."""
171
    db = get_db()
172
    with app.open_resource('schema.sql') as f:
173
        db.cursor().executescript(f.read())
174
    db.commit()
175
176
177
@app.cli.command('initdb')
178
def initdb_command():
179
    """Creates the database tables."""
180
    init_db()
181
    print('Initialized the database.')
182
183
184
def get_db():
185
    """Opens a new database connection if there is none yet for the
186
    current application context.
187
    """
188
    if not hasattr(g, 'sqlite_db'):
189
        g.sqlite_db = connect_db()
190
    return g.sqlite_db
191
192
def get_filepaths(directory):
193
    """
194
    This function will generate the file names in a directory 
195
    tree by walking the tree either top-down or bottom-up. For each 
196
    directory in the tree rooted at directory top (including top itself), 
197
    it yields a 3-tuple (dirpath, dirnames, filenames).
198
    """
199
    file_paths = [] 
200
    for root, directories, files in os.walk(directory):
201
        for filename in files:
202
            filepath = os.path.join(root, filename)
203
            file_paths.append(filepath)
204
    return file_paths  
205
206
def get_num(x):
207
    """get numbers from a string"""
208
    return int(''.join(ele for ele in x if ele.isdigit()))
209
210
@app.teardown_appcontext
211
def close_db(error):
212
    """Closes the database again at the end of the request."""
213
    if hasattr(g, 'sqlite_db'):
214
        g.sqlite_db.close()
215
216
def check_version():
217
    try:
218
        r = requests.get("http://raw.githubusercontent.com/blabla1337/skf-flask/master/setup.py")
219
        items_remote = r.content.split(",") 
220
        version_remote = items_remote[1]
221
        version_remote = version_remote.replace(version_remote[:14], '')
222
        version_remote = version_remote[:-1]
223
        with open ("version.txt", "r") as myfile:
224
            version_local = myfile.read().replace('\n', '')
225
226
        if version_local == version_remote:
227
            return True
228
        else:
229
            return False
230
    except:
231
        return False
232
233
def get_version():
234
    with open ("version.txt", "r") as myfile:
235
        version_final = myfile.read().replace('\n', '')
236
    return version_final
237
        
238
def projects_functions_techlist():
239
    """get list of technology used for creating project functions"""
240
    if not session.get('logged_in'):
241
        abort(401)
242
    db = get_db()
243
    cur = db.execute('SELECT techID, techName, vulnID from techhacks ORDER BY techID DESC')
244
    entries = cur.fetchall()
245
    return entries 
246
247
@app.route('/')
248
@security
249
def show_landing():
250
    """show the loging page and set default code language"""
251
    rand.cleanup()
252
    csrf_token_raw = rand.bytes(128)
253
    csrf_token = base64.b64encode(csrf_token_raw)
254
    session['csrf_token'] = csrf_token
255
    session['code_lang'] = "php"
256
257
    return render_template('login.html', csrf_token=session['csrf_token'])
258
259
@app.route('/dashboard', methods=['GET'])
260
@security
261
def dashboard():
262
    """show the landing page"""
263
    if not session.get('logged_in'):
264
        log("User with no valid session tries access to page /dashboard", "FAIL", "HIGH")
265
        abort(401)
266
    permissions("read")
267
    version_check = check_version()
268
    version = get_version()
269
    return render_template('dashboard.html', version=version, version_check=version_check)
270
271
@app.route('/first-login', methods=['GET'])
272
@security
273
def first_login():
274
    version_check = check_version()
275
    version = get_version()
276
    return render_template('first-login.html', version=version, version_check=version_check)
277
278
"""create account for a user"""
279
@app.route('/create-account', methods=['GET', 'POST'])
280
@security
281
def create_account():
282
    """validate the login data for access dashboard page"""
283
    error = None
284
    db = get_db()
285
    db.commit()
286
    if request.method == 'POST':
287
        """Username, password, token, email from form"""
288
        token  = request.form['token']
289
        email  = request.form['email']
290
        password  = request.form['password']
291
        
292
        #hash the password with Bcrypt, does autosalt
293
        hashed = bcrypt.generate_password_hash(password, 12)
294
      
295
        #Do DB query also check for access
296
        cur = db.execute('SELECT accessToken, userID from users where email=? AND accessToken=?',
297
                            [email, token])
298
        check = cur.fetchall()
299
        for verify in check:
300
            userID = verify[1]
301
            if str(verify[0]) == token:
302
                        #update the counter and blocker table with new values 
303
                db.execute('UPDATE users SET access=?, password=?, activated=? WHERE accessToken=? AND userID=?',
304
                           ["true", hashed, "true", token , userID])
305
                db.commit()
306
                #Insert record in counter table for the counting of malicious inputs
307
                db.execute('INSERT INTO counter (userID, countEvil, block) VALUES (?, ?, ?)',
308
                            [userID, 0, 0])
309
                db.commit()
310
                
311
                #Create standard group  for this user to assign himself to
312
                date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
313
                db.execute('INSERT INTO groups (ownerID, groupName, timestamp) VALUES (?, ?, ?)',
314
                            [userID, "privateGroup", date])
315
                db.commit()
316
                
317
                #Select this groupID so we can assign the user to this group automatically
318
                cur = db.execute('SELECT groupID from groups where ownerID=?',
319
                            [userID])
320
                group = cur.fetchall()
321
                for theID in group:
322
                    groupID = theID[0]
323
                            
324
                #Now we assign the user to the group
325
                date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
326
                db.execute('INSERT INTO groupMembers (userID, groupID, ownerID) VALUES (?, ?, ?)',
327
                            [userID, groupID, userID])
328
                db.commit()
329
               
330
        if not check:
331
            #if not the right pin, the user account wil be deleted if not exsisting
332
            db.execute('DElETE FROM users where email=? AND activated=?',
333
                        [email, "false"])
334
            db.commit()
335
        
336
        
337
        return render_template('login.html', error=error)
338
339
"""First comes the method for login"""
340
@app.route('/login', methods=['GET', 'POST'])
341
@security
342
def login():
343
    """validate the login data for access dashboard page"""
344
    error = None
345
    db = get_db()
346
    db.commit()
347
    if request.method == 'POST':
348
        """Username and password from form"""
349
        username = request.form['username']
350
        password = request.form['password']
351
        
352
        #Do DB query also check for access
353
        cur = db.execute('SELECT access from users where userName=?',
354
                            [username])
355
        check = cur.fetchall()
356
        for verify in check:
357
            if verify[0] == "false":
358
                return render_template('warning.html', error=error)
359
            
360
        #Do DB query also check for access
361
        cur = db.execute('SELECT u.userID, u.privilegeID, u.userName, u.password, u.access, priv.privilegeID, priv.privilege from users as u JOIN privileges AS priv ON priv.privilegeID = u.privilegeID where username=? AND access="true"',
362
                            [username])
363
        entries = cur.fetchall()
364
        for entry in entries:
365
            passwordHash = entry[3]  
366
            userID 		 = entry[0]         
367
            #Do encryption
368
            if bcrypt.check_password_hash(passwordHash, password):
369
                log("Valid username/password submit", "SUCCESS", "HIGH")  
370
                rand.cleanup()
371
                csrf_token_raw = rand.bytes(128)
372
                csrf_token = base64.b64encode(csrf_token_raw)  
373
                session['logged_in'] = True
374
                session['userID'] = userID
375
                session['csrf_token'] = csrf_token
376
                session['code_lang'] = "php"
377
                session['userName'] = entry[2]
378
                valAlphaNum(session['userName'], 12)
379
                session['permissions'] = entry[6]
380
                version_check = check_version()
381
                version = get_version()
382
                
383
                #Do DB query also check for access
384
                cur = db.execute('SELECT groupID from groups WHERE groupName=? AND ownerID=?',
385
                            ["privateGroup", session['userID']])
386
                groupID = cur.fetchall()
387
                for entry in groupID:
388
                    session['privateGroup'] = entry[0]
389
                return render_template('dashboard.html', version=version, version_check=version_check)
390
            else:    
391
                log("invalid login submit", "FAIL", "HIGH")                   
392
    return render_template('login.html', error=error)
393
394
def countAttempts(counter):
395
    """We count hacking attempts and block the user if structural"""
396
    if not session.get('logged_in'):
397
        abort(401)
398
    db = get_db()
399
    cur = db.execute('SELECT * FROM counter where userID=?',
400
                        [session['userID']])
401
    entries = cur.fetchall()
402
    for entry in entries:
403
        counterDB = entry[2]
404
        blockDB   = entry[3] 
405
    
406
    updateCount = counterDB + counter
407
    updateBlock = blockDB   + counter
408
    redirect = False
409
    
410
    if updateCount >= 3:
411
        countUpdate = 0
412
        redirect = True
413
        
414
    if updateBlock >=12:
415
        redirect = True
416
        db.execute('UPDATE users SET access=? WHERE userID=?',
417
               ["false", session['userID']])
418
    	db.commit()
419
    	renderwhat = "/warning.html"
420
    
421
    #update the counter and blocker table with new values 
422
    db.execute('UPDATE counter SET countEvil=?, block=? WHERE userID=?',
423
        [updateCount, updateBlock, session['userID']])
424
    db.commit()
425
    
426
    if redirect == True:
427
        log( "Authenticated session destroyed by counter class", "SUCCESS", "LOW")
428
        # TO-DO turn on again
429
        #session.pop('logged_in', None)
430
        #session.clear()
431
    if redirect == False:
432
        return True
433
434
"""Here is the method for the database enforced privilege based authentication"""
435
def permissions(fromFunction):
436
    db = get_db()
437
    db.commit()
438
    
439
    """Do DB query to see if username exists"""
440
    cur = db.execute('SELECT a.username, a.userID, a.password, a.privilegeID, b.privilegeID, b.privilege FROM users as a JOIN privileges as b ON a.privilegeID = b.privilegeID WHERE a.userID =? and a.access="true" ',
441
    				       [session['userID']])
442
    entries = cur.fetchall()
443
    for entry in entries:
444
    	permissions = entry[5]
445
    	
446
    permissionsGranted = string.split(permissions, ':')	
447
    permissionsNeeded  = string.split(fromFunction, ':')
448
    
449
    count = len(permissionsNeeded)
450
    counthits = 0
451
	
452
    for val in permissionsGranted:
453
	    if val in fromFunction:
454
	        counthits +=1
455
    if counthits >= count:
456
        return permissions
457
    else:
458
        log( "User tries to reach functions out of bound no restrictions!!", "FAIL", "HIGH")
459
        abort(401)
460
461
@app.route('/logout', methods=['GET', 'POST'])
462
@security
463
def logout():
464
    """logout and destroy session"""
465
    log( "Authenticated session destroyed", "SUCCESS", "LOW")
466
    session.pop('logged_in', None)
467
    session.clear()
468
    return redirect("/")
469
470
@app.route('/code/<code_lang>', methods=['GET'])
471
@security
472
def set_code_lang(code_lang):
473
    """set a code language: php java python perl"""
474
    if not session.get('logged_in'):
475
        log( "User with no valid session tries access to page /code", "FAIL", "HIGH")
476
        abort(401)
477
    permissions("read")
478
    allowed = "php java python asp"
479
    valAlphaNum(code_lang, 12)
480
    safe_code_lang = encodeInput(code_lang)
481
    found = allowed.find(safe_code_lang)
482
    if found != -1:
483
        #to do below security issue... Create white-list of the languages
484
        if safe_code_lang == "asp" or safe_code_lang == "php": 
485
            session['code_lang'] = safe_code_lang
486
    return redirect(url_for('code_examples'))
487
488
@app.route('/code-examples', methods=['GET'])
489
@security
490
def code_examples():
491
    """Shows the knowledge base markdown files."""
492
    if not session.get('logged_in'):
493
        log( "User with no valid session tries access to page /code-examples", "FAIL", "HIGH")
494
        abort(401)
495
    permissions("read")
496
    items = []
497
    id_items = []
498
    full_file_paths = []
499
    allowed = set(string.ascii_lowercase + string.ascii_uppercase + '.')
500
    if set(session['code_lang']) <= allowed:
501
        full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/code_examples/"+session['code_lang']))
502
        for path in full_file_paths:
503
            id_item = get_num(path)
504
            path = path.split("-")
505
            y = len(path)-3 
506
            kb_name_uri = path[(y)]
507
            kb_name = kb_name_uri.replace("_", " ")
508
            items.append(kb_name)
509
            id_items.append(id_item)
510
    return render_template('code-examples.html', items=items, id_items=id_items)
511
512
@app.route('/code-item', methods=['POST'])
513
@security
514
def show_code_item():
515
    """show the coding examples page"""
516
    if not session.get('logged_in'):
517
        log("User with no valid session tries access to page /code-item", "FAIL", "HIGH")
518
        abort(401)
519
    permissions("read")
520
    valNum(request.form['id'], 12)
521
    id = int(request.form['id'])
522
    items = []
523
    full_file_paths = []
524
    allowed = set(string.ascii_lowercase + string.ascii_uppercase + '.')
525
    if set(session['code_lang']) <= allowed:
526
        full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/code_examples/"+session['code_lang']))
527
        for path in full_file_paths:
528
            if id == get_num(path):
529
                filemd = open(path, 'r').read()
530
                content = Markup(markdown.markdown(filemd)) 
531
    return render_template('code-examples-item.html', **locals())
532
533
@app.route('/kb-item', methods=['POST'])
534
@security
535
def show_kb_item():
536
    """show the knowledge base search result page"""
537
    if not session.get('logged_in'):
538
        log("User with no valid session tries access to page /kb-item", "FAIL", "HIGH")
539
        abort(401)
540
    permissions("read")
541
    valNum(request.form['id'], 12)
542
    id = int(request.form['id'])
543
    items = []
544
    full_file_paths = []
545
    full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown"))
546
    for path in full_file_paths:
547
        if id == get_num(path):
548
            filemd = open(path, 'r').read()
549
            content = Markup(markdown.markdown(filemd)) 
550
    return render_template('knowledge-base-item.html', **locals())
551
552
553
@app.route('/knowledge-base-api', methods=['GET'])
554
@security
555
def show_kb_api():
556
    """show the knowledge base items page"""
557
    log( "User access page /knowledge-base-api", "SUCCESS", "HIGH")
558
    full_file_paths = []
559
    content = []
560
    kb_name = []
561
    full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/knowledge_base"))
562
    for path in full_file_paths:
563
        filetmp = open(path, 'r').read()
564
        filetmp2 = filetmp.replace("-------", "")
565
        filetmp3 = filetmp2.replace("**", "")
566
        filetmp4 = filetmp3.replace("\"", "")
567
        filetmp5 = filetmp4.replace("\t", "")
568
        content.append(filetmp5.replace("\n", " "))
569
        path = path.split("-")
570
        y = len(path)-3
571
        kb_name_uri = path[(y)]
572
        kb_name.append(kb_name_uri.replace("_", " "))
573
    return render_template('knowledge-base-api.html', **locals())
574
575
@app.route('/knowledge-base', methods=['GET'])
576
@security
577
def knowledge_base():
578
    """Shows the knowledge base markdown files."""
579
    if not session.get('logged_in'):
580
        log( "User with no valid session tries access to page /knowledge-base", "FAIL", "HIGH")
581
        abort(401)
582
    permissions("read")
583
    items = []
584
    id_items = []
585
    full_file_paths = []
586
    full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/knowledge_base"))
587
    for path in full_file_paths:
588
        id_item = get_num(path)
589
        path = path.split("-")
590
        y = len(path)-3 
591
        kb_name_uri = path[(y)]
592
        kb_name = kb_name_uri.replace("_", " ")
593
        items.append(kb_name)
594
        id_items.append(id_item)
595
    return render_template('knowledge-base.html', items=items, id_items=id_items)
596
597
@app.route('/users-new', methods=['GET'])
598
@security
599
def user_new():
600
    """show the create new project page"""
601
    if not session.get('logged_in'):
602
        log("User with no valid session tries access to page /user-new", "FAIL", "HIGH")
603
        abort(401)     
604
    permissions("manage")
605
    return render_template('users-new.html', csrf_token=session['csrf_token'])
606
    
607
@app.route('/users-add', methods=['POST'])
608
@security
609
def users_add():
610
    """add a new project to database"""
611
    if not session.get('logged_in'):
612
        log("User with no valid session tries access to page /users-add", "FAIL", "HIGH")
613
        abort(401)
614
    permissions("manage")
615
    check_token()
616
    db = get_db()
617
    valAlphaNum(request.form['username'], 1)
618
    valNum(request.form['privID'], 12)
619
    valNum(request.form['pincode'], 12)
620
    safe_userName = encodeInput(request.form['username'])
621
    safe_email    = encodeInput(request.form['email'])
622
    safe_privID   = encodeInput(request.form['privID'])
623
    pincode       = encodeInput(request.form['pincode'])
624
625
    db.execute('INSERT INTO users (privilegeID, userName, email, password, access, accessToken, activated) VALUES (?, ?, ?, ?, ?, ?, ?)',
626
               [safe_privID, safe_userName, safe_email, "none", "false", pincode, "false"])
627
    db.commit()
628
    
629
    return redirect(url_for('users_manage'))
630
631
@app.route('/users-manage', methods=['GET'])
632
@security
633
def users_manage():
634
    """show the project list page"""
635
    if not session.get('logged_in'):
636
        log("User with no valid session tries access to page /group-manage", "FAIL", "HIGH")
637
        abort(401)
638
    permissions("manage")
639
    db = get_db()
640
    cur = db.execute('SELECT u.userID, u.userName, u.email, u.privilegeID, u.access, p.privilegeID, p.privilege from users as u JOIN privileges as p ON p.privilegeID = u.privilegeID')
641
    users = cur.fetchall()
642
    
643
    return render_template('users-manage.html', users=users, csrf_token=session['csrf_token'])
644
645
@app.route('/user-access', methods=['POST'])
646
@security
647
def user_access():
648
    """add a new project to database"""
649
    if not session.get('logged_in'):
650
        log("User with no valid session tries access to page /assign-group", "FAIL", "HIGH")
651
        abort(401)
652
    permissions("manage")
653
    check_token()
654
    db = get_db()
655
    valNum(request.form['userID'], 12)
656
    whiteList("false,true", request.form['access'], 12)
657
    safe_userID   = encodeInput(request.form['userID'])
658
    safe_access = encodeInput(request.form['access'])
659
    db.execute('UPDATE users SET access=? WHERE userID=?',
660
		   [safe_access, safe_userID])
661
    db.execute('UPDATE counter SET countEvil=? AND block=? WHERE userID=?',
662
		   [0, 0, safe_userID])
663
    db.commit()
664
    
665
    return redirect(url_for('users_manage'))
666
    
667
@app.route('/group-new', methods=['GET'])
668
@security
669
def group_new():
670
    """show the create new project page"""
671
    if not session.get('logged_in'):
672
        log( "User with no valid session tries access to page /group-new", "FAIL", "HIGH")
673
        abort(401)     
674
    permissions("edit")
675
    return render_template('group-new.html', csrf_token=session['csrf_token'])
676
677
@app.route('/group-add', methods=['POST'])
678
@security
679
def group_add():
680
    """add a new project to database"""
681
    if not session.get('logged_in'):
682
        log("User with no valid session tries access to page /group-add", "FAIL", "HIGH")
683
        abort(401)
684
    permissions("edit")
685
    check_token()
686
    db = get_db()
687
    valAlphaNum(request.form['groupName'], 3)
688
    safe_inputName = encodeInput(request.form['groupName'])
689
    date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
690
    db.execute('INSERT INTO groups (timestamp, groupName, ownerID) VALUES (?, ?, ?)',
691
               [date, safe_inputName, session['userID']])
692
    db.commit()
693
    #than we select the most last group in order to check id
694
    cur2 = db.execute('SELECT groupID from groups WHERE timestamp=? AND ownerID=?',
695
                        [date, session['userID']])
696
    group = cur2.fetchall()
697
    #Do actual loop
698
    for value in group:
699
        groupID = value[0]
700
        
701
    #Than we insert this back into groupMembers table so the user is added to group
702
    db.execute('INSERT INTO groupMembers (userID, groupID, ownerID, timestamp) VALUES (?, ?, ?, ?)',
703
               [session['userID'], groupID, session['userID'], date])
704
    db.commit()
705
    return redirect(url_for('group_manage'))
706
707
@app.route('/group-users', methods=['GET'])
708
@security
709
def group_users():
710
    """show the project list page"""
711
    if not session.get('logged_in'):
712
        log("User with no valid session tries access to page /group-users", "FAIL", "HIGH")
713
        abort(401)
714
    permissions("edit")
715
    db = get_db()
716
    cur = db.execute('SELECT * from groups where ownerID=?',
717
                          [session['userID']])
718
    groups = cur.fetchall()
719
    
720
    """Select all users for adding to group"""
721
    cur2 = db.execute('SELECT username, userID from users')
722
    users = cur2.fetchall()
723
    
724
    """select users by assigned groups for display"""
725
    cur3 = db.execute('SELECT u.username, u.userID, g.groupName, g.groupID, m.groupID, m.userID, m.timestamp, g.ownerID from users as u JOIN groups AS g ON g.groupID = m.groupID JOIN groupMembers as m ON u.userID = m.userID  WHERE g.ownerID=? AND u.userName !=? ORDER BY g.groupName ',
726
    				   [session['userID'], session['userName']])
727
    summary = cur3.fetchall()
728
729
    return render_template('group-users.html', groups=groups, users=users, summary=summary, csrf_token=session['csrf_token'])
730
731
@app.route('/group-add-users', methods=['POST'])
732
@security
733
def group_add_users():
734
    """add a project function"""
735
    if not session.get('logged_in'):
736
        log("User with no valid session tries access to page /project-function-add", "FAIL", "HIGH")
737
        abort(401)
738
    permissions("edit")
739
    check_token()    
740
    valNum(request.form['groupName'], 12)     
741
    safe_groupID = encodeInput(request.form['groupName'])
742
743
    """Check is submitted groupID is owned by user"""
744
    db = get_db()
745
    cur3 = db.execute('SELECT groupID from groups where ownerID=?',
746
    				   [session['userID']])
747
    owner = cur3.fetchall()
748
    for val in owner:
749
	    if int(safe_groupID) == int(val[0]):
750
			f = request.form
751
			for key in f.keys():
752
				for value in f.getlist(key):
753
					found = key.find("test")
754
					if found != -1:
755
						db = get_db()
756
						date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
757
						items = value.split("-")
758
						userID = items[0]
759
						valNum(userID, 12)
760
						safe_userID = encodeInput(userID)
761
						db.execute('INSERT INTO groupMembers (timestamp, groupID, userID, ownerID) VALUES (?, ?, ?, ?)',
762
							   [date, safe_groupID, safe_userID, session['userID']])
763
						db.commit()
764
    redirect_url = '/group-users'
765
    return redirect(redirect_url)
766
767
@app.route('/user-del', methods=['POST'])
768
@security
769
def user_del():
770
    """delete project from database"""
771
    if not session.get('logged_in'):
772
        log("User with no valid session tries access to page /user-del", "FAIL", "HIGH")
773
        abort(401)
774
    permissions("delete")
775
    check_token()
776
    valNum(request.form['userID'], 12)
777
    
778
    safe_userID  = encodeInput(request.form['userID'])
779
    
780
    db = get_db()
781
    db.execute("DELETE FROM users WHERE userID=?",
782
               [safe_userID])
783
    db.commit()
784
    return redirect("/users-manage")
785
786
@app.route('/group-manage', methods=['GET'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
787
@security
788
def group_manage():
789
    """show the project list page"""
790
    if not session.get('logged_in'):
791
        log("User with no valid session tries access to page /group-manage", "FAIL", "HIGH")
792
        abort(401)
793
    permissions("edit")
794
    db = get_db()
795
    cur = db.execute('SELECT * from groups where ownerID=?',
796
                          [session['userID']])
797
    groups = cur.fetchall()
798
    
799
    return render_template('group-manage.html', groups=groups, csrf_token=session['csrf_token'])
800
    
801
@app.route('/group-del', methods=['POST'])
802
@security
803
def group_del():
804
    """delete project from database"""
805
    if not session.get('logged_in'):
806
        log("User with no valid session tries access to page /group-del", "FAIL", "HIGH")
807
        abort(401)
808
    permissions("manage")
809
    check_token()
810
    valNum(request.form['groupID'], 12)
811
    
812
    safe_groupID = encodeInput(request.form['groupID'])
813
    
814
    db = get_db()
815
    db.execute("DELETE FROM groups WHERE groupID=? AND ownerID=?",
816
               [safe_groupID, session['userID']])
817
    db.commit()
818
    return redirect("/group-manage")
819
820
@app.route('/project-new', methods=['GET'])
821
@security
822
def projects():
823
    """show the create new project page"""
824
    if not session.get('logged_in'):
825
        log("User with no valid session tries access to page /project-new", "FAIL", "HIGH")
826
        abort(401)     
827
    permissions("edit")
828
    return render_template('project-new.html', csrf_token=session['csrf_token'])
829
830
@app.route('/project-add', methods=['POST'])
831
@security
832
def add_entry():
833
    """add a new project to database"""
834
    if not session.get('logged_in'):
835
        log("User with no valid session tries access to page /project-add", "FAIL", "HIGH")
836
        abort(401)
837
    permissions("edit")
838
    check_token()
839
    db = get_db()
840
    valAlphaNum(request.form['inputName'], 1)
841
    valNum(request.form['inputVersion'], 1)
842
    safe_inputName = encodeInput(request.form['inputName'])
843
    safe_inputVersion = encodeInput(request.form['inputVersion'])
844
    safe_inputDesc = encodeInput(request.form['inputDesc'])
845
    date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
846
    db.execute('INSERT INTO projects (timestamp, projectName, projectVersion, projectDesc, userID, ownerID, groupID) VALUES (?, ?, ?, ?, ?, ?, ?)',
847
               [date, safe_inputName, safe_inputVersion, safe_inputDesc, session['userID'],  session['userID'], session['privateGroup']])
848
    db.commit()
849
    return redirect(url_for('project_list'))
850
851
@app.route('/assign-group', methods=['POST'])
852
@security
853
def assign_group():
854
    """add a new project to database"""
855
    if not session.get('logged_in'):
856
        log("User with no valid session tries access to page /assign-group", "FAIL", "HIGH")
857
        abort(401)
858
    permissions("edit")
859
    check_token()
860
    db = get_db()
861
    valNum(request.form['projectID'], 12)
862
    valNum(request.form['groupID'], 12)
863
    safe_groupID   = encodeInput(request.form['groupID'])
864
    safe_projectID = encodeInput(request.form['projectID'])
865
    """Check is submitted groupID is owned by user"""
866
    cur = db.execute('SELECT groupID from groups where ownerID=?',
867
    				   [session['userID']])
868
    owner = cur.fetchall()
869
    for val in owner:
870
        print(val)
871
        if int(safe_groupID) == int(val[0]):
872
            db.execute('UPDATE projects SET groupID=? WHERE projectID=? AND userID=?',
873
                   [safe_groupID, safe_projectID, session['userID']])
874
            db.commit()
875
    return redirect(url_for('project_list'))
876
877
@app.route('/project-del', methods=['POST'])
878
@security
879
def project_del():
880
    """delete project from database"""
881
    if not session.get('logged_in'):
882
        log("User with no valid session tries access to page /project-del", "FAIL", "HIGH")
883
        abort(401)
884
    permissions("delete")
885
    valNum(request.form['projectID'], 12)
886
    id = request.form['projectID']
887
    check_token()
888
    db = get_db()
889
    db.execute("DELETE FROM projects WHERE projectID=? AND userID=? AND ownerID=?",
890
               [id, session['userID'], session['userID']])
891
    db.commit()
892
    return redirect("/project-list")
893
894
@app.route('/project-list', methods=['GET'])
895
@security
896
def project_list():
897
    """show the project list page"""
898
    if not session.get('logged_in'):
899
        log("User with no valid session tries access to page /project-list", "FAIL", "HIGH")
900
        abort(401)
901
    permissions("read")
902
    db = get_db()  
903
    #First query is for the users own owned projects
904
    cur = db.execute('SELECT p.projectName, p.projectVersion, p.projectDESC, p.projectID, p.timestamp, p.groupID, g.groupName, g.groupID FROM projects as p JOIN groups as g ON g.groupID = p.groupID where p.userID=? ORDER BY projectID DESC',
905
                          [session['userID']])
906
    entries = cur.fetchall()
907
    #select the groups which can be selected by this user    
908
    cur3 = db.execute('SELECT * FROM groups WHERE ownerID=?',
909
                          [session['userID']])
910
    groups = cur3.fetchall()
911
    return render_template('project-list.html', entries=entries, groups=groups, csrf_token=session['csrf_token'])
912
    
913
@app.route('/project-shared', methods=['GET'])
914
@security
915
def project_shared():
916
    """show the project list page"""
917
    if not session.get('logged_in'):
918
        log("User with no valid session tries access to page /project-list", "FAIL", "HIGH")
919
        abort(401)
920
    permissions("read")
921
    db = get_db()
922
    #Here we see what projects this users was assigned to
923
    cur = db.execute('SELECT p.projectName, p.projectVersion, p.projectDESC, p.projectID, p.timestamp, p.groupID, p.ownerID, m.userID, m.groupID, u.userID, u.userName FROM projects as p JOIN groupMembers as m ON m.groupID = p.groupID JOIN users as u ON u.userID=p.ownerID where m.userID=? AND u.userName !=? ORDER BY p.projectID DESC',
924
                          [session['userID'], session['userName']])
925
    entries = cur.fetchall()
926
        
927
    return render_template('project-shared.html', entries=entries, csrf_token=session['csrf_token'])
928
929
@app.route('/project-options/<project_id>', methods=['GET'])
930
@security
931
def projects_options(project_id):
932
    """show the project options landing page"""
933
    if not session.get('logged_in'):
934
        log("User with no valid session tries access to page /project-options", "FAIL", "HIGH")
935
        abort(401)
936
    permissions("read")
937
    valNum(project_id, 12)
938
    safe_project_id = encodeInput(project_id)
939
    return render_template('project-options.html', project_id=safe_project_id, csrf_token=session['csrf_token'])
940
941
@app.route('/project-functions/<project_id>', methods=['GET'])
942
@security
943
def project_functions(project_id):
944
    """show the pproject functions page"""
945
    if not session.get('logged_in'):
946
        log("User with no valid session tries access to page /project-functions", "FAIL", "HIGH")
947
        abort(401)
948
    permissions("read")
949
    techlist = projects_functions_techlist()
950
    valNum(project_id, 12)
951
    safe_project_id = encodeInput(project_id)
952
    db = get_db()
953
    db.commit()
954
    cur = db.execute('SELECT p.paramID, p.functionName, p.functionDesc, p.projectID, p.userID, p.tech, p.techVuln, p.entryDate, t.techName, proj.projectID, proj.groupID, m.userID, m.groupID FROM parameters AS p JOIN techhacks AS t ON p.tech = t.techID JOIN projects as proj ON proj.projectID = p.projectID JOIN groupMembers as m ON m.groupID = proj.groupID WHERE proj.projectID=? AND m.userID=? GROUP BY t.techName',
955
                      [safe_project_id, session['userID']])
956
    entries = cur.fetchall()
957
    return render_template('project-functions.html', project_id=project_id, techlist=projects_functions_techlist(), entries=entries, csrf_token=session['csrf_token'])
958
959
@app.route('/project-function-del', methods=['POST'])
960
@security
961
def function_del():
962
    """delete a project function"""
963
    if not session.get('logged_in'):
964
        log( "User with no valid session tries access to page /project-function-del", "FAIL", "HIGH")
965
        abort(401)
966
    permissions("delete")
967
    check_token()
968
    valNum(request.form['projectID'], 12)
969
    valNum(request.form['paramID'], 12)
970
    id = request.form['projectID']
971
    id_param = int(request.form['paramID'])
972
    db = get_db()
973
    #First check if the user is allowed to delete this parameter
974
    cur = db.execute('SELECT p.projectID, p.groupID, m.groupID, m.userID from projects as p JOIN groupMembers as m ON m.groupID = p.groupID where m.userID=?',
975
    				   [session['userID']])
976
    for val in cur:
977
	    if int(id) == int(val[0]):
978
			db.execute("DELETE FROM parameters WHERE projectID=? AND paramID=?",
979
					   [id, id_param])
980
			db.commit()
981
			redirect_url = "/project-functions/"+str(id)
982
    return redirect(redirect_url)
983
984
985
@app.route('/project-function-add', methods=['POST'])
986
@security
987
def add_function():
988
    """add a project function"""
989
    if not session.get('logged_in'):
990
        log("User with no valid session tries access to page /project-function-add", "FAIL", "HIGH")
991
        abort(401)
992
    permissions("edit")
993
    check_token()
994
    valNum(request.form['project_id'], 12)
995
    id = request.form['project_id']
996
    valAlphaNum(request.form['functionName'], 1)
997
    valAlphaNum(request.form['functionDesc'], 1)
998
    safe_fName = encodeInput(request.form['functionName'])
999
    safe_fDesc = encodeInput(request.form['functionDesc'])	
1000
    
1001
    #Check is submitted projectID is owned by user
1002
    db = get_db()
1003
    cur3 = db.execute('SELECT p.projectID, p.groupID, m.groupID, m.userID from projects as p JOIN groupMembers as m ON m.groupID = p.groupID where m.userID=?',
1004
    				   [session['userID']])
1005
    owner = cur3.fetchall()
1006
    for val in owner:
1007
        print(val)
1008
        if int(id) == int(val[0]):
1009
			f = request.form
1010
			for key in f.keys():
1011
				for value in f.getlist(key):
1012
						found = key.find("test")
1013
						if found != -1:
1014
							db = get_db()
1015
							date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
1016
							items = value.split("-")
1017
							techID = items[2]
1018
							vulnID = items[0]
1019
							valAlphaNum(techID, 12)
1020
							valAlphaNum(vulnID, 12)
1021
							safe_techID = encodeInput(techID)
1022
							safe_vulnID = encodeInput(vulnID)
1023
							db.execute('INSERT INTO parameters (entryDate, functionName, functionDesc, techVuln, tech, projectID, userID) VALUES (?, ?, ?, ?, ?, ?, ?)',
1024
								   [date, safe_fName, safe_fDesc, safe_vulnID, safe_techID, id, session['userID']])
1025
							db.commit()
1026
    redirect_url = '/project-functions/'+str(id) 
1027
    return redirect(redirect_url)
1028
1029
@app.route('/project-checklist-add', methods=['POST'])
1030
@security
1031
def add_checklist():
1032
    """add project checklist"""
1033
    if not session.get('logged_in'):
1034
        log("User with no valid session tries access to page /project-checklist-add", "FAIL", "HIGH")
1035
        abort(401)
1036
    permissions("edit")
1037
    check_token()
1038
    i = 1
1039
    #We do valNum for projectID here because we need it in the comparison
1040
    valNum(request.form['projectID'], 12)
1041
    #Check is submitted projectID is owned by user
1042
    db = get_db()
1043
    cur3 = db.execute('SELECT p.projectID, p.groupID, m.groupID, m.userID from projects as p JOIN groupMembers as m ON m.groupID = p.groupID where m.userID=?',
1044
    				   [session['userID']])
1045
    owner = cur3.fetchall()
1046
    for val in owner:
1047
        print(val)
1048
        if int(request.form['projectID']) == int(val[0]):
1049
			f = request.form
1050
			for key in f.keys():
1051
				for value in f.getlist(key):
1052
					found = key.find("vuln")
1053
					if found != -1:
1054
						listID = "listID"+str(i)
1055
						answerID = "answer"+str(i)
1056
						questionID = "questionID"+str(i) 
1057
						vulnID = "vulnID"+str(i)
1058
						valAlphaNum(request.form[answerID], 12)
1059
						valNum(request.form[questionID], 12)
1060
						valNum(request.form[vulnID], 12)
1061
						valAlphaNum(request.form[listID], 12)
1062
						valAlphaNum(request.form['projectName'], 12)
1063
						safe_answerID = encodeInput(request.form[answerID])
1064
						safe_questionID = encodeInput(request.form[questionID])
1065
						safe_vulnID = encodeInput(request.form[vulnID])
1066
						safe_listID = encodeInput(request.form[listID])
1067
						safe_pName = encodeInput(request.form['projectName'])
1068
						safe_id = encodeInput(request.form['projectID'])
1069
						#print '        '+answerID+'="'+str(safe_answerID)+'",'
1070
						#print '        '+questionID+'="'+str(safe_questionID)+'",'
1071
						#print '        '+vulnID+'="'+str(safe_vulnID)+'",'
1072
						#print '        '+listID+'="'+str(safe_listID)+'",'
1073
						date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
1074
						db = get_db()
1075
						db.execute('INSERT INTO questionlist (entryDate, answer, projectName, projectID, questionID, vulnID, listName, userID) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
1076
								   [date, safe_answerID, safe_pName, safe_id, safe_questionID, safe_vulnID, safe_listID, session['userID']])
1077
						db.commit()
1078
						i += 1
1079
    redirect_url = "/results-checklists"
1080
    return redirect(redirect_url)
1081
1082
@app.route('/project-checklists/<project_id>', methods=['GET'])
1083
@security
1084
def project_checklists(project_id):
1085
    """show the project checklists page"""
1086
    if not session.get('logged_in'):
1087
        log( "User with no valid session tries access to page /project-checklists", "FAIL", "HIGH")
1088
        abort(401)
1089
    permissions("read")
1090
    valNum(project_id, 12)
1091
    safe_id = int(project_id, 12)
1092
    db = get_db()
1093
    cur = db.execute('SELECT p.projectID, p.userID, p.groupID, p.projectName, p.projectVersion, p.projectDesc, p.ownerID, m.userID, m.groupID FROM projects as p JOIN groupMembers AS m ON m.groupID = p.groupID WHERE p.projectID=? AND m.userID=?',
1094
                        [safe_id, session['userID']])
1095
    row = cur.fetchall()
1096
    prep = row[0]
1097
    projectName = prep[1]
1098
    owasp_items_lvl1 = []
1099
    owasp_items_lvl1_ygb = []
1100
    owasp_ids_lvl1 = []
1101
    owasp_kb_ids_lvl1 = []
1102
    owasp_content_lvl1 = []
1103
    owasp_content_desc_lvl1 = []
1104
    owasp_items_lvl2 = []
1105
    owasp_items_lvl2_ygb = []
1106
    owasp_ids_lvl2 = []
1107
    owasp_kb_ids_lvl2 = []
1108
    owasp_content_lvl2 = []
1109
    owasp_content_desc_lvl2 = []
1110
    owasp_items_lvl3 = []
1111
    owasp_items_lvl3_ygb = []
1112
    owasp_ids_lvl3 = []
1113
    owasp_kb_ids_lvl3 = []
1114
    owasp_content_lvl3 = []
1115
    owasp_content_desc_lvl3 = []
1116
    custom_items = []
1117
    custom_ids = []
1118
    custom_kb_ids = []
1119
    custom_content = []
1120
    basic_items = []
1121
    basic_ids = []
1122
    basic_kb_ids = []
1123
    basic_content = []
1124
    advanced_items = []
1125
    advanced_ids = []
1126
    advanced_kb_ids = []
1127
    advanced_content = []
1128
    full_file_paths = []
1129
    full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/checklists"))
1130
    full_file_paths.sort()
1131
    for path in full_file_paths:
1132
       found = path.find("ASVS-level-1")
1133
       if found != -1:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1134
            owasp_org_path = path
1135
            owasp_list_lvl1 = "ASVS-level-1"
1136
            owasp_path_lvl1 = path.split("-")
1137
            owasp_kb = owasp_path_lvl1[7]
1138
            owasp_id = get_num(owasp_path_lvl1[1])
1139
            #owasp_items_lvl1.append(owasp_checklist_name)
1140
            owasp_ids_lvl1.append(owasp_id)
1141
            owasp_items_lvl1_ygb.append(owasp_path_lvl1[9])
1142
            owasp_kb_ids_lvl1.append(owasp_kb)
1143
            filemd = open(owasp_org_path, 'r').read()
1144
            owasp_content_lvl1.append(Markup(markdown.markdown(filemd)))
1145
            full_file_paths_kb = get_filepaths(os.path.join(app.root_path, "markdown/knowledge_base"))
1146
            for path in full_file_paths_kb:
1147
                org_path = path
1148
                path_kb = path.split("markdown")
1149
                path_vuln = get_num(path_kb[1])
1150
                if int(owasp_kb) == int(path_vuln):
1151
                    filemd = open(org_path, 'r').read()
1152
                    description = filemd.split("**") 
1153
                    owasp_content_desc_lvl1.append(description[2])
1154
    for path in full_file_paths:
1155
       found = path.find("ASVS-level-2")
1156
       if found != -1:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1157
            owasp_org_path = path
1158
            owasp_list_lvl2 = "ASVS-level-2"
1159
            owasp_path_lvl2 = path.split("-")
1160
            owasp_kb = owasp_path_lvl2[7]
1161
            owasp_id = get_num(owasp_path_lvl2[1])
1162
            #owasp_items_lvl2.append(owasp_checklist_name)
1163
            owasp_ids_lvl2.append(owasp_id)
1164
            owasp_kb_ids_lvl2.append(owasp_kb)
1165
            owasp_items_lvl2_ygb.append(owasp_path_lvl2[9])
1166
            filemd = open(owasp_org_path, 'r').read()
1167
            owasp_content_lvl2.append(Markup(markdown.markdown(filemd)))
1168
            full_file_paths_kb = get_filepaths(os.path.join(app.root_path, "markdown/knowledge_base"))
1169
            for path in full_file_paths_kb:
1170
                org_path = path
1171
                path_kb = path.split("markdown")
1172
                path_vuln = get_num(path_kb[1])
1173
                if int(owasp_kb) == int(path_vuln):
1174
                    filemd = open(org_path, 'r').read()
1175
                    description = filemd.split("**") 
1176
                    owasp_content_desc_lvl2.append(description[2])
1177
    for path in full_file_paths:
1178
       found = path.find("ASVS-level-3")
1179
       if found != -1:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1180
            owasp_org_path = path
1181
            owasp_list_lvl3 = "ASVS-level-3"
1182
            owasp_path_lvl3 = path.split("-")
1183
            owasp_kb = owasp_path_lvl3[7]
1184
            owasp_id = get_num(owasp_path_lvl3[1])
1185
            #owasp_items_lvl3.append(owasp_checklist_name)
1186
            owasp_ids_lvl3.append(owasp_id)
1187
            owasp_kb_ids_lvl3.append(owasp_kb)
1188
            owasp_items_lvl3_ygb.append(owasp_path_lvl3[9])
1189
            filemd = open(owasp_org_path, 'r').read()
1190
            owasp_content_lvl3.append(Markup(markdown.markdown(filemd)))
1191
            full_file_paths_kb = get_filepaths(os.path.join(app.root_path, "markdown/knowledge_base"))
1192
            for path in full_file_paths_kb:
1193
                org_path = path
1194
                path_kb = path.split("markdown")
1195
                path_vuln = get_num(path_kb[1])
1196
                if int(owasp_kb) == int(path_vuln):
1197
                    filemd = open(org_path, 'r').read()
1198
                    description = filemd.split("**") 
1199
                    owasp_content_desc_lvl3.append(description[2])
1200
    for path in full_file_paths:
1201
       found = path.find("CS_basic_audit")
1202
       if found != -1:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1203
            basic_org_path = path
1204
            basic_list = "CS_basic_audit"
1205
            basic_path = path.split("-")
1206
            basic_kb = basic_path[5]
1207
            basic_checklist_name = basic_path[3]
1208
            basic_id = get_num(basic_path[1])
1209
            basic_items.append(basic_checklist_name)
1210
            basic_ids.append(basic_id)
1211
            basic_kb_ids.append(basic_kb)
1212
            filemd = open(basic_org_path, 'r').read()
1213
            basic_content.append(Markup(markdown.markdown(filemd)))
1214
    for path in full_file_paths:
1215
       found = path.find("CS_advanced_audit")
1216
       if found != -1:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1217
            advanced_org_path = path
1218
            advanced_list = "CS_advanced_audit"
1219
            advanced_path = path.split("-")
1220
            advanced_kb = advanced_path[5]
1221
            advanced_name = advanced_path[3]
1222
            advanced_id = get_num(advanced_path[1])
1223
            advanced_items.append(advanced_name)
1224
            advanced_ids.append(advanced_id)
1225
            advanced_kb_ids.append(advanced_kb)
1226
            filemd = open(advanced_org_path, 'r').read()
1227
            advanced_content.append(Markup(markdown.markdown(filemd)))
1228
    for path in full_file_paths:
1229
       found = path.find("custom")
1230
       if found != -1:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1231
            custom_org_path = path
1232
            custom_list = "custom"
1233
            custom_path = path.split("-")
1234
            custom_kb = custom_path[5]
1235
            custom_name = custom_path[3]
1236
            custom_id = get_num(custom_path[1])
1237
            custom_items.append(custom_name)
1238
            custom_ids.append(custom_id)
1239
            custom_kb_ids.append(custom_kb)
1240
            filemd = open(custom_org_path, 'r').read()
1241
            custom_content.append(Markup(markdown.markdown(filemd)))
1242
    return render_template('project-checklists.html', csrf_token=session['csrf_token'],  **locals())
1243
1244
@app.route('/results-checklists', methods=['GET'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1245
@security
1246
def results_checklists():
1247
    """show the results checklists page"""
1248
    if not session.get('logged_in'):
1249
        log( "User with no valid session tries access to page /results-checklists", "FAIL", "HIGH")
1250
        abort(401)
1251
    permissions("read")
1252
    db = get_db()
1253
    cur = db.execute('SELECT q.answer, q.projectID, q.questionID,  q.vulnID, q.listName, q.entryDate, p.projectName, p.projectVersion, p.projectDesc, p.groupID, m.groupID, m.userID FROM questionlist AS q JOIN projects AS p ON q.projectID = p.projectID JOIN groupMembers as m ON m.groupID = p.groupID WHERE m.userID=? GROUP BY q.listName, q.entryDate ORDER BY p.projectName ASC',
1254
                          [session['userID']])
1255
    entries = cur.fetchall()
1256
    return render_template('results-checklists.html', entries=entries, csrf_token=session['csrf_token'])
1257
1258
@app.route('/results-functions', methods=['GET'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1259
@security
1260
def results_functions():
1261
    """show the results functions page"""
1262
    if not session.get('logged_in'):
1263
        log( "User with no valid session tries access to page /results-functions", "FAIL", "HIGH")
1264
        abort(401)
1265
    permissions("read")
1266
    db = get_db()
1267
    cur = db.execute('SELECT p.projectName, p.projectID, par.entryDate, p.projectDesc, p.groupID, m.userID, m.groupID, p.projectVersion, par.paramID, par.functionName, par.projectID FROM projects AS p join parameters AS par on p.projectID = par.projectID JOIN groupMembers AS m ON m.groupID = p.groupID WHERE m.userID=? GROUP BY p.projectVersion ',
1268
                         [session['userID']])
1269
    entries = cur.fetchall()
1270
    return render_template('results-functions.html', entries=entries, csrf_token=session['csrf_token'])
1271
1272
@app.route('/results-functions-del', methods=['POST'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1273
@security
1274
def functions_del():
1275
    """delete functions result items"""
1276
    if not session.get('logged_in'):
1277
        log( "User with no valid session tries access to page /results-functions-del", "FAIL", "HIGH")
1278
        abort(401)
1279
    permissions("delete")
1280
    check_token()
1281
    valNum(request.form['projectID'], 12)
1282
    safe_entryDate = encodeInput(request.form['entryDate'])
1283
    safe_projectID = encodeInput(request.form['projectID'])
1284
    db = get_db()
1285
    
1286
    #Use select in order to see if this user is linked to project
1287
    cur = db.execute("SELECT p.projectID, p.groupID, m.groupID, m.userID FROM projects AS p JOIN groupMembers AS m ON m.groupID = p.groupID WHERE m.userID=?  ",
1288
               		[session['userID']])
1289
    entries = cur.fetchall()
1290
    for entry in entries:
1291
        if int(entry[0]) == int(safe_projectID):
1292
            db.execute("DELETE FROM parameters WHERE entryDate=? AND projectID=?",
1293
               [safe_entryDate, safe_projectID])
1294
            db.commit()
1295
    return redirect("/results-functions")
1296
1297
@app.route('/results-checklists-del', methods=['POST'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1298
@security
1299
def checklists_del():
1300
    """delete checklist result item"""
1301
    if not session.get('logged_in'):
1302
        log( "User with no valid session tries access to page /results-checklists-del", "FAIL", "HIGH")
1303
        abort(401)
1304
    permissions("delete")
1305
    check_token()
1306
    safe_entryDate = encodeInput(request.form['entryDate'])
1307
    valNum(request.form['projectID'], 12)
1308
    safe_projectID = encodeInput(request.form['projectID'])
1309
    db = get_db()
1310
    #Use select in order to see if this user is linked to project
1311
    cur = db.execute("SELECT p.projectID, p.groupID, m.groupID, m.userID FROM projects AS p JOIN groupMembers AS m ON m.groupID = p.groupID WHERE m.userID=?  ",
1312
               		[session['userID']])
1313
    entries = cur.fetchall()
1314
    for entry in entries:
1315
        if int(entry[0]) == int(safe_projectID):
1316
			db.execute("DELETE FROM questionlist WHERE entryDate=? AND projectID=? ",
1317
				   [safe_entryDate, safe_projectID])
1318
			db.commit()
1319
    return redirect("/results-checklists")
1320
1321
1322
@app.route('/results-checklist-report/<entryDate>', methods=['GET'])
1323
@security
1324
def checklist_results(entryDate):
1325
    """show checklist results report"""
1326
    if not session.get('logged_in'):
1327
        log( "User with no valid session tries access to page /results-checklist-report", "FAIL", "HIGH")
1328
        abort(401)
1329
    permissions("read")
1330
    ygb = []
1331
    id_items = []
1332
    questions = []
1333
    content = []
1334
    full_file_paths = []
1335
    safe_entryDate = encodeInput(entryDate)
1336
    db = get_db()
1337
    cur = db.execute("SELECT l.listID, l.answer, l.projectID, l.projectName, l.questionID, l.vulnID, l.listName, l.entryDate, l.userID, m.userID, m.groupID, p.projectID, p.groupID FROM questionlist AS l JOIN projects AS p ON p.projectID = l.projectID JOIN groupMembers AS m ON m.groupID = p.groupID WHERE l.answer='no' AND l.entryDate=? AND m.userID=?",
1338
               [safe_entryDate, session['userID']])
1339
    entries = cur.fetchall()
1340
    for entry in entries:
1341
        projectName = entry[3]
1342
        questionID = entry[4]
1343
        vulnID = entry[5]
1344
        listName = entry[6]
1345
        entryDate = entry[7]
1346
        full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/knowledge_base"))
1347
        for path in full_file_paths:
1348
            org_path = path
1349
            path = path.split("markdown")
1350
            path_vuln = get_num(path[1])
1351
            if int(vulnID) == int(path_vuln):
1352
                filemd = open(org_path, 'r').read()
1353
                content.append(Markup(markdown.markdown(filemd)))
1354
                full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/checklists"))
1355
                for path in full_file_paths:
1356
                    org_path = path
1357
                    custom_path = org_path.split("-")
1358
                    path_questionID = get_num(custom_path[1])
1359
                    if int(questionID) == int(path_questionID):
1360
                        filemd = open(org_path, 'r').read()
1361
                        questions.append(Markup(markdown.markdown(filemd)))
1362
                        custom_paths = org_path.split("-")
1363
                        found = custom_paths[3].find("ASVS")
1364
                        if found != -1:
1365
                            ygb.append(custom_paths[9])
1366
    return render_template('results-checklist-report.html', **locals())
1367
1368
1369
@app.route('/results-checklist-docx/<entryDate>')
1370
def download_file_checklist(entryDate):
1371
    """Download checklist results report in docx"""
1372
    if not session.get('logged_in'):
1373
        log( "User with no valid session tries access to page /results-checklist-docx", "FAIL", "HIGH")
1374
        abort(401)
1375
    permissions("read")
1376
    ygb_docx = []    
1377
    content_raw = []
1378
    content_checklist = []
1379
    content_title = []
1380
    safe_entryDate = encodeInput(entryDate)
1381
    db = get_db()
1382
    cur = db.execute("SELECT l.listID, l.answer, l.projectID, l.projectName, l.questionID, l.vulnID, l.listName, l.entryDate, l.userID, m.userID, m.groupID, p.projectID, p.groupID FROM questionlist AS l JOIN projects AS p ON p.projectID = l.projectID JOIN groupMembers AS m ON m.groupID = p.groupID WHERE l.answer='no' AND l.entryDate=? AND m.userID=?",
1383
               [safe_entryDate, session['userID']])
1384
    entries = cur.fetchall()
1385
    document = Document()
1386
    document.add_picture(os.path.join(app.root_path,'static/img/banner-docx.jpg'), width=Inches(5.125), height=Inches(1.042))
1387
    last_paragraph = document.paragraphs[-1] 
1388
    last_paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
1389
    #document.add_heading('Security Knowledge Framework', 0)
1390
    last_paragraph = document.paragraphs[-1] 
1391
    last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
1392
    p = document.add_paragraph()
1393
    projectName = entries[0][3]
1394
    listName = entries[0][6]
1395
    ygb = False
1396
    p.add_run('Used Checklist: '+listName)
1397
    p.add_run('\r\n')
1398
    p.add_run('Date: '+datetime.datetime.now().strftime("%Y-%m-%d %H:%M"))
1399
    p.add_run('\r\n')
1400
    p.add_run('Project: '+projectName)
1401
    document.add_page_break()
1402
    p = document.add_heading('Table of contents', level=1)
1403
    p.add_run('\r\n')
1404
    document.add_paragraph('Introduction')
1405
    for entry in entries:
1406
        projectName = entry[3]
1407
        questionID = entry[4]
1408
        vulnID = entry[5]
1409
        listName = entry[6]
1410
        entryDate = entry[7]
1411
        full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/knowledge_base"))
1412
        for path in full_file_paths:
1413
            org_path = path
1414
            path = path.split("markdown")
1415
            path_vuln = get_num(path[1])
1416
            if int(vulnID) == int(path_vuln):
1417
                filemd = open(org_path, 'r').read()
1418
                content = Markup(markdown.markdown(filemd))
1419
                text = ''.join(BeautifulSoup(content).findAll(text=True))
1420
                text_encode = text.encode('utf-8')
1421
                content_title.append(text_encode.splitlines()[0])
1422
                text_encode = text_encode.replace("Solution", "\nSolution");
1423
                content_raw.append(text_encode)
1424
                full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/checklists"))
1425
                for path in full_file_paths:
1426
                    org_path = path
1427
                    path = path.split("markdown")
1428
                    tmp_path = path[1].split("-")
1429
                    custom_path = get_num(tmp_path[0])
1430
                    path_questionID = custom_path
1431
                    if int(questionID) == int(path_questionID):
1432
                        filemd = open(org_path, 'r').read()
1433
                        content_checklist.append(Markup(markdown.markdown(filemd)))
1434
                        custom_paths = org_path.split("-")
1435
                        found = custom_paths[3].find("ASVS")
1436
                        if found != -1:
1437
                            ygb = True
1438
                            ygb_docx.append(custom_paths[9])
1439
    for item in content_title:
1440
        p = document.add_paragraph(item)
1441
        p.add_run()
1442
    document.add_page_break()
1443
    document.add_heading('Introduction', level=1)
1444
    p = document.add_paragraph(
1445
        'The security knowledge framework is composed by means of the highest security standards currently available and is designed to maintain the integrity of your application, so you and your costumers sensitive data is protected against hackers. This document is provided with a checklist in which the programmers of your application had to run through in order to provide a secure product.'
1446
    )
1447
    p.add_run('\n')
1448
    p = document.add_paragraph(
1449
        'In the post-development stage of the security knowledge framework the developer double-checks his application against a checklist which consists out of several questions asking the developer about different stages of development and the methodology of implementing different types of functionality the application contains. After filling in this checklist the developer gains feedback on the failed checklist items providing him with solutions about how to solve the additional vulnerability\'s found in the application.'
1450
    )
1451
    document.add_page_break()
1452
    i = 0
1453
    for item in content_raw:
1454
        document.add_heading(content_title[i], level=1)
1455
        result = re.sub("<p>", " ", content_checklist[i])
1456
        result1 = re.sub("</p>", " ", result)
1457
        document.add_heading(result1, level=4)
1458
        p = document.add_paragraph(item.partition("\n")[2])
1459
        if ygb == True:
1460
            if ygb_docx[i] == "b":
1461
                image = document.add_picture(os.path.join(app.root_path,'static/img/blue.png'), width=Inches(0.20))
1462
            elif ygb_docx[i] == "gb":
1463
                image = document.add_picture(os.path.join(app.root_path,'static/img/green.png'), width=Inches(0.20))
1464
                image = document.add_picture(os.path.join(app.root_path,'static/img/blue.png'), width=Inches(0.20))
1465
            elif ygb_docx[i] == "ygb":
1466
                image = document.add_picture(os.path.join(app.root_path,'static/img/yellow.png'), width=Inches(0.20))
1467
                image = document.add_picture(os.path.join(app.root_path,'static/img/green.png'), width=Inches(0.20))            
1468
                image = document.add_picture(os.path.join(app.root_path,'static/img/blue.png'), width=Inches(0.20))
1469
        p.add_run("\n")
1470
        document.add_page_break()
1471
        i += 1
1472
    document.save("checklist-security-report.docx")
1473
    headers = {"Content-Disposition": "attachment; filename=%s" % "checklist-security-report.docx"}
1474
    file_path = os.path.join(app.root_path, "checklist-security-report.docx")
1475
    with open("checklist-security-report.docx", 'rb') as f:
1476
        body = f.read()
1477
    return make_response((body, headers))
1478
    
1479
    
1480
@app.route('/results-function-report/<projectID>', methods=['GET'])
1481
@security
1482
def function_results(projectID):
1483
    """show checklist results report"""
1484
    if not session.get('logged_in'):
1485
        log( "User with no valid session tries access to page /results-function-report", "FAIL", "HIGH")
1486
        abort(401)
1487
    permissions("read")
1488
    id_items = []
1489
    content = []
1490
    full_file_paths = []
1491
    valNum(projectID, 12)
1492
    safe_id = encodeInput(projectID)
1493
    db = get_db()
1494
    cur = db.execute("SELECT projects.projectName, projects.projectID, projects.projectVersion, parameters.functionName, parameters.tech, parameters.functionDesc, parameters.entryDate, parameters.techVuln, techhacks.techName, projects.userID, projects.groupID, m.userID, m.groupID FROM projects JOIN parameters ON parameters.projectID=projects.projectID JOIN techhacks ON techhacks.techID  = parameters.tech JOIN groupMembers AS m ON m.groupID = projects.groupID WHERE parameters.projectID=? AND m.userID=? GROUP BY parameters.tech;",
1495
               [safe_id, session['userID']])
1496
    entries = cur.fetchall()
1497
    for entry in entries:
1498
        projectName = entry[0]
1499
        vulnID = entry[7]
1500
        full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/knowledge_base"))
1501
        for path in full_file_paths:
1502
            org_path = path
1503
            path = path.split("markdown")
1504
            path_vuln = get_num(path[1])
1505
            if int(vulnID) == int(path_vuln):
1506
                filemd = open(org_path, 'r').read()
1507
                content.append(Markup(markdown.markdown(filemd)))
1508
    return render_template('results-function-report.html', **locals())
1509
1510
@app.route('/results-function-docx/<projectID>')
1511
def download_file_function(projectID):
1512
    """Download checklist results report in docx"""
1513
    if not session.get('logged_in'):
1514
        log( "User with no valid session tries access to page /results-function-docx", "FAIL", "HIGH")
1515
        abort(401)
1516
    permissions("read")
1517
    content_raw = []
1518
    content_title = []
1519
    content_tech = []
1520
    valNum(projectID, 12)
1521
    safe_id = encodeInput(projectID)
1522
    db = get_db()
1523
    cur = db.execute("SELECT projects.projectName, projects.projectID, projects.projectVersion, parameters.functionName, parameters.tech, parameters.functionDesc, parameters.entryDate, parameters.techVuln, techhacks.techName, projects.userID, projects.groupID, m.userID, m.groupID FROM projects JOIN parameters ON parameters.projectID=projects.projectID JOIN techhacks ON techhacks.techID  = parameters.tech JOIN groupMembers AS m ON m.groupID = projects.groupID WHERE parameters.projectID=? AND m.userID=? GROUP BY parameters.tech;",
1524
               [safe_id, session['userID']])
1525
    entries = cur.fetchall()
1526
    document = Document()
1527
    document.add_picture(os.path.join(app.root_path,'static/img/banner-docx.jpg'), width=Inches(5.125), height=Inches(1.042))
1528
    last_paragraph = document.paragraphs[-1] 
1529
    last_paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
1530
    #document.add_heading('Security Knowledge Framework', 0)
1531
    last_paragraph = document.paragraphs[-1] 
1532
    last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
1533
    p = document.add_paragraph()
1534
    projectName = entries[0][0]
1535
    functionName = entries[0][3]
1536
    functionDesc= entries[0][5]
1537
    p.add_run('Date: '+datetime.datetime.now().strftime("%Y-%m-%d %H:%M"))
1538
    p.add_run('\r\n')
1539
    p.add_run('Project: '+projectName)
1540
    document.add_page_break()
1541
    p = document.add_heading('Table of contents', level=1)
1542
    p.add_run('\r\n')
1543
    document.add_paragraph('Introduction')
1544
    for entry in entries:
1545
        entryDate = entry[6]
1546
        vulnID = entry[7]
1547
        full_file_paths = get_filepaths(os.path.join(app.root_path, "markdown/knowledge_base"))
1548
        for path in full_file_paths:
1549
            org_path = path
1550
            path = path.split("markdown")
1551
            path_vuln = get_num(path[1])
1552
            if int(vulnID) == int(path_vuln):
1553
                filemd = open(org_path, 'r').read()
1554
                content = Markup(markdown.markdown(filemd))
1555
                text = ''.join(BeautifulSoup(content).findAll(text=True))
1556
                text_encode = text.encode('utf-8')
1557
                content_title.append(text_encode.splitlines()[0])
1558
                text_encode = text_encode.replace("Solution", "\nSolution");
1559
                content_raw.append(text_encode)
1560
    for item in content_title:
1561
        p = document.add_paragraph(item)
1562
        p.add_run()
1563
    document.add_page_break()
1564
    document.add_heading('Introduction', level=1)
1565
    p = document.add_paragraph(
1566
        'The security knowledge framework is composed by means of the highest security standards currently available and is designed to maintain the integrity of your application, so you and your costumers sensitive data is protected against hackers. This document is provided with a checklist in which the programmers of your application had to run through in order to provide a secure product.'
1567
    )
1568
    p.add_run('\n')
1569
    p = document.add_paragraph(
1570
        'In this part of security knowledge framework, al the parameters and variables are audited by means of the information given by the programmer such as the processing techniques. Each of these techniques contain different types of vulnerabilities when implemented in a improper fashion. This document will raise awareness about these vulnerabilities, as well as presenting solutions for the right implementation.'
1571
    )
1572
    document.add_page_break()
1573
    i = 0
1574
    for item in content_raw:
1575
        document.add_heading("Knowledge-Base: "+content_title[i], level=1)
1576
        document.add_heading("Technology: "+entries[i][8], level=2)
1577
        p = document.add_paragraph(item.partition("\n")[2])
1578
        p.add_run("\n")
1579
        document.add_page_break()
1580
        i += 1
1581
    document.save('function-security-report.docx')
1582
    headers = {"Content-Disposition": "attachment; filename=%s" % "function-security-report.docx"}
1583
    with open("function-security-report.docx", 'rb') as f:
1584
        body = f.read()
1585
    return make_response((body, headers))
1586
1587
if __name__ == "__main__":
1588
    #Command line options to enable debug and/or saas (bind to 0.0.0.0)
1589
    cmdargs = str(sys.argv)
1590
    total = len(sys.argv)
1591
    rand.cleanup()
1592
    csrf_token_raw = rand.bytes(128)
1593
    csrf_token = base64.b64encode(csrf_token_raw)
1594
    for i in xrange(total):
1595
        if (str(sys.argv[i][2:]) == "debug"):
1596
            # Load default config and override config from an environment variable
1597
            app.config.update(dict(
1598
            DEBUG=True
1599
            ))
1600
        if (str(sys.argv[i][2:]) == "saas"):
1601
            bindaddr = '0.0.0.0'
1602
    if os.path.isfile('server.crt') == False: 
1603
       app.run(host=bindaddr, port=5443, ssl_context='adhoc')
1604
    else:
1605
       context = SSL.Context(SSL.TLSv1_METHOD)
1606
       context = ('server.crt', 'server.key')
1607
       app.run(host=bindaddr, port=5443, ssl_context=context)
1608
1609
1610