This system analyzes PDF files for malware using a hybrid approach that combines:
- Machine Learning Model (Python/FastAPI) β predicts malicious / benign
- PDF structure feature extraction using PDFBox (Java)
- AI LLM-based analysis generated via a local Ollama model
- 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
- π 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)
βββββββββββββββββββββββ
β 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)β
βββββββββββββββββββββ
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
| 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 |
Download: https://ollama.com/download
Pull a recommended model:
ollama pull gemma3:latestRun the model:
ollama run gemma3git clone https://github.com/shrihari7396/Pdf-Malware-Detection-System.git
cd Pdf-Malware-Detection-Systemollama serve # Runs on http://localhost:11434cd ModelApi
pip install -r requirements.txt
python app.py # Runs on http://localhost:8000cd Backend
./mvnw spring-boot:run # Runs on http://localhost:8081cd AIService
./mvnw spring-boot:run # Runs on http://localhost:8082cd Frontend
pip install -r requirements.txt
streamlit run app.py # Opens at http://localhost:8501docker-compose up --buildAccess the app at http://localhost:8501
See the Kubernetes Deployment section below.
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 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 use an environment-aware config loader (config/settings.py) that:
- Reads
APP_ENVenvironment variable (defaults tolocal) - Loads the matching
config/{APP_ENV}.envfile - 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 |
- A running Kubernetes cluster (e.g., Minikube, Kind, or cloud-managed K8s)
kubectlCLI configured to communicate with your cluster- Docker installed locally
- Ollama running locally (exposed via ngrok for K8s access)
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.shThis 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 |
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 11434Copy 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"chmod +x deployment.sh
./deployment.shThis deploys services in the correct dependency order:
- ModelApi β
model-apiClusterIP service on port8000 - AIService β
ai-serviceClusterIP service on port8082 - Backend β
backendClusterIP service on port8081 - Frontend β
frontendNodePort service on port8501/ NodePort30501+ Ingress
| 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 | β | β | β | β |
# 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=100Enable the Ingress controller (Minikube):
minikube addons enable ingressAdd hostname to /etc/hosts:
echo "$(minikube ip) pdf-malware.local" | sudo tee -a /etc/hostsAccess at: http://pdf-malware.local
minikube service frontendkubectl port-forward svc/frontend 8501:8501Access at: http://localhost:8501
POST http://localhost:8081/api/v1/scan
Content-Type: multipart/form-data
Upload a PDF file with key file.
{
"prediction": "malicious",
"confidence": 0.998,
"features": { ... },
"explanation": { ... },
"htmlAnalysis": "BASE64_ENCODED_HTML_STRING"
}POST http://localhost:8082/api/v1/ai/analyze
Content-Type: application/json
{
"prediction": "malicious",
"confidence": 0.58,
"features": { ... },
"extractedText": "...",
"metadata": { ... },
"fileName": "sample.pdf",
"fileSize": 12345
}{
"htmlReport": "<div>... Full HTML analysis report ...</div>"
}POST http://localhost:8000/predict
Content-Type: application/json
{
"features": {
"pdfsize": 12345,
"metadata size": 200,
"pages": 3,
"isEncrypted": 0,
"JS": 1,
...
}
}{
"prediction": "malicious",
"confidence": 0.998,
"features": { ... }
}gemma3:latest(recommended)phi3:3bqwen2.5:3b
# Linux
export OLLAMA_USE_CUDA=1
# Windows
set OLLAMA_USE_CUDA=1- β Before: ~2 minutes
- β After: 6β15 seconds
β‘ Switch to smaller models + trim prompt
β‘ Enable CUDA / GPU acceleration
β‘ HTML is wrapped with white background container automatically
β‘ Check logs: kubectl logs -l app=<service-name>
β‘ Verify ConfigMap values are correct: kubectl describe configmap <name>
β‘ 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
β‘ Verify Backend service exists: kubectl get svc backend
β‘ Check Backend pods are running: kubectl get pods -l app=backend
β‘ Enable Ingress addon: minikube addons enable ingress
β‘ Check Ingress controller: kubectl get pods -n ingress-nginx
β‘ Verify /etc/hosts has the Minikube IP mapping
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