Skip to content

Repository files navigation

πŸ›‘οΈ PDF Malware Detection System

Machine Learning + AI-Powered PDF Risk Analyzer

Spring Boot Microservices | FastAPI ML Model | Local Ollama LLM | Streamlit Frontend


πŸ“Œ Overview

This system analyzes PDF files for malware using a hybrid approach that combines:

  1. Machine Learning Model (Python/FastAPI) β†’ predicts malicious / benign
  2. PDF structure feature extraction using PDFBox (Java)
  3. AI LLM-based analysis generated via a local Ollama model
  4. Streamlit Frontend β†’ uploads files and displays the HTML report

The system produces:

  • ML prediction
  • Confidence score
  • Extracted PDF features
  • AI-generated malware analysis report (HTML)
  • Beautiful report rendered inside the Streamlit UI

⭐ Features

  • πŸ“„ PDF feature extraction (metadata, objects, scripts, encryption, page data)
  • 🧠 ML-based malware prediction (malicious, benign)
  • πŸ€– LLM-generated HTML analysis via Ollama
  • πŸ” Base64-encoded HTML response for security
  • 🎨 Streamlit UI with fixed light background for dark mode users
  • ⚑ Optimized for < 15 second response time using lightweight local models
  • 🧱 Modular, scalable, extendable architecture
  • ☸️ Production-ready Kubernetes deployment with HPA, Ingress, ConfigMaps & Secrets
  • πŸ”§ Multi-environment config support (local, development, kubernetes, staging, production)

πŸ—οΈ System Architecture

                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚     Ingress          β”‚
                          β”‚  pdf-malware.local   β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚   Frontend (Streamlit)β”‚
                          β”‚   Port: 8501          β”‚
                          β”‚   NodePort: 30501     β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚ POST /api/v1/scan
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚  Backend (Spring Boot)β”‚
                          β”‚  Port: 8081           β”‚
                          β”‚  ClusterIP            β”‚
                          β””β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                             β”‚              β”‚
            POST /predict   β”‚              β”‚  POST /api/v1/ai/analyze
                             β”‚              β”‚
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚  ModelApi    β”‚    β”‚  AIService       β”‚
                  β”‚  (FastAPI)   β”‚    β”‚  (Spring Boot)   β”‚
                  β”‚  Port: 8000  β”‚    β”‚  Port: 8082      β”‚
                  β”‚  ClusterIP   β”‚    β”‚  ClusterIP       β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                             β”‚
                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚   Ollama LLM      β”‚
                                    β”‚   (via ngrok /     β”‚
                                    β”‚    localhost:11434)β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‚ Project Structure

