← [ BACK_TO_NOTES ]

BodySense 数据库第 19 课:Database Security、Privacy Erasure 与 Data Lifecycle

结合 BodySense 健康数据场景学习最小权限、PII/secret 边界、日志泄露、删除级联、privacy erasure、审计与数据生命周期。

#course #growing #backend #database #postgresql #bodysense

[!info] related notes

BodySense 数据库第 19 课:Database Security、Privacy Erasure 与 Data Lifecycle

[!abstract] 本课目标 数据库安全不只是 SQL Injection。对健康类系统,必须知道谁能读什么、数据复制到哪里、删除时哪些派生副本还存在。

从零建立概念:Database Security 不只是 SQL Injection

一提数据库安全,最先想到:

SQL Injection

它当然重要,但生产数据库的攻击面还包括:

credential theft
over-privileged account
network exposure
backup leakage
logs containing sensitive values
IDOR / authorization bugs
misconfigured replica
unsafe migration role
insider access
retention / erasure failure

所以这一课从“数据生命周期”看安全。

Authentication 与 Authorization

Authentication

这个 database client 是谁?

例如:

bodysense_api role
migration role
admin role
monitoring role

Authorization

这个 role 能做什么?

例如:

SELECT
INSERT
UPDATE
DELETE
CREATE TABLE
ALTER TABLE
CREATE EXTENSION
read specific schema

不要因为应用能连接,就让它拥有 superuser。

Least Privilege 从零理解

原则:

一个身份只拥有完成职责所需的最小权限。

例如 Runtime API 正常只需要:

read/write application tables
maybe execute selected functions

不代表它需要:

DROP DATABASE
CREATE ROLE
ALTER SYSTEM
CREATE EXTENSION

把 Migration Role 单独拆出来的价值:

API credential leaked
→ attacker blast radius smaller

Network Boundary

数据库端口不应该默认暴露给整个 Internet。

常见:

private network / VPC
firewall/security group
TLS
allowlisted clients
managed DB network policy

Redis/PostgreSQL 都一样:

Authentication 不是网络暴露的替代品。

Parameterized Query 与 SQL Injection

危险:

sql := "SELECT * FROM users WHERE email='" + input + "'"

用户输入可能改变 SQL 结构。

参数化:

SELECT * FROM users
WHERE email = $1

Driver 把 SQL structure 与 data value 分开。

ORM 正常 query API 也通常参数化,但:

Raw SQL
dynamic ORDER BY / column names
string-built clauses

仍要审查。

SQL Injection 防住了,也不代表 Authorization 正确

例如:

SELECT * FROM assessment_reports
WHERE id = $1

SQL 完全参数化。

但如果 API 没检查:

report.user_id == current_user

攻击者知道别人的 report id 仍可能读取。

这是 IDOR/BOLA,属于 authorization boundary。

数据库访问层需要把:

user-scoped query
tenant boundary
resource ownership

设计清楚。

Sensitive Data Classification

先分类才知道怎么保护。

BodySense 可能涉及:

Credentials

password hash
refresh/token secret
DB password
API key

PII

email
name
IP
device/account identifiers

Health / Body Data

body measurements
symptoms
observations
diagnosis/treatment history
uploads

Derived Data

embedding
projection
cache
analytics
search index

“派生”不等于“不敏感”。

如果 embedding / projection 仍能关联某用户健康信息,它仍属于 data lifecycle 的一部分。

At Rest / In Transit

In Transit

Application ↔ PostgreSQL

应考虑 TLS,尤其跨主机/不可信网络。

At Rest

数据库磁盘、snapshot、backup 可能由:

disk encryption
managed service encryption
encrypted backup

保护。

加密解决的是介质/传输风险的一部分,不替代应用 authorization。

Password 为什么存 Hash,不存可逆 Encryption

Password verification 不需要恢复原文。

所以应使用:

slow password hashing KDF
→ bcrypt / Argon2id 等

数据库泄露时提高破解成本。

不要把 password 当普通 secret:

AES encrypt password
→ application has decryption key
→ attacker gets DB + key may recover all plaintext

Logs 是数据复制系统

每次写:

log.Info("query", payload)

其实是在把数据复制到:

log file
collector
APM
cloud logging
retention archive
developer dashboard

因此 SQL logger 可能扩大敏感数据表面积。

BodySense database.go 在 staging/production 将 GORM logger 默认降低到 Warn,注释明确是为了避免把 consultation/body-state payload 通过 SQL interpolation 写进共享环境日志。

