q48academy / gdpr-privacy-by-design
PHP的隐私设计GDPR课程
Requires
- php: ^7.2
- ext-json: *
- ext-mbstring: *
- ext-sodium: *
Requires (Dev)
- phpunit/phpunit: ^8.4
This package is auto-updated.
Last update: 2024-09-29 05:22:19 UTC
README
PHP中的GDPR / DSGVO课程
免责声明
这是一个法律问题的技术解决方案。这不是法律建议。请咨询您的律师,以确认此处理是否符合您的环境。
关键考虑因素
GDPR是一个类,用于符合三个主要GDPR要求
- 隐私设计
- 默认隐私
- 数据最小化
目标是缩减可能关键数据,以避免如果相关数据根本不使用的情况下出现额外的法律要求。
核心过程
所有不必要的个人可识别信息(PII)数据都应该被清除或匿名化。
如果
- 在此过程调用之前没有其他访问,并且
- 其他过程仅通过
$_SERVER
超级全局变量访问此类数据
那么您就不会再处理PII。
这将禁用所有GDPR要求(在匿名化后),因为GDPR仅讨论个人可识别信息。当然,匿名化和删除的过程必须在您的流程中进行记录。
再次提醒:请与您的律师核实此过程。
如果您将其匿名化,可以选择加密原始数据以稍后访问。默认情况下,所有对原始数据的访问都将被记录。
文档/记录
对PII的每个处理(读取、转换、删除)都必须进行记录。即使是匿名化或删除也是如此。日志必须记录此过程的存在和工作状态。
但是,在原始日志中记录PII以记录您负责任地使用PII是不可能的。必须防止PII泄露。
我们使用基于Sodium的私有/公共密钥加密来加密每个日志条目,以便只有审计人员可以访问记录数据。
您可以将审计人员的公钥放在密钥目录中。您绝对不能在密钥目录中提供审计人员的私钥。请将其安全地保留仅供审计过程使用。
所有单个日志条目都是一个由本地盒子签名并使用审计人员公钥加密的JSON数组。
您可以将加密的日志条目转发到您选择的任何日志服务。
如果本地记录,所有日志文件都存储在每日目录中,并在两天后删除。
安装
composer require q48academy/gdpr-privacy-by-design
使用方法
此类负责以符合GDPR的方式处理潜在的个人信息。
清除信息
警告:清除这些信息可能会在您的应用程序中出现意外的行为。请仔细测试。
基本用法是清除以下潜在个人信息:
Gdpr::wipeIp();
如您所知,REMOTE_ADDR
并不总是持有正确数据,如果您在代理后面。您可以转发与您环境对应的密钥。
Gdpr::wipeIp( 'HTTP_X_FORWARDED_FOR' );
相同的函数可用于其他可能包含PII的密钥。
Gdpr::wipeUserAgent();
Gdpr::wipeReferrer();
Gdpr::wipeQueryString();
Gdpr::wipeCookies();
匿名化信息
警告:匿名化这些信息可能会在您的应用程序中出现意外的行为。请仔细测试。
关键功能
对于每个键字段有三个方法。
getAnon[Key]
,即getAnonIp()
,用于获取匿名化数据setAnon[Key]
,即setAnonIp()
,用于设置匿名化数据getRaw[Key]
,例如getRawIp()
,用于获取调用带有 'doEncrypt' 选项的setAnon[Key]
后的原始数据
选项
不同的键提供不同的选项。选项作为数组传递给获取器和设置器
始终可用的选项有
- 'index':包含信息的
$_SERVER
数组的键。例如REMOTE_ADDR
- 'doEncrypt':原始数据将存储以供以后检索。它将存储在基于 'index' 的键中,例如
GDPR_REMOTE_ADDR
IP
原因
IP 被认为是 PII,随着 IPv6 的出现,这一点似乎非常明显。
匿名化概念
将特定的字节数设置为 '0'。
基本用法
$gdpr = new Gdpr();
$anonIp = $gdpr->getAnonIp();
特殊选项
- 'rawIp':IP 应该不是从
$_SERVER
数组中获取,而是以原始方式给出。信息将存储在 'index' 中,例如REMOTE_ADDR
- 'v4':应设置为零以匿名化的 IPv4 地址的字节数。目前默认值为 1。
- 'v6':应设置为零以匿名化的 IPv6 地址的字节数。目前默认值为 4。
用户代理
原因
用户代理被认为是 PII,因为它可以用来创建设备指纹。
匿名化概念
移除所有版本信息。保持匿名化
- 操作系统
- 移动/平板电脑
- 浏览器
机器人不会进行匿名化。
基本用法
$gdpr = new Gdpr();
$anonIp = $gdpr->getAnonUserAgent();
设置可以通过 ENV 设置
GDPR_DIR_KEYS=/etc/.keys
GDPR_DIR_LOGS=/var/log/gdpr
类也可以通过两个设置启动
-
keyDir
-
logDir
$gdpr = new Gdpr('/etc/.keys','/var/log/gdpr');
安装验证
$gdpr = new Gdpr();
$verifyLog = $gdpr->verify();
var_dump($verifyLog);
特殊选项
- 'rawUserAgent':用户代理不应从
$_SERVER
数组中获取,而应以原始方式给出。信息将存储在 'index' 中,例如HTTP_USER_AGENT
HTTP Referer
原因
Referer 可以包含 PII。
匿名化概念
移除所有路径和查询信息。仅保留主机。如果主机与白名单匹配,则保留路径信息。
基本用法
$gdpr = new Gdpr();
$anonIp = $gdpr->getAnonReferrer();
特殊选项
- 'rawReferrer':Referer 不应从
$_SERVER
数组中获取,而应以原始方式给出。信息将存储在 'index' 中,例如HTTP_REFERER
- 'whitelist':包含主机名的数组
HTTP Referer
原因
Referer 可以包含 PII。
匿名化概念
移除所有路径和查询信息。仅保留主机。如果主机与白名单匹配,则保留路径信息。
基本用法
$gdpr = new Gdpr();
$anonIp = $gdpr->getAnonReferrer();
特殊选项
- 'rawReferrer':Referer 不应从
$_SERVER
数组中获取,而应以原始方式给出。信息将存储在 'index' 中,例如HTTP_REFERER
- 'whitelist':包含主机名的数组
查询字符串
原因
查询字符串可以包含 PII。例如 http://example.com/?mynameis=John+Smith
匿名化概念
移除所有查询键。如果键与白名单匹配,则保留路径信息。
基本用法
$gdpr = new Gdpr();
$anonIp = $gdpr->getAnonQueryString();
特殊选项
- 'rawQueryString':查询字符串不应从
$_SERVER
数组中获取,而应以原始方式给出。信息将存储在 'index' 中,例如QUERY_STRING
- 'whitelist':包含查询键的数组
请求 URI
原因
请求 URI 可以包含 PII。例如 http://example.com/path?mynameis=John+Smith
匿名化概念
移除查询字符串。如果键与白名单匹配,则保留路径信息。
注意:PII 可以通过 404 请求泄露,例如 http://example.com/mynameis/John+Smith
。这应在您的应用程序中处理。
基本用法
$gdpr = new Gdpr();
$anonIp = $gdpr->getAnonRequestUri();
特殊选项
- 'rawRequestUri':请求 URI 不应从
$_SERVER
数组中获取,而应以原始方式给出。信息将存储在 'index' 中,例如REQUEST_URI
- 'whitelist':包含查询键的数组
访问原始数据
如果需要访问原始数据,则必须提供一些信息,并将进行记录。
public function getRawIp(string $lawful_purpose, string $data_category, string $process_reason, string $accessor ,array $options=[]):string
合法目的
GDPR 的合法目的作为常量提供
const LAWFUL_PURPOSE_CONSENT = 'consent';
const LAWFUL_PURPOSE_CONTRACTUAL_OBLIGATION = 'contract';
const LAWFUL_PURPOSE_LEGAL_OBLIGATION = 'legal';
const LAWFUL_PURPOSE_VITAL_INTEREST_OF_INDIVIDUAL = 'vital';
const LAWFUL_PURPOSE_PUBLIC_INTEREST = 'public';
const LAWFUL_PURPOSE_LEGITIMATE_INTEREST = 'interest';
数据类别
GDPR 的数据类别作为常量提供
const DATA_CATEGORY_DEFAULT = 'default';
const DATA_CATEGORY_ETHNICITY = 'ethnicity';
const DATA_CATEGORY_POLITICS = 'politics';
const DATA_CATEGORY_RELIGION = 'religion';
const DATA_CATEGORY_LABOR_UNION = 'laborUnion';
const DATA_CATEGORY_HEALTH = 'health';
const DATA_CATEGORY_SEXUAL = 'sexual';
处理原因
GDPR 的处理原因作为常量提供
const PROCESS_REASON_CREATE = 'create';
const PROCESS_REASON_READ = 'read';
const PROCESS_REASON_UPDATE = 'update';
const PROCESS_REASON_DELETE = 'delete';
const PROCESS_REASON_PUBLISH = 'publish';
const PROCESS_REASON_COMBINE = 'combine';
const PROCESS_REASON_ANONYMIZE = 'anonymize';
const PROCESS_REASON_ENCRYPT = 'encrypt';
访问者
访问者是访问此数据的类|函数|作者
待办事项:提供关于此访问过程记录的信息