Pdf-Malware-Detection-System/
β”œβ”€β”€ Backend/                          # Spring Boot - Main orchestrator
β”‚   β”œβ”€β”€ src/main/java/com/pict/
β”‚   β”‚   β”œβ”€β”€ controller/
β”‚   β”‚   β”‚   └── PdfScanController.java
β”‚   β”‚   β”œβ”€β”€ service/
β”‚   β”‚   β”‚   β”œβ”€β”€ PdfFeatureExtractor.java
β”‚   β”‚   β”‚   β”œβ”€β”€ PythonPredictClient.java
β”‚   β”‚   β”‚   β”œβ”€β”€ AIAnalysisBuilderService.java
β”‚   β”‚   β”‚   β”œβ”€β”€ AiService.java
β”‚   β”‚   β”‚   └── CombineService.java
β”‚   β”‚   β”œβ”€β”€ dtos/
β”‚   β”‚   └── config/
β”‚   β”‚       └── WebFluxConfig.java
β”‚   β”œβ”€β”€ src/main/resources/
β”‚   β”‚   β”œβ”€β”€ application.yml            # Base config (port 8081)
β”‚   β”‚   β”œβ”€β”€ application-local.yml      # Local profile (localhost URLs)
β”‚   β”‚   └── application-k8s.yml        # K8s profile (service DNS URLs)
β”‚   β”œβ”€β”€ deploy/                        # Kubernetes manifests
β”‚   β”‚   β”œβ”€β”€ configmap.yml
β”‚   β”‚   β”œβ”€β”€ secret.yml
β”‚   β”‚   β”œβ”€β”€ service.yml
β”‚   β”‚   β”œβ”€β”€ deployment.yml
β”‚   β”‚   β”œβ”€β”€ hpa.yml
β”‚   β”‚   └── deploy.sh
β”‚   └── Dockerfile
β”‚
β”œβ”€β”€ AIService/                         # Spring Boot - LLM AI analysis
β”‚   β”œβ”€β”€ src/main/java/edu/pict/
β”‚   β”‚   β”œβ”€β”€ controller/
β”‚   β”‚   β”‚   └── AIController.java
β”‚   β”‚   β”œβ”€β”€ service/
β”‚   β”‚   └── dtos/
β”‚   β”œβ”€β”€ src/main/resources/
β”‚   β”‚   β”œβ”€β”€ application.yml            # Base config (port 8082)
β”‚   β”‚   β”œβ”€β”€ application-local.yml      # Local profile
β”‚   β”‚   └── application-k8s.yml        # K8s profile
β”‚   β”œβ”€β”€ deploy/                        # Kubernetes manifests
β”‚   β”‚   β”œβ”€β”€ configmap.yml
β”‚   β”‚   β”œβ”€β”€ secret.yml
β”‚   β”‚   β”œβ”€β”€ service.yml
β”‚   β”‚   β”œβ”€β”€ deployment.yml
β”‚   β”‚   β”œβ”€β”€ hpa.yml
β”‚   β”‚   └── deploy.sh
β”‚   └── Dockerfile
β”‚
β”œβ”€β”€ ModelApi/                          # FastAPI - ML prediction
β”‚   β”œβ”€β”€ app.py
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”œβ”€β”€ settings.py                # Environment-aware config loader
β”‚   β”‚   β”œβ”€β”€ local.env
β”‚   β”‚   β”œβ”€β”€ dev.env
β”‚   β”‚   β”œβ”€β”€ kubernetes.env
β”‚   β”‚   β”œβ”€β”€ staging.env
β”‚   β”‚   └── production.env
β”‚   β”œβ”€β”€ deploy/                        # Kubernetes manifests
β”‚   β”‚   β”œβ”€β”€ configmap.yml
β”‚   β”‚   β”œβ”€β”€ secret.yml
β”‚   β”‚   β”œβ”€β”€ service.yml
β”‚   β”‚   β”œβ”€β”€ deployment.yml
β”‚   β”‚   β”œβ”€β”€ hpa.yml
β”‚   β”‚   └── deploy.sh
β”‚   β”œβ”€β”€ pdf_malware_detector.json      # XGBoost model file
β”‚   └── Dockerfile
β”‚
β”œβ”€β”€ Frontend/                          # Streamlit - Web UI
β”‚   β”œβ”€β”€ app.py
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”œβ”€β”€ settings.py                # Environment-aware config loader
β”‚   β”‚   β”œβ”€β”€ local.env
β”‚   β”‚   β”œβ”€β”€ dev.env
β”‚   β”‚   β”œβ”€β”€ kubernetes.env
β”‚   β”‚   β”œβ”€β”€ staging.env
β”‚   β”‚   └── production.env
β”‚   β”œβ”€β”€ deploy/                        # Kubernetes manifests
β”‚   β”‚   β”œβ”€β”€ configmap.yml
β”‚   β”‚   β”œβ”€β”€ secret.yml
β”‚   β”‚   β”œβ”€β”€ service.yml
β”‚   β”‚   β”œβ”€β”€ deployment.yml
β”‚   β”‚   β”œβ”€β”€ hpa.yml
β”‚   β”‚   β”œβ”€β”€ ingress.yml
β”‚   β”‚   └── deploy.sh
β”‚   └── Dockerfile
β”‚
β”œβ”€β”€ Model/                             # ML model training scripts
β”œβ”€β”€ TestingWithMalciousFile/           # Test PDF samples
β”œβ”€β”€ build.sh                           # Build all Docker images
β”œβ”€β”€ deployment.sh                      # Deploy all services to K8s
β”œβ”€β”€ docker-compose.yml                 # Local Docker Compose setup
└── push.sh                            # Push images to registry

βš™οΈ Technologies Used

Component Technology
ML Model Python, XGBoost, FastAPI
LLM Ollama (Gemma3, Phi3, Qwen, Mistral)
Backend Spring Boot (Java 21)
AI Service Spring Boot (Java 21)
PDF Parsing Apache PDFBox
Networking Spring WebClient (Reactive)
Frontend Streamlit
Containerization Docker (multi-stage builds)
Orchestration Kubernetes (Deployments, Services, HPA, Ingress)
Config Management ConfigMaps, Secrets, Spring Profiles, Python env files

πŸš€ Setup & Installation

1️⃣ Install Ollama

Download: https://ollama.com/download

Pull a recommended model:

ollama pull gemma3:latest

Run the model:

ollama run gemma3

2️⃣ Clone Repository

git clone https://github.com/shrihari7396/Pdf-Malware-Detection-System.git
cd Pdf-Malware-Detection-System

