|
from flask import Flask, jsonify, render_template |
|
import json |
|
import random |
|
|
|
app = Flask(__name__) |
|
|
|
|
|
package_json_data = """ |
|
{ |
|
"name": "auth-service", |
|
"version": "1.0.0", |
|
"description": "Pizza delivery Application ", |
|
"main": "index.js", |
|
"scripts": { |
|
"build": "tsc", |
|
"dev": "cross-env NODE_ENV=dev nodemon --legacy-watch src/server.ts", |
|
"format:fix": "prettier . --write", |
|
"format:check": "prettier . --check", |
|
"lint:fix": "eslint --fix .", |
|
"lint:check": "eslint .", |
|
"test": "jest --no-cache --runInBand --coverage --all", |
|
"test:watch": "jest --watch --runInBand", |
|
"prepare": "husky", |
|
"start": "ts-node src/index.ts", |
|
"migration:generate": "typeorm-ts-node-commonjs migration:generate -d ./src/config/data-source.ts", |
|
"migration:create": "typeorm-ts-node-commonjs migration:create", |
|
"migration:run": "typeorm-ts-node-commonjs migration:run -d ./src/config/data-source.ts" |
|
}, |
|
"keywords": [ |
|
"typescript", |
|
"postgres" |
|
], |
|
"author": "Kunal Kharat <[email protected]>", |
|
"license": "ISC", |
|
"devDependencies": { |
|
"@eslint/js": "^9.17.0", |
|
"@types/cookie-parser": "^1.4.8", |
|
"@types/cors": "^2.8.17", |
|
"@types/express": "^5.0.0", |
|
"@types/http-errors": "^2.0.4", |
|
"@types/jest": "^29.5.14", |
|
"@types/jsonwebtoken": "^9.0.8", |
|
"@types/lint-staged": "^13.3.0", |
|
"@types/node": "^22.10.2", |
|
"@types/supertest": "^6.0.2", |
|
"cross-env": "^7.0.3", |
|
"eslint": "^9.17.0", |
|
"husky": "^9.1.7", |
|
"jest": "^29.7.0", |
|
"nodemon": "^3.1.9", |
|
"prettier": "3.4.2", |
|
"ts-jest": "^29.2.5", |
|
"ts-node": "10.9.1", |
|
"typescript": "^5.7.2", |
|
"typescript-eslint": "^8.18.2" |
|
}, |
|
"dependencies": { |
|
"bcryptjs": "^3.0.2", |
|
"class-validator": "^0.14.1", |
|
"cookie-parser": "^1.4.7", |
|
"cors": "^2.8.5", |
|
"dotenv": "^16.4.7", |
|
"express": "^4.21.2", |
|
"express-jwt": "^8.5.1", |
|
"express-validator": "^7.2.1", |
|
"http-errors": "^2.0.0", |
|
"jsonwebtoken": "^9.0.2", |
|
"jwks-rsa": "^3.1.0", |
|
"lint-staged": "^15.3.0", |
|
"mock-jwks": "^3.3.4", |
|
"pg": "^8.4.0", |
|
"reflect-metadata": "^0.1.13", |
|
"rsa-pem-to-jwk": "^1.1.3", |
|
"supertest": "^7.0.0", |
|
"typeorm": "0.3.20", |
|
"uuid": "^11.1.0", |
|
"winston": "^3.17.0", |
|
"node-serialize": "0.0.4", |
|
"express-fileupload": "1.1.1-alpha.1", |
|
"jquery": "1.12.4", |
|
"lodash": "4.17.4" |
|
}, |
|
"lint-staged": { |
|
"*.ts": [ |
|
"npm run format:fix", |
|
"npm run lint:fix" |
|
] |
|
} |
|
} |
|
""" |
|
|
|
|
|
|
|
simulated_vulnerabilities = { |
|
"node-serialize": { |
|
"score": 9.8, |
|
"level": "Critical", |
|
"probability": 95, |
|
"reason": "Deserialization vulnerability allows remote code execution.", |
|
"resolution": "This package is deprecated and highly insecure. Remove it and use a safe alternative for serialization (e.g., JSON.stringify/parse with caution, or specific libraries for structured data).", |
|
"cve": "CVE-2017-5929" |
|
}, |
|
"express-fileupload": { |
|
"score": 8.1, |
|
"level": "High", |
|
"probability": 80, |
|
"reason": "Potential path traversal or denial-of-service vulnerabilities in older versions.", |
|
"resolution": "Upgrade to the latest stable version (e.g., >14.0.0) and ensure proper input validation and file handling.", |
|
"cve": "CVE-XXXX-YYYY (Example)" |
|
}, |
|
"jquery": { |
|
"score": 6.1, |
|
"level": "Medium", |
|
"probability": 65, |
|
"reason": "Cross-Site Scripting (XSS) vulnerabilities in older versions due to improper handling of HTML/DOM manipulation.", |
|
"resolution": "Upgrade to a recent version (e.g., >3.5.0) and use safe methods for DOM manipulation.", |
|
"cve": "CVE-2020-11022, CVE-2020-11023" |
|
}, |
|
"lodash": { |
|
"score": 7.5, |
|
"level": "High", |
|
"probability": 70, |
|
"reason": "Prototype pollution vulnerabilities allow attackers to add or modify properties of Object.prototype.", |
|
"resolution": "Upgrade to version 4.17.21 or later.", |
|
"cve": "CVE-2019-10744" |
|
}, |
|
"jsonwebtoken": { |
|
"score": 5.3, |
|
"level": "Medium", |
|
"probability": 50, |
|
"reason": "Vulnerabilities related to algorithm confusion or improper key handling in older versions or specific configurations.", |
|
"resolution": "Ensure you are using a recent version and explicitly specify secure algorithms (e.g., RS256, HS256) and verify keys correctly.", |
|
"cve": "CVE-2015-9283 (Example)" |
|
} |
|
|
|
} |
|
|
|
@app.route('/') |
|
def index(): |
|
"""Serve the main HTML dashboard page.""" |
|
return render_template('index.html') |
|
|
|
@app.route('/data') |
|
def get_dependency_data(): |
|
"""Provide dependency and simulated vulnerability data as JSON.""" |
|
try: |
|
package_data = json.loads(package_json_data) |
|
except json.JSONDecodeError: |
|
return jsonify({"error": "Failed to parse package.json data"}), 500 |
|
|
|
dependencies = [] |
|
vulnerable_count = 0 |
|
prod_count = 0 |
|
dev_count = 0 |
|
vulnerable_prod_count = 0 |
|
vulnerable_dev_count = 0 |
|
vulnerability_levels = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0, "None": 0} |
|
vulnerable_packages_list = [] |
|
total_vulnerability_score_sum = 0 |
|
|
|
|
|
for name, version in package_data.get('dependencies', {}).items(): |
|
prod_count += 1 |
|
dep_info = { |
|
"name": name, |
|
"version": version, |
|
"type": "production", |
|
"is_vulnerable": False, |
|
"vulnerability": None |
|
} |
|
if name in simulated_vulnerabilities: |
|
dep_info["is_vulnerable"] = True |
|
dep_info["vulnerability"] = simulated_vulnerabilities[name] |
|
vulnerable_count += 1 |
|
vulnerable_prod_count += 1 |
|
level = simulated_vulnerabilities[name].get("level", "Unknown") |
|
vulnerability_levels[level] = vulnerability_levels.get(level, 0) + 1 |
|
score = simulated_vulnerabilities[name].get("score", 0) |
|
vulnerable_packages_list.append({ |
|
"name": name, |
|
"score": score |
|
}) |
|
total_vulnerability_score_sum += score |
|
else: |
|
vulnerability_levels["None"] += 1 |
|
|
|
dependencies.append(dep_info) |
|
|
|
|
|
for name, version in package_data.get('devDependencies', {}).items(): |
|
dev_count += 1 |
|
dep_info = { |
|
"name": name, |
|
"version": version, |
|
"type": "development", |
|
"is_vulnerable": False, |
|
"vulnerability": None |
|
} |
|
|
|
if name in simulated_vulnerabilities: |
|
dep_info["is_vulnerable"] = True |
|
dep_info["vulnerability"] = simulated_vulnerabilities[name] |
|
vulnerable_count += 1 |
|
vulnerable_dev_count += 1 |
|
level = simulated_vulnerabilities[name].get("level", "Unknown") |
|
vulnerability_levels[level] = vulnerability_levels.get(level, 0) + 1 |
|
score = simulated_vulnerabilities[name].get("score", 0) |
|
vulnerable_packages_list.append({ |
|
"name": name, |
|
"score": score |
|
}) |
|
total_vulnerability_score_sum += score |
|
else: |
|
vulnerability_levels["None"] += 1 |
|
|
|
|
|
dependencies.append(dep_info) |
|
|
|
total_dependencies = len(dependencies) |
|
|
|
|
|
|
|
overall_risk_score = (total_vulnerability_score_sum / vulnerable_count) if vulnerable_count > 0 else 0 |
|
|
|
|
|
|
|
data = { |
|
"project_name": package_data.get("name", "Unknown Project"), |
|
"project_version": package_data.get("version", "N/A"), |
|
"total_dependencies": total_dependencies, |
|
"vulnerable_dependencies_count": vulnerable_count, |
|
"secure_dependencies_count": total_dependencies - vulnerable_count, |
|
"prod_dependencies_count": prod_count, |
|
"dev_dependencies_count": dev_count, |
|
"vulnerable_prod_count": vulnerable_prod_count, |
|
"vulnerable_dev_count": vulnerable_dev_count, |
|
"vulnerability_levels_distribution": vulnerability_levels, |
|
"vulnerable_packages_scores": vulnerable_packages_list, |
|
"overall_risk_score": round(overall_risk_score, 2), |
|
"dependencies": dependencies |
|
} |
|
|
|
return jsonify(data) |
|
|
|
if __name__ == '__main__': |
|
|
|
|
|
app.run(debug=True) |