Skip to content

第九站练习答案 ​

返回纵览 | 专题一 | 专题二

python
from django.test import Client, TestCase
from django.urls import reverse


class CsrfTests(TestCase):
    def test_post_without_csrf_is_rejected(self):
        client = Client(enforce_csrf_checks=True)
        client.force_login(self.user)
        response = client.post(
            reverse("tickets:edit", args=[self.ticket.pk]),
            {"title": "changed", "priority": 3},
        )
        self.assertEqual(response.status_code, 403)
python
class CspTests(TestCase):
    def test_report_only_policy_is_present(self):
        response = self.client.get(reverse("health"))
        policy = response["Content-Security-Policy-Report-Only"]
        self.assertIn("default-src 'self'", policy)

运行:

bash
python manage.py test tickets.tests.CsrfTests tickets.tests.CspTests

专题二核对 ​

python
from django.core.files.uploadedfile import SimpleUploadedFile

small = SimpleUploadedFile("proof.txt", b"ok", content_type="text/plain")
oversized = SimpleUploadedFile("large.txt", b"x" * (2 * 1024 * 1024 + 1), content_type="text/plain")

分别断言合法文件通过、超限文件进入表单错误。上传先落隔离区,扫描失败保持 quarantined 且不可下载。异常日志保留 request ID、版本和稳定错误码,删除 Cookie、Authorization、表单正文和文件内容。

深水边界 ​

如果视图需要登录,未带 CSRF 的匿名请求可能先被重定向;测试必须构造能真正到达写路径的身份和 URL。安全测试要验证威胁路径,不只是状态码快照。

开放练习(不提供答案) ​

在反向代理后验证 SECURE_PROXY_SSL_HEADER、HTTPS 重定向、安全 Cookie 和 Host 校验;记录错误信任代理头如何让应用误判连接安全。

继续第十站

加码题解:安全测试与上传边界 ​

python
def safe_name(name):
    import uuid
    suffix = name.rsplit('.', 1)[-1].lower()
    if suffix not in {'png', 'jpg', 'jpeg'}:
        raise ValueError('unsupported extension')
    return f'{uuid.uuid4().hex}.{suffix}'

关键推理 ​

存储 key 不沿用用户文件名,扩展名只作为初筛,内容扫描仍需在后续状态机完成。

可替代方案 ​

把文件放入对象存储隔离区,扫描通过后再生成可下载 URL。

典型错误 ​

相信 Content-Type 或扩展名就直接公开文件;日志中记录完整 token 和请求体。

复盘时请把状态码/事务/权限/资源清理中的至少一项写成自动化测试,而不是只截图成功页面。

用心记录每一步成长