3️⃣ Choose Your Deployment Method

Option A: Run Locally (Without Containers)

Start Ollama

ollama serve   # Runs on http://localhost:11434

Start ModelApi (Python ML Server)

cd ModelApi
pip install -r requirements.txt
python app.py   # Runs on http://localhost:8000

Start Backend (Spring Boot)

cd Backend
./mvnw spring-boot:run   # Runs on http://localhost:8081

Start AIService (Spring Boot)

cd AIService
./mvnw spring-boot:run   # Runs on http://localhost:8082

Start Frontend (Streamlit)

cd Frontend
pip install -r requirements.txt
streamlit run app.py   # Opens at http://localhost:8501

Option B: Run with Docker Compose

docker-compose up --build

Access the app at http://localhost:8501


Option C: Deploy to Kubernetes (Recommended for Production)

See the Kubernetes Deployment section below.


πŸ”§ Environment Configuration

Spring Boot Services (Backend & AIService)

Both Spring Boot services use Spring Profiles for environment-specific configuration:

Profile Activated By Config File Use Case
local Default / SPRING_PROFILES_ACTIVE=local application-local.yml Local development
k8s SPRING_PROFILES_ACTIVE=k8s application-k8s.yml Kubernetes deployment

Environment Variables & Defaults

Environment Variable Description Local Default K8s Default
SPRING_PROFILES_ACTIVE Active Spring profile local k8s
AI_ANALYSIS_URL AIService endpoint http://localhost:8082/api/v1/ai/analyze http://ai-service:8082/api/v1/ai/analyze
PYTHON_PREDICT_URL ModelApi endpoint http://localhost:8000/predict http://model-api:8000/predict
OLLAMA_BASE_URL Ollama LLM endpoint http://localhost:11434 Configured via ConfigMap (ngrok URL)
OLLAMA_MODEL Ollama model name gemma3:latest gemma3:latest

Python Services (Frontend & ModelApi)

Python services use an environment-aware config loader (config/settings.py) that:

  1. Reads APP_ENV environment variable (defaults to local)
  2. Loads the matching config/{APP_ENV}.env file
  3. Falls back to hardcoded defaults if env vars are missing
Environment APP_ENV Value Env File
Local local config/local.env
Development development config/dev.env
Kubernetes kubernetes config/kubernetes.env
Staging staging config/staging.env
Production production config/production.env

☸️ Kubernetes Deployment

πŸ“‹ Prerequisites

  • A running Kubernetes cluster (e.g., Minikube, Kind, or cloud-managed K8s)
  • kubectl CLI configured to communicate with your cluster
  • Docker installed locally
  • Ollama running locally (exposed via ngrok for K8s access)

πŸ—οΈ 1. Build Container Images

The build.sh script builds all 4 Docker images. If using Minikube, it automatically points Docker to Minikube's internal daemon β€” no need to push to a registry:

chmod +x build.sh
./build.sh

This builds:

Service Image Name
ModelApi pdf-malware-system-model-api:latest
AIService ai-service-backend:latest
Backend pdf-malware-backend:latest
Frontend pdf-malware-system-frontend:latest

πŸ”Œ 2. Expose Ollama via ngrok

Since Ollama runs on your local machine with GPU, expose it to the K8s cluster via ngrok:

# Start Ollama
ollama serve

# In another terminal, expose port 11434 via ngrok
ngrok http 11434

