Spaces:
Sleeping
Sleeping
File size: 13,900 Bytes
8375d98 5e05a3c 8375d98 cb00897 5e05a3c 8375d98 6a6d583 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c 8375d98 5e05a3c e95b7e2 5e05a3c 8375d98 5e05a3c c02a9fe cb00897 5e05a3c cb00897 5e05a3c cb00897 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | import asyncio
import random
from typing import Optional, List, Dict
from types import SimpleNamespace
from fastapi import FastAPI
from openenv.core.env_server import Environment
from models import MyEnvV4Observation, MyEnvV4Action, URLInfo
class MyEnvV4Env(Environment):
def __init__(self):
super().__init__()
self.dataset = self._generate_sophisticated_dataset()
# For evaluation reproducibility, we could shuffle, but for benchmark stability, we keep order
self.current_step = 0
def _generate_sophisticated_dataset(self):
"""
Expanded dataset with 15 samples across 3 difficulty levels.
Covers Clean, Spam, and Phishing (Digital Seduction).
"""
base_data = [
# LEVEL 1: CLEAR CASES (5)
{
"sender": "registrar@manipal.edu",
"subject": "Semester Registration Open",
"body": "Dear student, please register for the Fall semester via the student portal.",
"raw_headers": "Received: from mail.manipal.edu (14.139.161.20) by mx.google.com; SPF: pass; DKIM: pass;",
"auth_results": {"SPF": "pass", "DKIM": "pass", "DMARC": "pass"},
"urls": [],
"label": "INBOX",
"difficulty": 1
},
{
"sender": "no-reply@amazon.com",
"subject": "Your Order #123-4567 has shipped",
"body": "Track your package delivery status in your Amazon account.",
"raw_headers": "Received: from a9-12.smtp-out.amazonses.com... SPF: pass; DKIM: pass;",
"auth_results": {"SPF": "pass", "DKIM": "pass", "DMARC": "pass"},
"urls": [{"url": "https://amazon.com/track", "is_shortened": False, "domain_age_days": 8000, "has_ssl": True, "reputation_score": 1.0}],
"label": "INBOX",
"difficulty": 1
},
{
"sender": "win-money@lottery-global.net",
"subject": "YOU WON!! $1,000,000",
"body": "Congratulations! You have been selected as our winner. CLAIM YOUR $1M NOW!",
"raw_headers": "Received: from unknown-relay.co (103.22.1.5)... SPF: none; DKIM: fail;",
"auth_results": {"SPF": "none", "DKIM": "fail", "DMARC": "none"},
"urls": [{"url": "http://get-cash-free.net/claim", "is_shortened": False, "domain_age_days": 2, "has_ssl": False, "reputation_score": 0.1}],
"label": "SPAM",
"difficulty": 1
},
{
"sender": "viagra-sales@pharma-dealz.biz",
"subject": "Cheapest Meds Online",
"body": "Buy now and save 90% on all prescription drugs. No prescription needed!",
"raw_headers": "Received: from botnet-node.ru... SPF: softfail;",
"auth_results": {"SPF": "softfail", "DKIM": "none", "DMARC": "none"},
"urls": [{"url": "http://cheap-rx.biz", "is_shortened": False, "domain_age_days": 15, "has_ssl": False, "reputation_score": 0.05}],
"label": "SPAM",
"difficulty": 1
},
{
"sender": "support@netflix-security.com",
"subject": "Update Payment Method",
"body": "Your Netflix subscription has expired. Click here to login and update billing.",
"raw_headers": "Received: from suspicious-vps.com... SPF: fail; DMARC: fail;",
"auth_results": {"SPF": "fail", "DKIM": "none", "DMARC": "fail"},
"urls": [{"url": "https://bit.ly/fake-netflix-login", "is_shortened": True, "domain_age_days": 3, "has_ssl": True, "reputation_score": 0.02}],
"label": "QUARANTINE",
"difficulty": 1
},
# LEVEL 2: NUANCED / MARKETING / LEGIT BUT ANNOYING (5)
{
"sender": "news@internshala-mail.com",
"subject": "New Internships in Manipal",
"body": "Check out these new opportunities for CSE students. Apply today!",
"raw_headers": "Received: from mktg.server.com... SPF: pass; DKIM: pass;",
"auth_results": {"SPF": "pass", "DKIM": "pass", "DMARC": "pass"},
"urls": [{"url": "https://internshala.com/n/123", "is_shortened": False, "domain_age_days": 2500, "has_ssl": True, "reputation_score": 0.95}],
"label": "SPAM", # Triaged as Promotions/Spam
"difficulty": 2
},
{
"sender": "marketing@swiggy.in",
"subject": "50% OFF your next meal!",
"body": "Hungry? Use code HUNGRY50 at checkout.",
"raw_headers": "Received: from swiggy-mail.in... SPF: pass; DKIM: pass;",
"auth_results": {"SPF": "pass", "DKIM": "pass", "DMARC": "pass"},
"urls": [],
"label": "SPAM",
"difficulty": 2
},
{
"sender": "hr@startup-hiring.co",
"subject": "Interview Invitation",
"body": "We saw your profile on LinkedIn and want to chat about a role.",
"raw_headers": "Received: from linkedin-referral.com... SPF: neutral;",
"auth_results": {"SPF": "neutral", "DKIM": "none", "DMARC": "none"},
"urls": [{"url": "https://startup-hiring.co/apply", "is_shortened": False, "domain_age_days": 45, "has_ssl": True, "reputation_score": 0.6}],
"label": "INBOX", # Legitimate cold outreach
"difficulty": 2
},
{
"sender": "alert@banking-secure.net",
"subject": "Suspicious Activity Detected",
"body": "We detected an unusual login to your account from Russia. Please verify.",
"raw_headers": "Received: from spoofed-host.com... SPF: softfail; DMARC: none;",
"auth_results": {"SPF": "softfail", "DKIM": "none", "DMARC": "none"},
"urls": [{"url": "https://t.co/secure-bank-login", "is_shortened": True, "domain_age_days": 10, "has_ssl": True, "reputation_score": 0.3}],
"label": "QUARANTINE",
"difficulty": 2
},
{
"sender": "noreply@github.com",
"subject": "[GitHub] A personal access token has been added",
"body": "A new personal access token was added to your account. If this wasn't you, click here.",
"raw_headers": "Received: from out-21.smtp.github.com... SPF: pass; DKIM: pass;",
"auth_results": {"SPF": "pass", "DKIM": "pass", "DMARC": "pass"},
"urls": [{"url": "https://github.com/settings/tokens", "is_shortened": False, "domain_age_days": 6000, "has_ssl": True, "reputation_score": 1.0}],
"label": "INBOX",
"difficulty": 2
},
# LEVEL 3: DIGITAL SEDUCTION (PHISHING / SPEAR PHISHING) (5)
{
"sender": "dean.office@manipal-edu.in", # Typo-squatted (.in instead of .edu)
"subject": "Urgent: Faculty Grievance Report",
"body": "A report has been filed against your department. Review the grievances here immediately.",
"raw_headers": "Received: from rogue-vps.xyz (45.33.22.11) by mx.google.com; SPF: fail; DMARC: fail;",
"auth_results": {"SPF": "fail", "DKIM": "none", "DMARC": "fail"},
"urls": [{"url": "https://bit.ly/3xYz1-grievance", "is_shortened": True, "domain_age_days": 5, "has_ssl": True, "reputation_score": 0.05}],
"label": "QUARANTINE",
"difficulty": 3
},
{
"sender": "it-support@manipal-helpdesk.com", # Look-alike domain
"subject": "Mandatory Password Reset",
"body": "As per the new MIT security policy, all students must reset their password today.",
"raw_headers": "Received: from mail-delivery.online... SPF: pass; DKIM: pass;", # Attacker set up SPF/DKIM correctly!
"auth_results": {"SPF": "pass", "DKIM": "pass", "DMARC": "none"},
"urls": [{"url": "http://manipal-helpdesk.com/reset", "is_shortened": False, "domain_age_days": 1, "has_ssl": False, "reputation_score": 0.1}],
"label": "QUARANTINE",
"difficulty": 3
},
{
"sender": "prof.sharma@mit-manipal.org", # Wrong TLD
"subject": "Final Exam Paper Leak?",
"body": "I suspect the paper has leaked. Look at this screenshot and confirm if these are your questions.",
"raw_headers": "Received: from sendgrid.net... SPF: pass;",
"auth_results": {"SPF": "pass", "DKIM": "none", "DMARC": "none"},
"urls": [{"url": "https://dropbox-files.com/s/xyz", "is_shortened": False, "domain_age_days": 4, "has_ssl": True, "reputation_score": 0.2}],
"label": "QUARANTINE",
"difficulty": 3
},
{
"sender": "accounts@google-security.info",
"subject": "Critical Security Alert",
"body": "Someone just used your password to try to sign in to your account. Go to your Google account now.",
"raw_headers": "Received: from host-12.xyz... SPF: fail;",
"auth_results": {"SPF": "fail", "DKIM": "none", "DMARC": "fail"},
"urls": [{"url": "https://google-secure-login.info", "is_shortened": False, "domain_age_days": 2, "has_ssl": True, "reputation_score": 0.01}],
"label": "QUARANTINE",
"difficulty": 3
},
{
"sender": "library@manipal.edu",
"subject": "Overdue Book Notice",
"body": "Your copy of 'Computer Networks' is overdue. Click to pay the fine of ₹50.",
"raw_headers": "Received: from mail.manipal.edu... SPF: pass; DKIM: pass;",
"auth_results": {"SPF": "pass", "DKIM": "pass", "DMARC": "pass"},
"urls": [{"url": "https://portal.manipal.edu/pay", "is_shortened": False, "domain_age_days": 4000, "has_ssl": True, "reputation_score": 1.0}],
"label": "INBOX",
"difficulty": 3 # Difficult because it looks like a phishing lure but is legit.
}
]
return base_data
async def reset(self):
self.current_step = 0
return self._get_result()
def _get_result(self, reward=0.0, done=False):
if self.current_step >= len(self.dataset):
obs = MyEnvV4Observation(
sender="N/A", subject="N/A", body="N/A", raw_headers="",
hop_count=0, auth_results={}, urls=[], echoed_message="End of Session"
)
return SimpleNamespace(observation=obs, reward=reward, done=True)
data = self.dataset[self.current_step]
obs = MyEnvV4Observation(
sender=data["sender"],
subject=data["subject"],
body=data["body"],
raw_headers=data["raw_headers"],
hop_count=data["raw_headers"].count("Received:"),
auth_results=data["auth_results"],
urls=[URLInfo(**u) for u in data["urls"]],
echoed_message=f"Task {self.current_step + 1}/{len(self.dataset)}"
)
return SimpleNamespace(observation=obs, reward=reward, done=done)
async def step(self, action: MyEnvV4Action):
if self.current_step >= len(self.dataset):
return self._get_result(done=True)
target = self.dataset[self.current_step]
correct = target["label"]
prediction = action.message.strip().upper()
# SOPHISTICATED REWARD LOGIC
reward = 0.0
if prediction == correct:
# Perfect Match: reward scales with difficulty
reward = 1.0 + (target["difficulty"] * 0.1)
elif correct in ["SPAM", "QUARANTINE"] and prediction in ["SPAM", "QUARANTINE"]:
# Partial Credit: Recognized threat but misclassified type
reward = 0.4
elif correct == "QUARANTINE" and prediction == "INBOX":
# Dangerous Failure: Penalty for letting a threat into the Inbox
reward = -1.5
elif correct == "INBOX" and prediction == "QUARANTINE":
# False Positive: Penalty for blocking legitimate mail
reward = -0.5
# Add Reasoning Bonus (Explainability)
if hasattr(action, 'reasoning') and action.reasoning and len(action.reasoning) > 30:
# Small bonus if agent provides a justification
reward += 0.05
# Normalize reward to [0, 1] range as per OpenEnv specs (clipping/rescaling)
# However, many environments allow negative for penalties; we clip to [0,1] for final score
final_reward = max(0.0, min(1.0, reward))
self.current_step += 1
done = self.current_step >= len(self.dataset)
return self._get_result(reward=final_reward, done=done)
async def state(self):
return {"current_step": self.current_step, "total_tasks": len(self.dataset)}
# Global instance for the server
my_env = MyEnvV4Env()
app = FastAPI()
@app.get("/reset")
async def reset():
res = await my_env.reset()
return {"observation": res.observation, "reward": res.reward, "done": res.done}
@app.post("/step")
async def step(action: MyEnvV4Action):
res = await my_env.step(action)
return {"observation": res.observation, "reward": res.reward, "done": res.done}
@app.get("/state")
async def state():
return await my_env.state() |