iliopdavid/django-amnesia-honeywords

GitHub: iliopdavid/django-amnesia-honeywords

一个 Django 身份验证后端,通过 Amnesia Honeywords 概率标记方案在无需独立 honeychecker 服务的情况下检测凭证泄露后的被盗密码冒用行为。

Stars: 0 | Forks: 0

# django-amnesia-honeywords 一个实现了 **Amnesia honeywords** 方案的 Django 身份验证后端,用于检测数据库泄露——无需单独的 honeychecker 服务。 当攻击者破解了凭证数据库并尝试使用被盗凭证进行在线登录时,该后端会检测提交的密码是*已标记*的凭证还是*未标记*的诱饵(honeyword)。 ## 概述 对于每个用户,系统不再存储单个密码哈希,而是存储 `k` 个哈希候选者(1 个真实密码 + `k-1` 个 honeywords)。每个候选者都带有一个 `marked` 布尔标志。真实密码始终被标记;其他候选者以 `p_mark` 的概率被标记。 登录时: 1. 查找与提交的密码匹配的候选者 2. 如果**不匹配** → 拒绝(无效密码) 3. 如果**匹配但未标记** → 检测到泄露(攻击者正在使用被盗凭证) 4. 如果**匹配且已标记** → 成功;以 `p_remark` 的概率重新标记其他候选者 核心优势:**无需单独的 Honeychecker 服务**。系统从不存储哪个索引是真实密码——安全性来源于概率标记方案。 ## 功能 - **即插即用的 Django 身份验证后端** — 与 Django 的认证系统无缝集成 - **Honeyword 生成** — 基于简单变异的生成器(可扩展用于自定义生成器) - **事件记录** — 跟踪所有带有 IP 和 User-Agent 的身份验证尝试 - **Django 信号** — 接入 honeyword 检测事件 - **可配置的策略** — 在检测到泄露时,可选择记录、重置密码或锁定账户 - **无需 Honeychecker** — Amnesia 方案消除了对单独服务的需求 ## 架构 ``` ┌─────────────────────────────────┐ │ Django App │ │ │ │ ┌───────────────────────────┐ │ │ │ HoneywordsBackend │ │ │ │ (authentication) │ │ │ └───────────┬───────────────┘ │ │ │ │ │ ┌───────────▼───────────────┐ │ │ │ amnesia_check() │ │ │ │ - find matching cred │ │ │ │ - check marked flag │ │ │ │ - probabilistic remark │ │ │ └───────────┬───────────────┘ │ │ │ │ │ ┌───────────▼───────────────┐ │ │ │ AmnesiaSet │ │ │ │ └─ k AmnesiaCredentials │ │ │ │ (hash + marked flag) │ │ │ └───────────────────────────┘ │ └─────────────────────────────────┘ ``` ## 安装 ``` pip install django-amnesia-honeywords ``` ## 本软件包的功能(以及不具备的功能) **具备的功能** - 提供了一个 Django **身份验证后端** (`django_honeywords.backend.HoneywordsBackend`),用于根据 Amnesia honeyword 集合检查密码。 - 为每个用户存储带有概率**标记**的 `k` 个密码候选者(哈希值);在登录时,它可以检测到使用**未标记**候选者的行为,并将其作为泄露信号。 - 记录结果(`real`/`honey`/`invalid`)并在检测到时发出 `honeyword_detected` 信号,以便进行告警/自动化处理。 **不具备的自动化功能** - 安装本软件包本身**不会**更改您项目的身份验证方式。 您必须显式设置 `AUTHENTICATION_BACKENDS` 才能使用 `HoneywordsBackend`。 - 它无法从已哈希的密码中初始化现有用户。您需要用户的**明文密码**(注册 / 密码修改 / 可控迁移)。 **重要集成说明** - 当您为用户初始化 honeywords 时,本软件包会将用户的 Django 密码设置为**不可用** (`set_unusable_password()`),以降低在启用 `ModelBackend` 时被绕过的风险。 - 如果您在 `HoneywordsBackend` 之外同时启用了 `django.contrib.auth.backends.ModelBackend`,那么**没有 AmnesiaSet 的用户**仍然可以使用默认的 Django 密码后端进行身份验证。 在生产环境中,建议仅使用 `HoneywordsBackend`,或者确保所有用户都已初始化。 或者从源码安装: ``` git clone https://github.com/iliopdavid/django-amnesia-honeywords.git cd django-amnesia-honeywords pip install -e . ``` ## 快速开始 ### 1. 添加到 Django 设置 ``` INSTALLED_APPS = [ # ... "django_honeywords.apps.DjangoHoneywordsConfig", ] AUTHENTICATION_BACKENDS = [ "django_honeywords.backend.HoneywordsBackend", ] # Honeywords 配置(全部可选 — 提供合理的默认值) HONEYWORDS = { "AMNESIA_K": 20, # Number of candidates per user "AMNESIA_P_MARK": 0.1, # Probability of marking a honeyword "AMNESIA_P_REMARK": 0.01, # Probability of re-marking on success "ON_HONEYWORD": "log", # "log" | "reset" | "lock" "LOG_REAL_SUCCESS": False, # Log successful *marked* credential logins (real or marked honeyword) "LOCK_BASE_SECONDS": 60, # Base lockout duration "LOCK_MAX_SECONDS": 3600, # Maximum lockout duration } ``` ### 2. 运行数据库迁移 ``` python manage.py migrate django_honeywords ``` ### 3. 初始化用户(重要) 本软件包无法从现有的哈希中推导出 honeywords:您必须在拥有用户**明文密码**时(注册、密码修改、迁移脚本)初始化用户。 - 管理命令(用于迁移 / 管理脚本): ``` python manage.py amnesia_init_user --password ``` - 通过代码初始化: ``` from django_honeywords.amnesia_service import amnesia_initialize_from_settings amnesia_initialize_from_settings(user, "real_password") ``` ### 4. (推荐)在生产环境中移除 ModelBackend 对于大多数部署环境,请仅配置 honeywords 后端: ``` AUTHENTICATION_BACKENDS = [ "django_honeywords.backend.HoneywordsBackend", ] ``` 如果您保持启用 `ModelBackend`,请确保您了解未初始化用户面临的绕过风险。 ## 配置选项 | 设置 | 默认值 | 描述 | |---------|---------|-------------| | `AMNESIA_K` | `20` | 每个用户的候选密码数量(1 个真实密码 + k-1 个 honeywords) | | `AMNESIA_P_MARK` | `0.1` | 初始化期间标记每个 honeyword 的概率 | | `AMNESIA_P_REMARK` | `0.01` | 登录成功后重新标记其他候选者的概率 | | `ON_HONEYWORD` | `"log"` | 检测到 honeyword 时的操作:`"log"`、`"reset"` 或 `"lock"` | | `LOG_REAL_SUCCESS` | `False` | 是否记录使用*已标记*凭证进行的成功身份验证 | | `LOCK_BASE_SECONDS` | `60` | 账户锁定的基准持续时间 | | `LOCK_MAX_SECONDS` | `3600` | 最大锁定持续时间(指数退避的上限) | ## 操作说明 - **系统检查**:运行 `python manage.py check` 以显示配置警告(例如,通配符主机、测试用哈希器、后端回退)。 - **事件语义**:记录“real”结果对应于**使用已标记凭证登录**(真实密码或已标记的 honeyword)。Amnesia 特意无法区分这些情况。 - **性能**:身份验证最多检查 `k` 个候选者(线性扫描)。请据此选择 `k` 和密码哈希器参数。 ## 组件 ### Django 模型 - **`AmnesiaSet`** — 将用户与其包含 `k` 个候选者及标记参数的集合关联起来 - **`AmnesiaCredential`** — 带有 `marked` 标志和索引的单个密码哈希 - **`HoneywordEvent`** — 身份验证尝试的审计日志(结果:real/honey/invalid) - **`HoneywordUserState`** — 跟踪每个用户的锁定和密码重置状态 ### 服务 #### `amnesia_service.py` - `amnesia_initialize(user, password, k, p_mark, p_remark)` — 为用户生成并存储候选者 - `amnesia_initialize_from_settings(user, password)` — 同上,但使用 `HONEYWORDS` 设置中的值 - `amnesia_check(user, password)` — 返回 `"success"`、`"breach"` 或 `"invalid"` #### `generator.py` - `SimpleMutationGenerator` — 用于 honeywords 的基本字符变异生成器 - 通过随机变异单个字符来创建变体 - 可扩展:使用 `honeywords(real, k)` 方法实现您自己的生成器 #### `backend.py` - `HoneywordsBackend` — Django 身份验证后端 - 通过 `amnesia_check()` 对用户进行身份验证 - 在检测到 honeyword 时执行策略(log/reset/lock) - 在检测到泄露时触发 `honeyword_detected` 信号 #### `policy.py` - `is_locked(user)` — 检查用户当前是否被锁定 - `apply_reset(user)` — 将用户标记为需要重置密码 - `apply_lock(user)` — 应用指数退避锁定 #### `events.py` - `log_event(user, username, outcome, request)` — 记录带有元数据的身份验证尝试 ### 信号 连接到 `honeyword_detected` 信号以实现自定义告警: ``` from django_honeywords.signals import honeyword_detected def on_honeyword(sender, user, username, request, event, **kwargs): send_security_alert( message=f"Honeyword detected for user {username}", ip=event.ip_address, user_agent=event.user_agent, ) honeyword_detected.connect(on_honeyword) ``` ## 管理命令 ### `amnesia_init_user` 为现有用户初始化 honeywords: ``` python manage.py amnesia_init_user alice --password "SecurePass123" ``` 参数: - `username` — 用户的用户名 - `--password` — 用户的真实密码(必填) 参数 `k`、`p_mark` 和 `p_remark` 从 `HONEYWORDS` 设置中读取。 ## 开发 ### 运行测试 ``` # 安装 dev dependencies pip install -e ".[dev]" # 运行所有测试 pytest # 运行特定测试组 pytest tests/test_amnesia_a1_models.py # Model creation pytest tests/test_amnesia_a2_core.py # Core amnesia logic pytest tests/test_amnesia_a3_backend.py # Authentication backend pytest tests/test_amnesia_a4_command.py # Management command ``` ## 部署说明 - 请勿原样部署 `example_project/settings.py` 配置。 - 使用 `example_project/settings_prod.py` 作为生产环境配置模板(设置 `DJANGO_SECRET_KEY` 和 `DJANGO_ALLOWED_HOSTS`)。 - 在生产环境中,除非您完全了解未使用 `AmnesiaSet` 初始化的用户所面临的绕过风险,否则请避免启用 `django.contrib.auth.backends.ModelBackend`。 - 请勿在生产环境中使用 `MD5PasswordHasher`(它仅在 `example_project/settings_test.py` 中使用,以加快测试速度)。 推荐的生产环境策略: - 除非您已经具备了完整的密码重置用户体验流程,否则建议使用 `ON_HONEYWORD = "lock"`(或 `"log"`)。 - 如果您设置 `ON_HONEYWORD = "reset"`,您的应用程序必须提供密码重置/修改视图和提示信息,以便用户恢复账户。 ## 文档 - 有关生产环境部署清单,请参阅 `docs/deployment.md`。 - 有关在注册/密码修改流程中初始化用户的指南,请参阅 `docs/integration.md`。 - 有关 GitHub + PyPI 发布步骤,请参阅 `docs/releasing.md`。 ### 项目结构 ``` django-amnesia-honeywords/ ├── src/django_honeywords/ │ ├── apps.py # Django app config │ ├── amnesia_service.py # Core amnesia service │ ├── backend.py # Authentication backend │ ├── conf.py # Settings with defaults │ ├── events.py # Event logging │ ├── generator.py # Honeyword generation │ ├── models.py # Database models │ ├── policy.py # Reset/lock policies │ ├── signals.py # Django signals │ └── management/commands/ # Management commands ├── tests/ # Test suite └── example_project/ # Example Django project for testing ``` ## 安全考量 1. **Honeyword 质量**:包含的 `SimpleMutationGenerator` 仅创建基本变体。为了获得更高的安全性,请实现一个能够生成难以区分的 honeywords 的自定义生成器。 2. **审计日志**:所有身份验证尝试都会记录到 `HoneywordEvent` 中。请定期查看这些日志,并为 honeyword 检测设置告警。 3. **参数调优**:`p_mark` 和 `p_remark` 参数控制误报率和检测灵敏度之间的权衡。有关选择值的指导,请参阅 Amnesia 论文。 4. **密码重置流程**:当 `ON_HONEYWORD = "reset"` 时,被标记为 `must_reset` 的用户应被重定向到密码修改页面。请将此与您的应用程序身份验证流程集成。 ## 参考文献 - Juels, A., & Rivest, R. L. (2013). *Honeywords: Making password-cracking detectable*. ACM CCS 2013. - Wang, K. C., & Reiter, M. K. (2021). *Using amnesia to detect credential database breaches*. In 30th USENIX Security Symposium (USENIX Security 21) (pp. 839-855). ## 许可证 MIT 许可证
标签:Atomic Red Team, Django, Python, Syscall, Web开发, 数据泄露检测, 无后门, 蜜语, 逆向工具