Copy the ngrok URL (e.g., https://abc123.ngrok-free.app) and update the AIService ConfigMap:

# AIService/deploy/configmap.yml
data:
  OLLAMA_BASE_URL: "https://your-ngrok-url.ngrok-free.app"

πŸš€ 3. Deploy All Services

chmod +x deployment.sh
./deployment.sh

This deploys services in the correct dependency order:

  1. ModelApi β†’ model-api ClusterIP service on port 8000
  2. AIService β†’ ai-service ClusterIP service on port 8082
  3. Backend β†’ backend ClusterIP service on port 8081
  4. Frontend β†’ frontend NodePort service on port 8501 / NodePort 30501 + Ingress

Kubernetes Resources Per Service

Resource Frontend Backend AIService ModelApi
ConfigMap βœ… βœ… βœ… βœ…
Secret βœ… βœ… βœ… βœ…
Deployment βœ… βœ… βœ… βœ…
Service NodePort ClusterIP ClusterIP ClusterIP
HPA βœ… (1-5 pods) βœ… (1-5 pods) βœ… (1-5 pods) βœ… (1-5 pods)
Ingress βœ… β€” β€” β€”

πŸ”Ž 4. Verify the Deployment

# Check all resources
kubectl get all

# Check pods are running
kubectl get pods

# Check services
kubectl get svc

# Check ingress
kubectl get ingress

# View logs
kubectl logs -l app=backend --tail=100
kubectl logs -l app=ai-service --tail=100
kubectl logs -l app=model-api --tail=100
kubectl logs -l app=frontend --tail=100

🌐 5. Access the Application

Option 1: Via Ingress (Recommended)

Enable the Ingress controller (Minikube):

minikube addons enable ingress

Add hostname to /etc/hosts:

echo "$(minikube ip) pdf-malware.local" | sudo tee -a /etc/hosts

Access at: http://pdf-malware.local

Option 2: Via NodePort

minikube service frontend

Option 3: Via Port Forwarding

kubectl port-forward svc/frontend 8501:8501

Access at: http://localhost:8501


πŸ” API Documentation

πŸ“Œ 1. /scan β€” Main Scan Endpoint (Backend)

POST http://localhost:8081/api/v1/scan
Content-Type: multipart/form-data

Request:

Upload a PDF file with key file.

Response (PredictionResponse):

{
  "prediction": "malicious",
  "confidence": 0.998,
  "features": { ... },
  "explanation": { ... },
  "htmlAnalysis": "BASE64_ENCODED_HTML_STRING"
}

πŸ“Œ 2. /ai/analyze β€” AI Analysis Endpoint (AIService)

POST http://localhost:8082/api/v1/ai/analyze
Content-Type: application/json

Request Body (AIAnalysisRequest):

{
  "prediction": "malicious",
  "confidence": 0.58,
  "features": { ... },
  "extractedText": "...",
  "metadata": { ... },
  "fileName": "sample.pdf",
  "fileSize": 12345
}

Response:

{
  "htmlReport": "<div>... Full HTML analysis report ...</div>"
}

πŸ“Œ 3. /predict β€” ML Prediction Endpoint (ModelApi)

POST http://localhost:8000/predict
Content-Type: application/json

Request Body:

{
  "features": {
    "pdfsize": 12345,
    "metadata size": 200,
    "pages": 3,
    "isEncrypted": 0,
    "JS": 1,
    ...
  }
}

Response:

{
  "prediction": "malicious",
  "confidence": 0.998,
  "features": { ... }
}

⚑ Performance Optimization

βœ” Recommended fast local models:

  • gemma3:latest (recommended)
  • phi3:3b
  • qwen2.5:3b

βœ” Enable GPU for Ollama:

# Linux
export OLLAMA_USE_CUDA=1

# Windows
set OLLAMA_USE_CUDA=1

βœ” Reduce extracted text to 300–400 characters

βœ” Use shorter, focused prompts

⚑ Result:

  • ❌ Before: ~2 minutes
  • βœ… After: 6–15 seconds

πŸ›  Troubleshooting

❌ Slow LLM inference (> 60s)

➑ Switch to smaller models + trim prompt
➑ Enable CUDA / GPU acceleration

❌ Dark-mode unreadable text in Streamlit

➑ HTML is wrapped with white background container automatically

❌ Pods stuck in CrashLoopBackOff

➑ Check logs: kubectl logs -l app=<service-name>
➑ Verify ConfigMap values are correct: kubectl describe configmap <name>

❌ AIService cannot reach Ollama

➑ Ensure ngrok is running: ngrok http 11434
➑ Update OLLAMA_BASE_URL in AIService/deploy/configmap.yml
➑ Re-apply: kubectl apply -f AIService/deploy/configmap.yml
➑ Restart pods: kubectl rollout restart deployment/ai-service

❌ Frontend cannot reach Backend

➑ Verify Backend service exists: kubectl get svc backend
➑ Check Backend pods are running: kubectl get pods -l app=backend

❌ Ingress not working

➑ Enable Ingress addon: minikube addons enable ingress
➑ Check Ingress controller: kubectl get pods -n ingress-nginx
➑ Verify /etc/hosts has the Minikube IP mapping


🏁 Conclusion

This system is:

βœ” Fully modular microservices architecture
βœ” Fast and optimized with GPU-accelerated LLM
βœ” Local and privacy-preserving (no cloud API calls)
βœ” Produces professional HTML malware analysis reports
βœ” Multi-environment support (local, Docker Compose, Kubernetes)
βœ” Production-ready with HPA auto-scaling, Ingress, and ConfigMap-based configuration
βœ” Scalable for enterprise cybersecurity workflows


About

AI-powered PDF malware detection system combining Machine Learning, PDF structural analysis, and local LLM-generated security reports using Spring Boot, Python, and Ollama.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages