Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: reduce mode of SQLite storage file to 0o600 #1057

Merged
merged 12 commits into from
Nov 15, 2023
19 changes: 19 additions & 0 deletions ops/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import pickle
import shutil
import sqlite3
import stat
import subprocess
from datetime import timedelta
from pathlib import Path
Expand Down Expand Up @@ -59,11 +60,29 @@ def __init__(self, filename: Union['Path', str]):
# sqlite3.connect creates the file silently if it does not exist
logger.debug(f"Initializing SQLite local storage: {filename}.")

if filename != ":memory:":
self._ensure_db_permissions(str(filename))
self._db = sqlite3.connect(str(filename),
isolation_level=None,
timeout=self.DB_LOCK_TIMEOUT.total_seconds())
self._setup()

def _ensure_db_permissions(self, filename: str):
"""Make sure that the DB file has appropriately secure permissions."""
mode = stat.S_IRUSR | stat.S_IWUSR
if os.path.exists(filename):
try:
os.chmod(filename, mode)
except OSError as e:
logger.warning(f"Unable to adjust permissions of storage file {filename!r}: {e}")
return
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
try:
fd = os.open(filename, os.O_CREAT | os.O_EXCL, mode=mode)
except OSError as e:
logger.warning(f"Unable to ensure permissions of storage file {filename!r}: {e}")
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
else:
os.close(fd)

def _setup(self):
"""Make the database ready to be used as storage."""
# Make sure that the database is locked until the connection is closed,
Expand Down
8 changes: 8 additions & 0 deletions test/test_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io
import os
import pathlib
import stat
import sys
import tempfile
import typing
Expand Down Expand Up @@ -218,6 +219,13 @@ class TestSQLiteStorage(StoragePermutations, BaseTestCase):
def create_storage(self):
return ops.storage.SQLiteStorage(':memory:')

def test_permissions(self):
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved
with tempfile.TemporaryDirectory() as temp_dir:
filename = os.path.join(temp_dir, "framework.data")
storage = ops.storage.SQLiteStorage(filename)
self.assertEqual(stat.S_IMODE(os.stat(filename).st_mode), stat.S_IRUSR | stat.S_IWUSR)
storage.close()


def setup_juju_backend(test_case: unittest.TestCase, state_file: pathlib.Path):
"""Create fake scripts for pretending to be state-set and state-get."""
Expand Down
Loading