过滤 AWS 资源访问验证成功通知

This commit is contained in:
2026-10-08 16:13:16 +08:00
parent 2174b61606
commit 5db6f351cd
4 changed files with 155 additions and 8 deletions
+34 -4
View File
@@ -34,6 +34,15 @@ WARNING_TERMS = re.compile(
EXPLICIT_CLOSURE_SUBJECT = re.compile(
r"permanent closure confirmation|永久关闭确认", re.I
)
ACCESS_VALIDATED = re.compile(
r"your\s+request\s+for\s+accessing\s+AWS\s+resources\s+has\s+been\s+"
r"(?:successfully\s+)?validated\b|"
r"您访问\s*AWS\s*资源的请求已(?:得到验证|通过验证|验证成功)", re.I
)
RISK_ALERT_SUBJECT = re.compile(
r"suspicious activity|security (?:alert|warning)|abuse report|phishing|compromis|"
r"可疑活动|异常活动|滥用|钓鱼|泄露|安全警告", re.I
)
SECRET = re.compile(
r"\b(?:AKIA|ASIA)[A-Z0-9]{16}\b|"
r"\bBearer\s+[A-Za-z0-9._~+/-]+|"
@@ -76,6 +85,15 @@ DOCUMENT_REQUEST = re.compile(
r"(?:请|需要|必须).{0,30}(?:上传|提交|提供).{0,40}(?:材料|证件|身份证|护照|账单|证明)", re.I
)
RISK_EVIDENCE = re.compile(ACCOUNT_RISK.pattern + "|" + DOCUMENT_REQUEST.pattern, re.I)
RESOURCE_RISK_ACTION = re.compile(
r"(?:please|must|required to|take action).{0,80}(?:remove|delete|stop|disable|revoke|rotate)"
r".{0,100}(?:phishing|abus(?:e|ive)|malicious|compromised|unauthorized)|"
r"(?:请|必须|需要|立即).{0,40}(?:删除|移除|停止|停用|撤销|轮换|更换)"
r".{0,60}(?:钓鱼|滥用|恶意|泄露|未授权)", re.I
)
ACCESS_NOTICE_RISK_EVIDENCE = re.compile(
RISK_EVIDENCE.pattern + "|" + RESOURCE_RISK_ACTION.pattern, re.I
)
CONDITIONAL = re.compile(r"\bif\b|如果|假如|倘若|若|如(?:您|你)", re.I)
NON_RESPONSE = re.compile(
r"\b(?:do not|don't|fail to|failed to|unless)\b|"
@@ -84,7 +102,7 @@ NON_RESPONSE = re.compile(
)
def has_explicit_risk(text):
def has_explicit_risk(text, evidence=RISK_EVIDENCE):
# Evaluate each clause, so a conditional security tip cannot hide an actual
# restriction elsewhere in the same paragraph (or make a code into an alert).
for sentence in re.split(r"[\n.!?。!?;;]+|\b(?:but|however)\b|但是|然而", text, flags=re.I):
@@ -94,11 +112,12 @@ def has_explicit_risk(text):
for clause in re.split(r"[,,]+", sentence):
if CONDITIONAL.search(clause):
conditional_help = not bool(NON_RESPONSE.search(clause))
for match in RISK_EVIDENCE.finditer(clause):
for match in evidence.finditer(clause):
prefix = clause[:match.start()]
if CONDITIONAL.search(prefix) and not NON_RESPONSE.search(prefix):
continue
if conditional_help and DOCUMENT_REQUEST.match(match.group()):
if conditional_help and (DOCUMENT_REQUEST.match(match.group())
or RESOURCE_RISK_ACTION.match(match.group())):
continue
return True
return False
@@ -114,6 +133,17 @@ def is_verification_code(subject, body):
)
def is_access_validated_notice(subject, body):
"""Ignore completed resource-access verification, while keeping risk notices."""
combined = subject + "\n" + body
return bool(
ACCESS_VALIDATED.search(combined)
and not (has_explicit_risk(combined, ACCESS_NOTICE_RISK_EVIDENCE)
or EXPLICIT_CLOSURE_SUBJECT.search(subject)
or RISK_ALERT_SUBJECT.search(subject))
)
class PlainHTML(HTMLParser):
def __init__(self):
super().__init__()
@@ -238,7 +268,7 @@ def extract(message, received):
subject = header_value(message, "Subject")
body = body_text(message)
combined = subject + "\n" + body
if is_verification_code(subject, body):
if is_verification_code(subject, body) or is_access_validated_notice(subject, body):
return None
if not RISK_TERMS.search(combined) or not (
WARNING_TERMS.search(combined) or EXPLICIT_CLOSURE_SUBJECT.search(subject)