feat(dlp): add enterprise phase scaffolds (policy role, content analysis, siem, case, compliance, cli)
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
|
||||
def validate_inn(value: str) -> bool:
|
||||
digits = re.sub(r"\D", "", value)
|
||||
if len(digits) == 10:
|
||||
coef = [2, 4, 10, 3, 5, 9, 4, 6, 8]
|
||||
chk = sum(int(digits[i]) * coef[i] for i in range(9)) % 11 % 10
|
||||
return chk == int(digits[9])
|
||||
if len(digits) == 12:
|
||||
c11 = [7, 2, 4, 10, 3, 5, 9, 4, 6, 8]
|
||||
c12 = [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8]
|
||||
chk11 = sum(int(digits[i]) * c11[i] for i in range(10)) % 11 % 10
|
||||
chk12 = sum(int(digits[i]) * c12[i] for i in range(11)) % 11 % 10
|
||||
return chk11 == int(digits[10]) and chk12 == int(digits[11])
|
||||
return False
|
||||
|
||||
|
||||
def validate_snils(value: str) -> bool:
|
||||
digits = re.sub(r"\D", "", value)
|
||||
if len(digits) != 11:
|
||||
return False
|
||||
number = digits[:9]
|
||||
checksum = int(digits[9:])
|
||||
s = sum(int(number[i]) * (9 - i) for i in range(9))
|
||||
if s < 100:
|
||||
expected = s
|
||||
elif s in (100, 101):
|
||||
expected = 0
|
||||
else:
|
||||
expected = s % 101
|
||||
if expected == 100:
|
||||
expected = 0
|
||||
return checksum == expected
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"inn": {
|
||||
"regex": "\\b\\d{10}\\b|\\b\\d{12}\\b",
|
||||
"checksum": "inn",
|
||||
"description": "ИНН"
|
||||
},
|
||||
"snils": {
|
||||
"regex": "\\b\\d{3}-\\d{3}-\\d{3}\\s?\\d{2}\\b",
|
||||
"checksum": "snils",
|
||||
"description": "СНИЛС"
|
||||
},
|
||||
"passport": {
|
||||
"regex": "\\b\\d{4}\\s?\\d{6}\\b",
|
||||
"checksum": "none",
|
||||
"description": "Паспорт РФ"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import pathlib
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
from checksum_validator import validate_inn, validate_snils
|
||||
|
||||
|
||||
def _validate(kind: str, value: str) -> bool:
|
||||
if kind == "inn":
|
||||
return validate_inn(value)
|
||||
if kind == "snils":
|
||||
return validate_snils(value)
|
||||
return True
|
||||
|
||||
|
||||
def match_text(text: str, dictionary_path: str) -> list[dict[str, Any]]:
|
||||
rules = json.loads(pathlib.Path(dictionary_path).read_text(encoding="utf-8"))
|
||||
results: list[dict[str, Any]] = []
|
||||
for name, rule in rules.items():
|
||||
regex = re.compile(rule["regex"])
|
||||
checksum_kind = rule.get("checksum", "none")
|
||||
for m in regex.finditer(text):
|
||||
token = m.group(0)
|
||||
if _validate(checksum_kind, token):
|
||||
results.append(
|
||||
{
|
||||
"name": name,
|
||||
"description": rule.get("description", name),
|
||||
"value": token,
|
||||
"start": m.start(),
|
||||
"end": m.end(),
|
||||
}
|
||||
)
|
||||
return results
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
import pytesseract
|
||||
|
||||
|
||||
def extract_text(image_path: str) -> str:
|
||||
path = Path(image_path)
|
||||
if not path.exists():
|
||||
return ""
|
||||
img = Image.open(path)
|
||||
return pytesseract.image_to_string(img, lang="rus+eng")
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"rules": [
|
||||
{ "id": "email", "regex": "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}", "severity": "low" },
|
||||
{ "id": "phone-ru", "regex": "(?:\\+7|8)\\s*\\(?\\d{3}\\)?\\s*\\d{3}[- ]?\\d{2}[- ]?\\d{2}", "severity": "low" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"rules": [
|
||||
{ "id": "card-pan", "regex": "\\b(?:\\d[ -]*?){13,19}\\b", "severity": "high" },
|
||||
{ "id": "iban", "regex": "\\b[A-Z]{2}\\d{2}[A-Z0-9]{11,30}\\b", "severity": "medium" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"rules": [
|
||||
{ "id": "aws-access-key", "regex": "AKIA[0-9A-Z]{16}", "severity": "high" },
|
||||
{ "id": "generic-password", "regex": "(?i)(password|пароль)\\s*[:=]\\s*\\S{6,}", "severity": "medium" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user