Harden security
This commit is contained in:
1488
artifacts/audits/1-initial.json
Normal file
1488
artifacts/audits/1-initial.json
Normal file
File diff suppressed because it is too large
Load Diff
674
artifacts/audits/2-first-pass-fix.json
Normal file
674
artifacts/audits/2-first-pass-fix.json
Normal file
@@ -0,0 +1,674 @@
|
||||
|
||||
{
|
||||
"score": 58,
|
||||
"grade": "D",
|
||||
"gradeLabel": "Significant security risks",
|
||||
"totalFindings": 22,
|
||||
"totalDepVulns": 0,
|
||||
"categories": {
|
||||
"secrets": {
|
||||
"label": "Secrets",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"injection": {
|
||||
"label": "Code Vulnerabilities",
|
||||
"findingCount": 3,
|
||||
"deduction": 9,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 3,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"deps": {
|
||||
"label": "Dependencies",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"label": "Auth & Access Control",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"label": "Configuration",
|
||||
"findingCount": 4,
|
||||
"deduction": 10,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 4,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"supply-chain": {
|
||||
"label": "Supply Chain",
|
||||
"findingCount": 1,
|
||||
"deduction": 3,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 1,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"api": {
|
||||
"label": "API Security",
|
||||
"findingCount": 3,
|
||||
"deduction": 10,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 3,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"label": "AI/LLM Security",
|
||||
"findingCount": 11,
|
||||
"deduction": 10,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 11,
|
||||
"low": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"file": "/code/xf/GIA/Dockerfile",
|
||||
"line": 25,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"rule": "DOCKER_RUN_AS_ROOT",
|
||||
"title": "Docker: Running as Root",
|
||||
"description": "No USER instruction found. Container runs as root by default.",
|
||||
"fix": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"cwe": "CWE-250",
|
||||
"owasp": "A05:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/Dockerfile",
|
||||
"line": 28,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"rule": "DOCKER_RUN_AS_ROOT",
|
||||
"title": "Docker: Running as Root",
|
||||
"description": "No USER instruction found. Container runs as root by default.",
|
||||
"fix": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"cwe": "CWE-250",
|
||||
"owasp": "A05:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/Dockerfile",
|
||||
"line": 30,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"rule": "DOCKER_RUN_AS_ROOT",
|
||||
"title": "Docker: Running as Root",
|
||||
"description": "No USER instruction found. Container runs as root by default.",
|
||||
"fix": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"cwe": "CWE-250",
|
||||
"owasp": "A05:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/Dockerfile",
|
||||
"line": 31,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"rule": "DOCKER_RUN_AS_ROOT",
|
||||
"title": "Docker: Running as Root",
|
||||
"description": "No USER instruction found. Container runs as root by default.",
|
||||
"fix": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"cwe": "CWE-250",
|
||||
"owasp": "A05:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/clients/whatsapp.py",
|
||||
"line": 3398,
|
||||
"severity": "high",
|
||||
"category": "api",
|
||||
"rule": "API_UPLOAD_NO_TYPE_CHECK",
|
||||
"title": "API: File Upload Without Type Validation",
|
||||
"description": "File upload using original filename without type validation.",
|
||||
"fix": "Validate file extension and MIME type. Generate random filenames for storage.",
|
||||
"cwe": "CWE-434",
|
||||
"owasp": "A04:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/clients/xmpp.py",
|
||||
"line": 57,
|
||||
"severity": "high",
|
||||
"category": "api",
|
||||
"rule": "API_UPLOAD_NO_TYPE_CHECK",
|
||||
"title": "API: File Upload Without Type Validation",
|
||||
"description": "File upload using original filename without type validation.",
|
||||
"fix": "Validate file extension and MIME type. Generate random filenames for storage.",
|
||||
"cwe": "CWE-434",
|
||||
"owasp": "A04:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/security/attachments.py",
|
||||
"line": 83,
|
||||
"severity": "high",
|
||||
"category": "api",
|
||||
"rule": "API_UPLOAD_NO_TYPE_CHECK",
|
||||
"title": "API: File Upload Without Type Validation",
|
||||
"description": "File upload using original filename without type validation.",
|
||||
"fix": "Validate file extension and MIME type. Generate random filenames for storage.",
|
||||
"cwe": "CWE-434",
|
||||
"owasp": "A04:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/tests/test_attachment_security.py",
|
||||
"line": 29,
|
||||
"severity": "medium",
|
||||
"category": "ssrf",
|
||||
"rule": "SSRF_INTERNAL_IP",
|
||||
"title": "SSRF: Internal IP Pattern",
|
||||
"description": "Internal IP address in code. Verify it is not reachable via user-controlled URLs.",
|
||||
"fix": "Block private IP ranges in URL validation for user-supplied URLs",
|
||||
"cwe": "CWE-918",
|
||||
"owasp": "A10:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/tests/test_attachment_security.py",
|
||||
"line": 34,
|
||||
"severity": "medium",
|
||||
"category": "ssrf",
|
||||
"rule": "SSRF_INTERNAL_IP",
|
||||
"title": "SSRF: Internal IP Pattern",
|
||||
"description": "Internal IP address in code. Verify it is not reachable via user-controlled URLs.",
|
||||
"fix": "Block private IP ranges in URL validation for user-supplied URLs",
|
||||
"cwe": "CWE-918",
|
||||
"owasp": "A10:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/tests/test_attachment_security.py",
|
||||
"line": 35,
|
||||
"severity": "medium",
|
||||
"category": "ssrf",
|
||||
"rule": "SSRF_INTERNAL_IP",
|
||||
"title": "SSRF: Internal IP Pattern",
|
||||
"description": "Internal IP address in code. Verify it is not reachable via user-controlled URLs.",
|
||||
"fix": "Block private IP ranges in URL validation for user-supplied URLs",
|
||||
"cwe": "CWE-918",
|
||||
"owasp": "A10:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/requirements.txt",
|
||||
"line": 23,
|
||||
"severity": "medium",
|
||||
"category": "supply-chain",
|
||||
"rule": "UNPINNED_PYTHON_DEP",
|
||||
"title": "Unpinned Python Dependency: ./vendor/django-crud-mixins",
|
||||
"description": "Python dependency without version pin. Pin to a specific version for reproducible builds.",
|
||||
"fix": "Pin version: ./vendor/django-crud-mixins==x.y.z",
|
||||
"cwe": null,
|
||||
"owasp": null
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/clients/signalapi.py",
|
||||
"line": 411,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_NO_OUTPUT_FILTER",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"description": "LLM output used directly without filtering. May contain sensitive info or hallucinations.",
|
||||
"fix": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"cwe": "CWE-200",
|
||||
"owasp": "LLM02"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 739,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 744,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 758,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 850,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 1377,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 1382,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 1396,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/signal.py",
|
||||
"line": 189,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_NO_OUTPUT_FILTER",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"description": "LLM output used directly without filtering. May contain sensitive info or hallucinations.",
|
||||
"fix": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"cwe": "CWE-200",
|
||||
"owasp": "LLM02"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/signal.py",
|
||||
"line": 197,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_NO_OUTPUT_FILTER",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"description": "LLM output used directly without filtering. May contain sensitive info or hallucinations.",
|
||||
"fix": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"cwe": "CWE-200",
|
||||
"owasp": "LLM02"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/signal.py",
|
||||
"line": 206,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_NO_OUTPUT_FILTER",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"description": "LLM output used directly without filtering. May contain sensitive info or hallucinations.",
|
||||
"fix": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"cwe": "CWE-200",
|
||||
"owasp": "LLM02"
|
||||
}
|
||||
],
|
||||
"depVulns": [],
|
||||
"remediationPlan": [
|
||||
{
|
||||
"priority": 1,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"categoryLabel": "CONFIGURATION",
|
||||
"title": "Docker: Running as Root",
|
||||
"file": "Dockerfile:25",
|
||||
"action": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"effort": "low"
|
||||
},
|
||||
{
|
||||
"priority": 2,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"categoryLabel": "CONFIGURATION",
|
||||
"title": "Docker: Running as Root",
|
||||
"file": "Dockerfile:28",
|
||||
"action": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"effort": "low"
|
||||
},
|
||||
{
|
||||
"priority": 3,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"categoryLabel": "CONFIGURATION",
|
||||
"title": "Docker: Running as Root",
|
||||
"file": "Dockerfile:30",
|
||||
"action": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"effort": "low"
|
||||
},
|
||||
{
|
||||
"priority": 4,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"categoryLabel": "CONFIGURATION",
|
||||
"title": "Docker: Running as Root",
|
||||
"file": "Dockerfile:31",
|
||||
"action": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"effort": "low"
|
||||
},
|
||||
{
|
||||
"priority": 5,
|
||||
"severity": "high",
|
||||
"category": "api",
|
||||
"categoryLabel": "API SECURITY",
|
||||
"title": "API: File Upload Without Type Validation",
|
||||
"file": "core/clients/whatsapp.py:3398",
|
||||
"action": "Validate file extension and MIME type. Generate random filenames for storage.",
|
||||
"effort": "medium"
|
||||
},
|
||||
{
|
||||
"priority": 6,
|
||||
"severity": "high",
|
||||
"category": "api",
|
||||
"categoryLabel": "API SECURITY",
|
||||
"title": "API: File Upload Without Type Validation",
|
||||
"file": "core/clients/xmpp.py:57",
|
||||
"action": "Validate file extension and MIME type. Generate random filenames for storage.",
|
||||
"effort": "medium"
|
||||
},
|
||||
{
|
||||
"priority": 7,
|
||||
"severity": "high",
|
||||
"category": "api",
|
||||
"categoryLabel": "API SECURITY",
|
||||
"title": "API: File Upload Without Type Validation",
|
||||
"file": "core/security/attachments.py:83",
|
||||
"action": "Validate file extension and MIME type. Generate random filenames for storage.",
|
||||
"effort": "medium"
|
||||
},
|
||||
{
|
||||
"priority": 8,
|
||||
"severity": "medium",
|
||||
"category": "ssrf",
|
||||
"categoryLabel": "SSRF",
|
||||
"title": "SSRF: Internal IP Pattern",
|
||||
"file": "core/tests/test_attachment_security.py:29",
|
||||
"action": "Block private IP ranges in URL validation for user-supplied URLs",
|
||||
"effort": "medium"
|
||||
},
|
||||
{
|
||||
"priority": 9,
|
||||
"severity": "medium",
|
||||
"category": "ssrf",
|
||||
"categoryLabel": "SSRF",
|
||||
"title": "SSRF: Internal IP Pattern",
|
||||
"file": "core/tests/test_attachment_security.py:34",
|
||||
"action": "Block private IP ranges in URL validation for user-supplied URLs",
|
||||
"effort": "medium"
|
||||
},
|
||||
{
|
||||
"priority": 10,
|
||||
"severity": "medium",
|
||||
"category": "ssrf",
|
||||
"categoryLabel": "SSRF",
|
||||
"title": "SSRF: Internal IP Pattern",
|
||||
"file": "core/tests/test_attachment_security.py:35",
|
||||
"action": "Block private IP ranges in URL validation for user-supplied URLs",
|
||||
"effort": "medium"
|
||||
},
|
||||
{
|
||||
"priority": 11,
|
||||
"severity": "medium",
|
||||
"category": "supply-chain",
|
||||
"categoryLabel": "SUPPLY CHAIN",
|
||||
"title": "Unpinned Python Dependency: ./vendor/django-crud-mixins",
|
||||
"file": "requirements.txt:23",
|
||||
"action": "Pin version: ./vendor/django-crud-mixins==x.y.z",
|
||||
"effort": "medium"
|
||||
},
|
||||
{
|
||||
"priority": 12,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"file": "core/clients/signalapi.py:411",
|
||||
"action": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 13,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:739",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 14,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:744",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 15,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:758",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 16,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:850",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 17,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:1377",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 18,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:1382",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 19,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:1396",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 20,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"file": "core/views/signal.py:189",
|
||||
"action": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 21,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"file": "core/views/signal.py:197",
|
||||
"action": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 22,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"file": "core/views/signal.py:206",
|
||||
"action": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"effort": "high"
|
||||
}
|
||||
],
|
||||
"recon": {
|
||||
"frameworks": [
|
||||
"django"
|
||||
],
|
||||
"languages": [
|
||||
"python"
|
||||
],
|
||||
"apiRoutes": [
|
||||
"app/urls.py",
|
||||
"core/management/commands/backfill_xmpp_attachment_urls.py"
|
||||
],
|
||||
"authPatterns": [],
|
||||
"databases": [],
|
||||
"cloudProviders": [],
|
||||
"frontendExposure": [],
|
||||
"packageManagers": [
|
||||
"pip"
|
||||
],
|
||||
"cicd": [],
|
||||
"hasDockerfile": true,
|
||||
"hasTerraform": false,
|
||||
"hasKubernetes": false,
|
||||
"envFiles": [],
|
||||
"configFiles": []
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agent": "InjectionTester",
|
||||
"category": "injection",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "AuthBypassAgent",
|
||||
"category": "auth",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "SSRFProber",
|
||||
"category": "ssrf",
|
||||
"findingCount": 3,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "SupplyChainAudit",
|
||||
"category": "supply-chain",
|
||||
"findingCount": 1,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "ConfigAuditor",
|
||||
"category": "config",
|
||||
"findingCount": 4,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "LLMRedTeam",
|
||||
"category": "llm",
|
||||
"findingCount": 11,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "MobileScanner",
|
||||
"category": "mobile",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "GitHistoryScanner",
|
||||
"category": "history",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "CICDScanner",
|
||||
"category": "cicd",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "APIFuzzer",
|
||||
"category": "api",
|
||||
"findingCount": 3,
|
||||
"success": true
|
||||
}
|
||||
]
|
||||
}
|
||||
410
artifacts/audits/3-second-pass-fix.json
Normal file
410
artifacts/audits/3-second-pass-fix.json
Normal file
@@ -0,0 +1,410 @@
|
||||
|
||||
{
|
||||
"score": 74,
|
||||
"grade": "C",
|
||||
"gradeLabel": "Fix before shipping",
|
||||
"totalFindings": 10,
|
||||
"totalDepVulns": 0,
|
||||
"categories": {
|
||||
"secrets": {
|
||||
"label": "Secrets",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"injection": {
|
||||
"label": "Code Vulnerabilities",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"deps": {
|
||||
"label": "Dependencies",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"label": "Auth & Access Control",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"label": "Configuration",
|
||||
"findingCount": 1,
|
||||
"deduction": 8,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 1,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"supply-chain": {
|
||||
"label": "Supply Chain",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"api": {
|
||||
"label": "API Security",
|
||||
"findingCount": 1,
|
||||
"deduction": 8,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 1,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"label": "AI/LLM Security",
|
||||
"findingCount": 8,
|
||||
"deduction": 10,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 8,
|
||||
"low": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"file": "/code/xf/GIA/Dockerfile",
|
||||
"line": 26,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"rule": "DOCKER_RUN_AS_ROOT",
|
||||
"title": "Docker: Running as Root",
|
||||
"description": "No USER instruction found. Container runs as root by default.",
|
||||
"fix": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"cwe": "CWE-250",
|
||||
"owasp": "A05:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/security/attachments.py",
|
||||
"line": 113,
|
||||
"severity": "high",
|
||||
"category": "api",
|
||||
"rule": "API_UPLOAD_NO_TYPE_CHECK",
|
||||
"title": "API: File Upload Without Type Validation",
|
||||
"description": "File upload using original filename without type validation.",
|
||||
"fix": "Validate file extension and MIME type. Generate random filenames for storage.",
|
||||
"cwe": "CWE-434",
|
||||
"owasp": "A04:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 775,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 781,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 795,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 1418,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 1424,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/osint.py",
|
||||
"line": 1438,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_RAG_NO_VALIDATION",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"description": "User input passed directly to vector search/embedding without validation.",
|
||||
"fix": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"cwe": "CWE-20",
|
||||
"owasp": "LLM08"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/signal.py",
|
||||
"line": 202,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_NO_OUTPUT_FILTER",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"description": "LLM output used directly without filtering. May contain sensitive info or hallucinations.",
|
||||
"fix": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"cwe": "CWE-200",
|
||||
"owasp": "LLM02"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/core/views/signal.py",
|
||||
"line": 211,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"rule": "LLM_NO_OUTPUT_FILTER",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"description": "LLM output used directly without filtering. May contain sensitive info or hallucinations.",
|
||||
"fix": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"cwe": "CWE-200",
|
||||
"owasp": "LLM02"
|
||||
}
|
||||
],
|
||||
"depVulns": [],
|
||||
"remediationPlan": [
|
||||
{
|
||||
"priority": 1,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"categoryLabel": "CONFIGURATION",
|
||||
"title": "Docker: Running as Root",
|
||||
"file": "Dockerfile:26",
|
||||
"action": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"effort": "low"
|
||||
},
|
||||
{
|
||||
"priority": 2,
|
||||
"severity": "high",
|
||||
"category": "api",
|
||||
"categoryLabel": "API SECURITY",
|
||||
"title": "API: File Upload Without Type Validation",
|
||||
"file": "core/security/attachments.py:113",
|
||||
"action": "Validate file extension and MIME type. Generate random filenames for storage.",
|
||||
"effort": "medium"
|
||||
},
|
||||
{
|
||||
"priority": 3,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:775",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 4,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:781",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 5,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:795",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 6,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:1418",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 7,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:1424",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 8,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "RAG Pipeline Without Input Validation",
|
||||
"file": "core/views/osint.py:1438",
|
||||
"action": "Validate and sanitize input before embedding. Limit query length.",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 9,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"file": "core/views/signal.py:202",
|
||||
"action": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"effort": "high"
|
||||
},
|
||||
{
|
||||
"priority": 10,
|
||||
"severity": "medium",
|
||||
"category": "llm",
|
||||
"categoryLabel": "AI/LLM SECURITY",
|
||||
"title": "LLM Output Without Filtering",
|
||||
"file": "core/views/signal.py:211",
|
||||
"action": "Filter LLM output before displaying: remove PII, validate against expected format",
|
||||
"effort": "high"
|
||||
}
|
||||
],
|
||||
"recon": {
|
||||
"frameworks": [
|
||||
"django"
|
||||
],
|
||||
"languages": [
|
||||
"python"
|
||||
],
|
||||
"apiRoutes": [
|
||||
"app/urls.py",
|
||||
"core/management/commands/backfill_xmpp_attachment_urls.py"
|
||||
],
|
||||
"authPatterns": [],
|
||||
"databases": [],
|
||||
"cloudProviders": [],
|
||||
"frontendExposure": [],
|
||||
"packageManagers": [
|
||||
"pip"
|
||||
],
|
||||
"cicd": [],
|
||||
"hasDockerfile": true,
|
||||
"hasTerraform": false,
|
||||
"hasKubernetes": false,
|
||||
"envFiles": [],
|
||||
"configFiles": []
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agent": "InjectionTester",
|
||||
"category": "injection",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "AuthBypassAgent",
|
||||
"category": "auth",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "SSRFProber",
|
||||
"category": "ssrf",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "SupplyChainAudit",
|
||||
"category": "supply-chain",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "ConfigAuditor",
|
||||
"category": "config",
|
||||
"findingCount": 1,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "LLMRedTeam",
|
||||
"category": "llm",
|
||||
"findingCount": 8,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "MobileScanner",
|
||||
"category": "mobile",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "GitHistoryScanner",
|
||||
"category": "history",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "CICDScanner",
|
||||
"category": "cicd",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "APIFuzzer",
|
||||
"category": "api",
|
||||
"findingCount": 1,
|
||||
"success": true
|
||||
}
|
||||
]
|
||||
}
|
||||
212
artifacts/audits/4-third-pass-fix.json
Normal file
212
artifacts/audits/4-third-pass-fix.json
Normal file
@@ -0,0 +1,212 @@
|
||||
|
||||
{
|
||||
"score": 92,
|
||||
"grade": "A",
|
||||
"gradeLabel": "Ship it!",
|
||||
"totalFindings": 1,
|
||||
"totalDepVulns": 0,
|
||||
"categories": {
|
||||
"secrets": {
|
||||
"label": "Secrets",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"injection": {
|
||||
"label": "Code Vulnerabilities",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"deps": {
|
||||
"label": "Dependencies",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"label": "Auth & Access Control",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"label": "Configuration",
|
||||
"findingCount": 1,
|
||||
"deduction": 8,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 1,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"supply-chain": {
|
||||
"label": "Supply Chain",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"api": {
|
||||
"label": "API Security",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"label": "AI/LLM Security",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"file": "/code/xf/GIA/Dockerfile",
|
||||
"line": 26,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"rule": "DOCKER_RUN_AS_ROOT",
|
||||
"title": "Docker: Running as Root",
|
||||
"description": "No USER instruction found. Container runs as root by default.",
|
||||
"fix": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"cwe": "CWE-250",
|
||||
"owasp": "A05:2021"
|
||||
}
|
||||
],
|
||||
"depVulns": [],
|
||||
"remediationPlan": [
|
||||
{
|
||||
"priority": 1,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"categoryLabel": "CONFIGURATION",
|
||||
"title": "Docker: Running as Root",
|
||||
"file": "Dockerfile:26",
|
||||
"action": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"effort": "low"
|
||||
}
|
||||
],
|
||||
"recon": {
|
||||
"frameworks": [
|
||||
"django"
|
||||
],
|
||||
"languages": [
|
||||
"python"
|
||||
],
|
||||
"apiRoutes": [
|
||||
"app/urls.py",
|
||||
"core/management/commands/backfill_xmpp_attachment_urls.py"
|
||||
],
|
||||
"authPatterns": [],
|
||||
"databases": [],
|
||||
"cloudProviders": [],
|
||||
"frontendExposure": [],
|
||||
"packageManagers": [
|
||||
"pip"
|
||||
],
|
||||
"cicd": [],
|
||||
"hasDockerfile": true,
|
||||
"hasTerraform": false,
|
||||
"hasKubernetes": false,
|
||||
"envFiles": [],
|
||||
"configFiles": []
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agent": "InjectionTester",
|
||||
"category": "injection",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "AuthBypassAgent",
|
||||
"category": "auth",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "SSRFProber",
|
||||
"category": "ssrf",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "SupplyChainAudit",
|
||||
"category": "supply-chain",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "ConfigAuditor",
|
||||
"category": "config",
|
||||
"findingCount": 1,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "LLMRedTeam",
|
||||
"category": "llm",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "MobileScanner",
|
||||
"category": "mobile",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "GitHistoryScanner",
|
||||
"category": "history",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "CICDScanner",
|
||||
"category": "cicd",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "APIFuzzer",
|
||||
"category": "api",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
}
|
||||
]
|
||||
}
|
||||
234
artifacts/audits/5-final-pass-fix.json
Normal file
234
artifacts/audits/5-final-pass-fix.json
Normal file
@@ -0,0 +1,234 @@
|
||||
|
||||
{
|
||||
"score": 90,
|
||||
"grade": "A",
|
||||
"gradeLabel": "Ship it!",
|
||||
"totalFindings": 2,
|
||||
"totalDepVulns": 0,
|
||||
"categories": {
|
||||
"secrets": {
|
||||
"label": "Secrets",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"injection": {
|
||||
"label": "Code Vulnerabilities",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"deps": {
|
||||
"label": "Dependencies",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"label": "Auth & Access Control",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"label": "Configuration",
|
||||
"findingCount": 2,
|
||||
"deduction": 10,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 2,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"supply-chain": {
|
||||
"label": "Supply Chain",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"api": {
|
||||
"label": "API Security",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"label": "AI/LLM Security",
|
||||
"findingCount": 0,
|
||||
"deduction": 0,
|
||||
"counts": {
|
||||
"critical": 0,
|
||||
"high": 0,
|
||||
"medium": 0,
|
||||
"low": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"file": "/code/xf/GIA/Dockerfile",
|
||||
"line": 26,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"rule": "DOCKER_RUN_AS_ROOT",
|
||||
"title": "Docker: Running as Root",
|
||||
"description": "No USER instruction found. Container runs as root by default.",
|
||||
"fix": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"cwe": "CWE-250",
|
||||
"owasp": "A05:2021"
|
||||
},
|
||||
{
|
||||
"file": "/code/xf/GIA/Dockerfile",
|
||||
"line": 1,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"rule": "DOCKER_NO_USER",
|
||||
"title": "Dockerfile: No Non-Root USER",
|
||||
"description": "No USER instruction found. Container runs as root, enabling escape attacks.",
|
||||
"fix": "Add before CMD: RUN addgroup -S app && adduser -S app -G app\nUSER app",
|
||||
"cwe": null,
|
||||
"owasp": null
|
||||
}
|
||||
],
|
||||
"depVulns": [],
|
||||
"remediationPlan": [
|
||||
{
|
||||
"priority": 1,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"categoryLabel": "CONFIGURATION",
|
||||
"title": "Docker: Running as Root",
|
||||
"file": "Dockerfile:26",
|
||||
"action": "Add USER nonroot before CMD/ENTRYPOINT",
|
||||
"effort": "low"
|
||||
},
|
||||
{
|
||||
"priority": 2,
|
||||
"severity": "high",
|
||||
"category": "config",
|
||||
"categoryLabel": "CONFIGURATION",
|
||||
"title": "Dockerfile: No Non-Root USER",
|
||||
"file": "Dockerfile:1",
|
||||
"action": "Add before CMD: RUN addgroup -S app && adduser -S app -G app\nUSER app",
|
||||
"effort": "low"
|
||||
}
|
||||
],
|
||||
"recon": {
|
||||
"frameworks": [
|
||||
"django"
|
||||
],
|
||||
"languages": [
|
||||
"python"
|
||||
],
|
||||
"apiRoutes": [
|
||||
"app/urls.py",
|
||||
"core/management/commands/backfill_xmpp_attachment_urls.py"
|
||||
],
|
||||
"authPatterns": [],
|
||||
"databases": [],
|
||||
"cloudProviders": [],
|
||||
"frontendExposure": [],
|
||||
"packageManagers": [
|
||||
"pip"
|
||||
],
|
||||
"cicd": [],
|
||||
"hasDockerfile": true,
|
||||
"hasTerraform": false,
|
||||
"hasKubernetes": false,
|
||||
"envFiles": [],
|
||||
"configFiles": []
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agent": "InjectionTester",
|
||||
"category": "injection",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "AuthBypassAgent",
|
||||
"category": "auth",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "SSRFProber",
|
||||
"category": "ssrf",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "SupplyChainAudit",
|
||||
"category": "supply-chain",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "ConfigAuditor",
|
||||
"category": "config",
|
||||
"findingCount": 2,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "LLMRedTeam",
|
||||
"category": "llm",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "MobileScanner",
|
||||
"category": "mobile",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "GitHistoryScanner",
|
||||
"category": "history",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "CICDScanner",
|
||||
"category": "cicd",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"agent": "APIFuzzer",
|
||||
"category": "api",
|
||||
"findingCount": 0,
|
||||
"success": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
# Feature Plan: Canonical Conversation Events (Append-Only Timeline)
|
||||
|
||||
## Goal
|
||||
Introduce a canonical append-only event log for conversations so adapters remain stateless and replay/debugging become deterministic.
|
||||
|
||||
## Why This Fits GIA
|
||||
- GIA already has `Person`, `PersonIdentifier`, `ChatSession`, `Message` and multi-transport routing.
|
||||
- This adds a durable event backbone without replacing current UI/features.
|
||||
|
||||
## Scope
|
||||
- Add `ConversationEvent` model (append-only).
|
||||
- Event types: `message_created`, `message_edited`, `message_deleted`, `reaction_added`, `reaction_removed`, `read_receipt`, `media_attached`, `participant_added`, `participant_removed`.
|
||||
- Persist source metadata: transport, upstream IDs, timestamps, actor, payload.
|
||||
- Write events from transport ingress and internal compose actions.
|
||||
- Build replay utility for one chat/session.
|
||||
|
||||
## Implementation
|
||||
1. Add model + migration + indexes (`session`, `event_type`, `created_at`, `origin_transport+origin_message_id`).
|
||||
2. Add write helper in a new module (`core/events/ledger.py`).
|
||||
3. Update signal/whatsapp/xmpp ingress handlers to emit canonical events.
|
||||
4. Update compose send/reaction/edit/delete paths to emit canonical events.
|
||||
5. Add admin/diagnostic read view for event stream by session.
|
||||
6. Add replay command to regenerate derived projections.
|
||||
|
||||
## Acceptance Criteria
|
||||
- Every new message/reaction/edit/delete creates exactly one canonical event.
|
||||
- Event ordering is deterministic per session.
|
||||
- Replay reproduces message projection for a selected session.
|
||||
- No adapter requires business logic to infer missing event state.
|
||||
|
||||
## Risks
|
||||
- Double-write races during transition.
|
||||
- Backfill complexity for old messages.
|
||||
|
||||
## Out of Scope
|
||||
- Full migration of all legacy records in one release.
|
||||
@@ -7,6 +7,22 @@ Define transport feature capabilities centrally so router/policy/UI can make det
|
||||
- GIA currently spans Signal/WhatsApp/Instagram/XMPP with uneven feature support.
|
||||
- Prevents silent failures (for example reaction exists internally but cannot be sent outward).
|
||||
|
||||
## How It Follows Plan 1
|
||||
- Plan 1 established canonical event flow as the shared source language for transport actions.
|
||||
- Plan 2 uses that event flow to gate what may be attempted per transport before adapter calls.
|
||||
- Interlink:
|
||||
- Canonical events define **what happened** (`reaction_added`, `message_edited`, etc.).
|
||||
- Capability matrix defines **what is allowed** on each service at execution time.
|
||||
- Together they prevent drift:
|
||||
- no silent no-op on unsupported features,
|
||||
- no adapter-specific policy branching,
|
||||
- deterministic user-visible failure reasons.
|
||||
|
||||
## Required Inputs From Plan 1
|
||||
- Canonical event types and normalized action shapes are stable.
|
||||
- Event write path exists for ingress/outbound actions.
|
||||
- Traceability exists for diagnostics (`trace_id`, source transport metadata).
|
||||
|
||||
## Scope
|
||||
- Add capability registry per transport.
|
||||
- Features: reactions, edits, deletes, threaded replies, typing, media classes, read receipts, participant events.
|
||||
@@ -23,6 +39,7 @@ Define transport feature capabilities centrally so router/policy/UI can make det
|
||||
- Unsupported action never calls transport adapter.
|
||||
- User receives explicit, actionable error.
|
||||
- Service capabilities are test-covered and easy to update.
|
||||
- Capability decisions are traceable against canonical event/action context.
|
||||
|
||||
## Out of Scope
|
||||
- Dynamic remote capability negotiation.
|
||||
|
||||
2
artifacts/plans/14-security-audit.md
Normal file
2
artifacts/plans/14-security-audit.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# 14) Run security audit using artifacts/1-initial.json. Generated using ship-safe.
|
||||
https://github.com/asamassekou10/ship-safe
|
||||
@@ -1,9 +0,0 @@
|
||||
# 14) Sensitive Information Hygiene
|
||||
|
||||
## Goal
|
||||
Detect and remove sensitive data exposure from code, config, logs, and payload surfaces.
|
||||
|
||||
## Minimal Plan
|
||||
1. Add a repeatable scan for sensitive patterns across repo and runtime-generated artifacts.
|
||||
2. Expunge discovered sensitive values and replace with safe placeholders or references.
|
||||
3. Add guardrails to prevent reintroduction and document the remediation workflow.
|
||||
@@ -10,4 +10,10 @@ This group has no derived tasks yet. To start populating this view:
|
||||
|
||||
|
||||
|
||||
task settings sound complicated, make them simpler
|
||||
task settings sound complicated, make them simpler
|
||||
|
||||
--
|
||||
|
||||
# https://gia.zm.is/settings/system/
|
||||
assume the user cannot access the log
|
||||
Use a trace id from the dropdown (recent traces), Event Ledger Smoke `sample[].trace_id`, or UR logs.
|
||||
Reference in New Issue
Block a user