ExistedYear's picture
deploy
a86f101
metadata
title: ScamShield
emoji: πŸ›‘οΈ
colorFrom: red
colorTo: blue
sdk: docker
app_port: 7860
pinned: true
license: mit

ScamShield β€” Technical Report

Multilingual Smishing Detection: XLM-RoBERTa + URL Fusion + Mobile Deployment

Base paper: "Enhancing Smishing Detection: A Deep Learning Approach for Improved Accuracy and Reduced False Positives" β€” IEEE Access, 2024 (DOI: 10.1109/ACCESS.2024.3463871)


1. Introduction & Problem Statement

1.1 What is Smishing?

Smishing (SMS Phishing) is a social engineering attack where fraudulent SMS messages trick recipients into revealing sensitive information β€” passwords, OTPs, bank account details β€” by impersonating trusted entities (banks, delivery services, government agencies).

1.2 Why Detection is Hard

  • SMS messages are short (<160 chars) β€” limited context
  • Attackers continuously evolve language to evade filters
  • Legitimate Indian transactional SMS (OTP, bank credits, recharges) resembles spam patterns β€” high false positive risk
  • Class imbalance: ~61% ham, ~39% spam
  • Adversarial evasion: character substitution, spacing tricks, word manipulation

1.3 Our Contributions Over the Base Paper

Contribution Base Paper (CNN-LSTM) Our System
Model CNN-LSTM from scratch XLM-RoBERTa (multilingual pre-trained transformer)
Languages English only English + Hindi + Hinglish
URL Analysis None 9 URL risk signals + Google Safe Browsing
Explainability None SHAP word-level explanations
Adversarial Testing None 4 attack types tested
Training Data ~5,574 messages ~30,000+ messages (6 sources, multilingual)
Mobile App None React Native Android/iOS app with real-time SMS scanning
Indian SMS Support None 60+ synthetic Indian legit SMS + feature fixes
Encryption None AES-256-CBC end-to-end encrypted API channel
Real-time Monitoring None Background SMS polling with push notifications

2. System Architecture

2.1 Three-Component System

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ScamShield System                                               β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  AES-256-CBC  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  ScamShield      │◄─────────────►│  Flask API           β”‚   β”‚
β”‚  β”‚  Mobile App      β”‚  /predict_    β”‚  (smishing_detector) β”‚   β”‚
β”‚  β”‚  (React Native)  β”‚   secure      β”‚  Port 5000           β”‚   β”‚
β”‚  β”‚  Android / iOS   β”‚  /explain     β”‚                      β”‚   β”‚
β”‚  β”‚  Real-time SMS   β”‚  /health      β”‚                      β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚     β–² Polls every 15s                          β”‚               β”‚
β”‚     β”‚ (android inbox, latest 30)               β”‚               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”‚               β”‚
β”‚  β”‚  KaggleTraining/ │── best_model.pt ─────────►│               β”‚
β”‚  β”‚  (Isolated pkg)  β”‚                          β”‚               β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚                                     β”‚  Google Safe Browsing  β”‚   β”‚
β”‚                                     β”‚  API (URL Verification)β”‚   β”‚
β”‚                                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2.2 Model Pipeline

SMS Message (English / Hindi / Hinglish)
    β”‚
    β”œβ”€β”€β–Ί XLM-RoBERTa Tokenizer β†’ XLM-RoBERTa Encoder β†’ CLS Token [768-d]
    β”‚    (SentencePiece, handles Devanagari natively)          β”‚
    β”œβ”€β”€β–Ί URL Feature Extractor β†’ 9 URL signals ──┐            β”‚
    β”‚                                            β–Ό            β–Ό
    └──► Text Feature Extractor β†’ 8 signals β†’ feat_proj β†’ [64-d]
                                                         β”‚
                                              Concatenate [832-d]
                                                         β”‚
                                              Classifier MLP
                                              (832β†’256β†’64β†’1)
                                                         β”‚
                                              Sigmoid β†’ P(spam)
                                                         β”‚
                                    β”Œβ”€β”€β”€β”€β”€β”€ β‰₯ 0.55? ──────
                                    β–Ό                     β–Ό
                               SPAM/MEDIUM            HAM/LOW
                                    β”‚
                              Has URLs?
                                    β”‚ Yes
                                    β–Ό
                          Google Safe Browsing
                          All URLs clean? β†’ Override to HAM

2.3 Project Structure

MAIN-EL-2/
β”œβ”€β”€ smishing_detector/          ← Flask API + model inference
β”‚   β”œβ”€β”€ app/flask_api.py        ← REST API (5 endpoints)
β”‚   β”œβ”€β”€ predictor.py            ← Inference + GSB override
β”‚   β”œβ”€β”€ models/model.py         ← SmishingDetector nn.Module
β”‚   β”œβ”€β”€ models/dataset.py       ← PyTorch Dataset
β”‚   β”œβ”€β”€ utils/data_loader.py    ← Feature engineering
β”‚   β”œβ”€β”€ utils/safe_browsing.py  ← Google Safe Browsing client
β”‚   β”œβ”€β”€ explainability/         ← SHAP explainer
β”‚   β”œβ”€β”€ adversarial/            ← Robustness testing
β”‚   └── best_model.pt           ← Trained checkpoint (~266 MB)
β”œβ”€β”€ ScamShield-Mobile/          ← React Native mobile app
β”‚   β”œβ”€β”€ App.js                  ← Root + theme
β”‚   β”œβ”€β”€ src/screens/            ← Inbox, Scan, Detail, Settings
β”‚   β”œβ”€β”€ src/components/         ← RiskBadge, ShapChart, ConfidenceBar…
β”‚   └── src/services/api.js     ← Flask API client
β”œβ”€β”€ KaggleTraining/             ← Isolated Kaggle training package
β”‚   β”œβ”€β”€ train.py                ← Training entry point
β”‚   β”œβ”€β”€ model.py                ← Architecture (same as API)
β”‚   β”œβ”€β”€ dataset.py              ← DataLoaders
β”‚   └── data_loader.py          ← Feature engineering (fixed)
β”œβ”€β”€ .env                        ← API keys (GSB + Kaggle)
└── COMMANDS_REFERENCE.md

3. Technologies Used

3.1 Core Stack

Layer Technology Purpose
Deep Learning PyTorch β‰₯ 2.0 Model training, inference
Transformer HuggingFace Transformers β‰₯ 4.35 XLM-RoBERTa model + tokenizer
NLP Model xlm-roberta-base Pre-trained multilingual encoder (270M params, 100 languages)
Tokenizer SentencePiece Handles Devanagari, Roman, English natively
Data Science scikit-learn, pandas, NumPy Metrics, splitting, normalization
Explainability SHAP β‰₯ 0.43 Word-level feature attribution
URL Analysis tldextract, requests Domain/TLD extraction
API Flask β‰₯ 3.0 + flask-cors REST backend
Mobile React Native (Expo SDK 54) Cross-platform mobile app
Mobile Nav React Navigation v7 Tab + stack navigation
Mobile Storage AsyncStorage Scan history, settings
Security Google Safe Browsing API v4 URL threat verification
GPU Kaggle T4 Training (via KaggleTraining package)

3.2 Why XLM-RoBERTa over DistilBERT?

Aspect DistilBERT (Phase 2) XLM-RoBERTa (Phase 3)
Languages English only 100 languages (Hindi, Urdu, Bengali...)
Parameters 66M 270M
Pre-training data English Wikipedia + BooksCorpus 2.5TB CommonCrawl (100 languages)
Hindi support ❌ None βœ… Native Devanagari via SentencePiece
Hinglish support ❌ Fragmented βœ… Handles Roman-script Hindi
Accuracy (English) ~99.66% β‰₯97% (target, larger model needs more data)
Model size 250MB 1.1GB

4. Model Architecture

4.1 SmishingDetector (Phase 3)

SmishingDetector(
  bert: XLMRobertaModel          ← xlm-roberta-base, all 12 layers trainable

  feat_proj: Sequential(
    Linear(17 β†’ 64), ReLU(), Dropout(0.3),
    Linear(64 β†’ 64), ReLU()
  )

  classifier: Sequential(
    Linear(832 β†’ 256), ReLU(), Dropout(0.3),
    Linear(256 β†’ 64), ReLU(), Dropout(0.3),
    Linear(64 β†’ 1)      ← single logit
  )
)

Input dimension: 17 hand-crafted features (9 URL + 8 text)
Fusion: CLS [768] + feat_proj [64] = [832-d]
Output: sigmoid(logit) β†’ P(spam) ∈ [0, 1]

4.2 Feature Engineering (v2 β€” Fixed)

URL Features (9 signals)

Feature Description
has_url Message contains a URL
num_urls URL count
has_http Insecure HTTP
has_https HTTPS present
suspicious_tld .tk, .xyz, .ml, .loan, etc.
max_url_len Longest URL length
has_ip_url Raw IP address URL
has_shortened_url bit.ly, t.co, etc.
has_legit_domain Domain in whitelist OR cleared by GSB

Text Features (8 signals) β€” v2 fixes highlighted

Feature Description v2 Change
num_chars Character count β€”
num_words Word count β€”
pct_upper % uppercase β€”
pct_digits % digits β€”
num_special Special char count β€”
urgency_count Urgency keyword matches Removed account, verify, otp β€” too common in legit Indian SMS
has_phone Contains phone number Fixed regex for +91 / 10-digit Indian format
has_currency Currency detected Removed rs, rupee text match β€” only β‚Ή symbol now

5. Training β€” v2 (Kaggle)

5.1 Configuration

Parameter Phase 2 (DistilBERT) Phase 3 (XLM-RoBERTa) Rationale
Learning Rate 2e-5 1e-5 Stable fine-tuning of larger model
Dropout 0.4 0.3 Larger model, less aggressive dropout
Frozen BERT layers 3 0 Full fine-tuning needed for multilingual
Batch size 32 16 XLM-RoBERTa uses more VRAM
pos_weight multiplier 1.5Γ— 1.0Γ— No artificial spam bias
Decision threshold 0.50 0.55 Reduce false positives on Indian SMS
Label smoothing None 0.05 Prevents overconfident predictions
Early stop patience 3 4 More time to generalize
Max epochs 8 10 β€”
Training datasets 4 sources 6 sources (+ Hindi/Hinglish) Multilingual coverage

5.2 Label Smoothing Loss

Standard BCE was replaced with a custom LabelSmoothingBCELoss:

targets_smooth = targets Γ— (1 - Ξ΅) + Ξ΅ Γ— 0.5

With Ξ΅ = 0.05: spam labels become 0.975 (not 1.0) and ham labels become 0.025 (not 0.0). This prevents the model from becoming overconfident and generalizes better.

5.3 Dataset (v2)

Source                                        Messages    Notes
──────────────────────────────────────────────────────────────────
UCI SMS Spam Collection                       ~5,572      Gold standard
Deysi/spam-detection (HuggingFace)            ~10,900     Large, diverse
gauravduttakiit/sms-spam (Kaggle)             ~varies     Indian SMS context
Synthetic Indian Legit SMS                    60          Hand-crafted OTP/bank
dbarbedillo multilingual (en+hi columns)      ~11,144     Hindi + English
rajnathpatel/multilingual-spam-data           ~varies     Real Hindi/Hinglish
──────────────────────────────────────────────────────────────────
After deduplication:                          ~30,000+

Split: 70% train / 15% val / 15% test (stratified)

Why synthetic Indian SMS? All 3 original datasets are Western English. The model had never seen legitimate Indian bank credits, OTP messages, or recharge confirmations β€” so it flagged everything with Rs., HDFC, credited as spam.

5.4 Root Cause of Overfitting (v1)

The original model marked every Indian transactional SMS as high-risk spam (99.9% confidence) because:

  1. Distribution mismatch β€” zero legitimate Indian SMS in training data
  2. has_currency fired on Rs. β€” every bank SMS triggered it
  3. urgency_count fired on account, verify β€” every bank SMS triggered it
  4. All BERT layers unfrozen β€” model memorized training corpus patterns aggressively
  5. pos_weight 1.5Γ— β€” artificially pushed predictions toward spam

6. Google Safe Browsing Integration

6.1 How It Works

Model Prediction: SPAM (confidence 0.82)
        β”‚
        └── Message has URLs?  Yes
                β”‚
                β–Ό
        Extract all URLs
                β”‚
                β–Ό
        Query Google Safe Browsing API v4
        (MALWARE, SOCIAL_ENGINEERING, UNWANTED_SOFTWARE)
                β”‚
        All URLs clean?
          Yes ──────────────► Override β†’ HAM / LOW risk
                              gsb_cleared = true in response
          No / Error ───────► Keep model prediction

6.2 API Response with GSB

{
  "label": "ham",
  "confidence": 0.45,
  "risk_level": "low",
  "gsb_cleared": true,
  "url_signals": { ... },
  "text_signals": { ... }
}

6.3 Bug Fixed in v1

The original safe_browsing.py had an inverted cache logic β€” when GSB returned "no threats found" (domain is safe), it was storing False in the cache, meaning every GSB-verified clean domain was still treated as dangerous. This has been fixed.


7. Evaluation Results (v1 Model)

Note: v2 results will be available after Kaggle retraining.

7.1 Core Metrics

Metric Our System (v1) Paper (CNN-LSTM) Improvement
Accuracy 99.66% 97.49% +2.17%
Precision (spam) 99.46% ~97% +2.46%
Recall (spam) 99.67% ~97% +2.67%
F1 (spam) 99.57% 0.97 +2.57%
False Positive Rate 0.34% ~3% 8.8Γ— lower
ROC-AUC 0.9999 β€” β€”
MCC 0.9929 β€” β€”

7.2 Confusion Matrix (v1, test set n=2,373)

                  Predicted
              Ham       Spam
Actual  Ham  [1446        5]   ← 5 false alarms
        Spam [   3      919]   ← 3 missed

7.3 Adversarial Robustness

Attack Method F1 Drop
CharSwap Replace letters with l33t-speak (30% rate) 0.00
EDA Random word deletion + swap (20% rate) 0.00
Spacing Insert spaces in keywords 0.00
Hybrid All three combined 0.00

Zero degradation β€” DistilBERT's subword tokenization is inherently robust to surface-level text manipulations.


8. Mobile Application

8.1 Overview

React Native (Expo) cross-platform app providing real-time SMS analysis on Android and manual scanning on iOS.

8.2 Screens

Screen Description
Inbox SMS message list with risk badges; stats card (Scanned/Threats/Safe); Scan All button
Scan Manual message input + URL extractor; full analysis on submit
Detail SHAP chart, confidence bar, URL analysis, text signals, threat warnings, GSB badge
Settings API URL config + connectivity test, auto-scan toggle, dark/light theme, history management

8.3 Key Components

Component Purpose
RiskBadge Color-coded pill (green=low, amber=medium, red=high)
ConfidenceBar Animated probability bar
ShapChart Horizontal bar chart of top spam/ham word contributions
UrlAnalysis Per-URL safety breakdown with risk indicators

8.4 API Integration

Mobile App β†’ POST /predict  β†’ Risk label, confidence, signals, gsb_cleared
           β†’ POST /explain  β†’ SHAP top_spam_words, top_ham_words
           β†’ POST /check-domain β†’ Google Safe Browsing result
           β†’ GET  /health   β†’ API connectivity check

8.5 Build

eas build --platform android --profile preview   # β†’ .apk
eas build --platform android --profile production # β†’ signed .apk

9. API Endpoints

Endpoint Method Input Output
/health GET β€” {status, model}
/predict POST {message} {label, confidence, risk_level, gsb_cleared, url_signals, text_signals}
/explain POST {message} {label, confidence, top_spam_words, top_ham_words, feature_importances}
/batch_predict POST {messages[]} {results[], count}
/check-domain POST {domain} {domain, is_legitimate, status}

9. Security & Mobile Architecture

9.1 AES-256-CBC End-to-End Encryption

All SMS content sent from the mobile app to the Flask API is encrypted using AES-256-CBC before transmission. This protects sensitive message content from interception (e.g., on shared Wi-Fi or untrusted networks).

Encryption Flow:

Mobile (React Native)                     Server (Flask API)
──────────────────────                    ──────────────────
1. Read SMS from inbox                    1. Receive POST /predict_secure
2. Generate random 16-byte IV             2. Base64-decode payload
3. AES-256-CBC encrypt(message, key, IV)  3. Extract IV (first 16 bytes)
4. Prepend IV to ciphertext               4. AES-256-CBC decrypt(ciphertext, key, IV)
5. Base64-encode β†’ send to API            5. Run XLM-RoBERTa prediction

Key Management:

  • 256-bit key stored in server .env as SMS_ENCRYPTION_KEY
  • Mobile fetches key from /api/encryption-key on first launch (token-protected via X-App-Token header)
  • Key cached in device AsyncStorage for offline use
  • Default fallback key ensures operation even if API is temporarily unreachable

Libraries Used:

  • Mobile: crypto-js (AES-CBC, PKCS7 padding)
  • Server: cryptography (Python, hazmat.primitives.ciphers)

9.2 Real-Time SMS Monitoring

The mobile app monitors the Android SMS inbox in real-time using a two-tier approach:

Foreground Monitoring (while app is open):

  • Polls the Android SMS inbox every 15 seconds using react-native-get-sms-android
  • Reads only the latest 30 messages (configurable) to minimize memory usage
  • New messages since last check are auto-scanned via /predict_secure

Background Monitoring (app closed):

  • Uses expo-background-fetch + expo-task-manager to register a persistent background task
  • Android schedules background fetches when device is idle (typically every 15 min)
  • Task auto-scans new SMS and fires a local push notification if risk level is high or medium

Notification Payload:

⚠️ ScamShield: Suspicious SMS Detected
From +91-XXXXX: "Aapka electricity connection aaj raat..."
Confidence: 97%

Permissions Required (Android):

  • READ_SMS β€” read inbox contents
  • RECEIVE_SMS β€” be notified of new messages
  • RECEIVE_BOOT_COMPLETED β€” restart monitoring after device reboot

9.3 API Endpoints Summary

Endpoint Method Auth Description
/predict POST None Unencrypted prediction (fallback)
/predict_secure POST None AES-256-CBC encrypted prediction
/batch_predict POST None Batch predict multiple messages
/explain POST None SHAP explanation
/check-domain POST None Google Safe Browsing lookup
/api/encryption-key GET X-App-Token Returns AES key for mobile
/health GET None Model status

10. Key Design Decisions

Decision Rationale
XLM-RoBERTa over DistilBERT 100-language support, Devanagari native, same 768-d hidden size
All layers unfrozen Multilingual fine-tuning needs full gradient flow through all 12 layers
Late fusion (concatenation) BERT and hand-crafted features learn independently before combining
17 hand-crafted features Language-agnostic URL signals that XLM-RoBERTa alone cannot extract
GSB whitelist-only override Only known-good domains override spam β€” new phishing domains not in GSB DB
Threshold 0.55 (not 0.50) Reduces false positives on borderline cases (Indian bank SMS)
Label smoothing 0.05 Prevents overconfident predictions on training distribution
Batch size 16 (not 32) XLM-RoBERTa (1.1GB) needs more VRAM per forward pass than DistilBERT
Stratified 70/15/15 split Maintains spam/ham ratio across all data splits
Normalization from train only Prevents data leakage from val/test into normalization statistics
Synthetic Indian SMS Corrects training distribution bias against Indian transactional messages
AES-256-CBC (not AES-GCM) crypto-js (React Native) natively supports CBC; simpler interop with Python
Latest 30 SMS only Limits memory usage and inference time in background task

11. Hardware & Performance

Component Spec
GPU (training) Kaggle T4 (via KaggleTraining package)
RAM 16 GB recommended
Storage ~1.3 GB (model ~1.1 GB + cached XLM-RoBERTa weights)
Training time ~45–90 min (Kaggle T4)
Inference latency ~100 ms/message (GPU), ~500 ms (CPU)
API response time ~600 ms (includes GSB lookup)
Encryption overhead <5 ms (AES-256-CBC, negligible)

12. Results Summary

Metric Value
Test Accuracy 97.54%
Spam F1-Score 0.94
Val F1 (best epoch) 0.9765
False Positive Rate 0.46%
Hindi F1 (5,572 msgs) 0.9845
Adversarial F1 drop ≀ 0.01
Manual test (12 cases) 12/12 correct

13. Future Work

  1. On-device inference β€” Export to ONNX/TFLite for fully offline mobile prediction (no API needed)
  2. Active URL scanning β€” Follow redirects, analyze landing page content
  3. More Indian languages β€” Tamil, Telugu, Kannada, Bengali via IndicBERT
  4. Federated learning β€” Train across devices without centralizing SMS data
  5. Continuous learning β€” Periodic model updates from newly reported scam patterns
  6. Domain age check β€” WHOIS lookup as additional URL feature (newly registered domains = higher risk)
  7. iOS support β€” SMS reading on iOS requires SiriKit/Message Filter Extension entitlement