Privacy Erasure:删除不是一条 SQL

用户要求删除数据时,第一步是建立 Data Inventory。

PostgreSQL authoritative tables
Redis session/cache
Object Storage uploads
pgvector / RAG derived rows
analytics
search index
backups
logs
third-party processors

如果只:

DELETE FROM users

其他副本仍可能存在。

ON DELETE CASCADE 解决什么

如果 child 的生命周期完全属于 parent:

user
└─ owned child

FK:

ON DELETE CASCADE

可以自动保持 referential cleanup。

但它不是隐私策略本身。

有些数据:

audit
billing
security event
legal retention

可能需要:

anonymize
retain minimal fields
expire later
explicit erasure workflow

不能全部 CASCADE。

Soft Delete 与 Erasure 不是同一个词

Soft Delete:

deleted_at = now
→ application hides row
→ bytes still exist

它适合:

undo
business history
workflow state

但:

如果要求真正删除个人数据,单纯 soft delete 往往不满足 erasure 目标。

必须明确 retention policy。

Backup 中的删除为什么特殊

很多 Backup 是:

immutable / append-retained

不现实每次用户删除都重写所有历史备份。

常见治理思路:

online systems erase promptly
backups access strictly restricted
backup retention expires
restore procedure re-applies erasure ledger before serving production

具体要求取决于法律/组织政策,但工程上必须把 Backup 纳入 data lifecycle。

Audit 与 Privacy 的张力

Audit 希望:

history not silently changed

Privacy 希望:

personal data not retained unnecessarily

设计需要:

记录 action identity / time / object
但避免记录不必要完整敏感 payload

这是 Data Minimization:

不因为“以后可能 debug”就无限复制和永久保留健康数据。

1. Least Privilege

应用数据库账号不应该默认是 superuser。应按需要授权 schema/table/sequence/extension 能力,migration role 与 runtime role 也可以分离。

2. Sensitive Data

分类:

credential secret
PII
health data
audit metadata
derived analytics
cache/search/embedding copies

不同类别有不同日志、保留、删除和访问策略。

3. SQL Log 也会泄露数据

BodySense production 调低 GORM SQL interpolation log level,就是为了避免 consultation/body-state payload 被写进共享日志。

Parameterized query 防 SQL injection,但不会自动防止敏感参数进入应用日志。

4. Privacy Erasure

删除用户不是:

DELETE FROM users WHERE id = ?;

就结束。要追踪:

FK child tables
uploads/object storage
Redis session/cache
pgvector / RAG derived rows
analytics/events
backup retention
audit exceptions

必须区分“立即从在线系统删除”和“历史备份按 retention 最终淘汰”。

5. ON DELETE CASCADE 不是万能隐私策略

CASCADE 很适合强 ownership child,但某些审计/不可变历史可能需要匿名化、软删除、保留法定字段或显式 lifecycle。关系语义必须先定义。

Prediction

[!question]

  1. 使用 parameterized SQL 后,数据库相关安全问题是否基本解决?
  2. Runtime 应用账号为什么不一定需要 CREATE EXTENSION / ALTER TABLE 权限?
  3. 用户表 ON DELETE CASCADE 能否证明 privacy erasure 已完整?
  4. 备份中的已删除数据该如何理解?
  5. 为方便 debug,把完整健康 JSONB 打到 SQL log 是否合适?

[!success]- Answer / 解析 1. 远远没有。 仍有权限、数据泄露、IDOR/authorization、日志、备份、连接 secret、生命周期等问题。

2. 这些是 schema/migration 权限,runtime 不需要时应遵循 least privilege,降低凭证泄露后的 blast radius。

3. 不能。 数据可能复制到 Redis、对象存储、向量库、analytics 和备份;还要检查非 FK 关联和外部系统。

4. 通常无法瞬时修改所有 immutable backup;需要明确 retention、访问控制和恢复后重新执行 erasure 的策略。

5. 不合适。 shared logs 会扩大敏感数据表面积;应记录结构化非敏感诊断或显式 redaction。

Lab

为 BodySense 做一张 user-data inventory:每一类用户数据列出 authority、派生副本、delete mechanism、retention、是否进入日志/备份。

L4 Gate

给定“用户请求删除账户”,能画出一条覆盖 PostgreSQL + Redis + uploads + vector/search + backup 的完整删除/保留边界。

创建于 2026/9/18 更新于 2026/9/18
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本