rajkhanke's picture
Update app.py
d36211d verified
from flask import Flask, jsonify, render_template
import json
import random # Used for simulating probability
app = Flask(__name__)
# Your provided package.json data
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"
]
}
}
"""
# Simulate vulnerability data for some packages (based on common knowledge of older versions)
# In a real app, this would come from a security scanner API
simulated_vulnerabilities = {
"node-serialize": {
"score": 9.8,
"level": "Critical",
"probability": 95, # Simulated probability
"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" # Example CVE
},
"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" # Examples
},
"lodash": {
"score": 7.5,
"level": "High", # Prototype pollution can be high impact
"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" # Example
},
"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)"
}
# Add more simulated vulnerabilities as needed
}
@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 calculating average score
# Process dependencies
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 # Add score to sum
else:
vulnerability_levels["None"] += 1
dependencies.append(dep_info)
# Process devDependencies
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
}
# Dev dependencies can also have vulnerabilities, check against simulated data
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 # Add score to sum
else:
vulnerability_levels["None"] += 1
dependencies.append(dep_info)
total_dependencies = len(dependencies)
# Calculate Overall Risk Score (Simple average of vulnerable package scores)
# A more sophisticated score would weight by level, probability, or context
overall_risk_score = (total_vulnerability_score_sum / vulnerable_count) if vulnerable_count > 0 else 0
# Prepare data for charts and summary
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, # For bar chart
"overall_risk_score": round(overall_risk_score, 2), # Rounded for display
"dependencies": dependencies # For the table
}
return jsonify(data)
if __name__ == '__main__':
# Use debug=True for development, turn off for production
app.run(debug=True)