From bff89a3508e1d73680b3e7cb8c85f4fd9a908609 Mon Sep 17 00:00:00 2001 From: Kunal Mehta Date: Wed, 26 Jan 2022 12:21:15 -0800 Subject: [PATCH] Obscure creation time of source private keys on disk We set the GPG key creation time to 2013-05-14 to hide when they were created, revealing when a source started using SecureDrop. However this information was being leaked via the file modification time of the private key material in the $keydir/private-keys-v1.d/ folder. While we can easily change a file's mtime to a past date, faking the ctime really isn't possible. So instead we touch each private key when the source app starts to mask the real creation time. Because of the nightly restarts, this will be updated within 24 hours of source creation. Fixes https://github.com/freedomofpress/securedrop-security/issues/71. --- securedrop/source_app/__init__.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/securedrop/source_app/__init__.py b/securedrop/source_app/__init__.py index 962f210702..0934879819 100644 --- a/securedrop/source_app/__init__.py +++ b/securedrop/source_app/__init__.py @@ -1,6 +1,8 @@ from pathlib import Path from typing import Optional +import os +import time import werkzeug from flask import (Flask, render_template, escape, flash, Markup, request, g, session, url_for) @@ -134,4 +136,15 @@ def page_not_found(error: werkzeug.exceptions.HTTPException) -> Tuple[str, int]: def internal_error(error: werkzeug.exceptions.HTTPException) -> Tuple[str, int]: return render_template('error.html'), 500 + # Obscure the creation time of source private keys by touching them all + # on startup. + private_keys = Path(config.GPG_KEY_DIR) / 'private-keys-v1.d' + now = time.time() + for entry in os.scandir(private_keys): + if not entry.is_file() or not entry.name.endswith('.key'): + continue + os.utime(entry.path, times=(now, now)) + # So the ctime is also updated + os.chmod(entry.path, entry.stat().st_mode) + return app