bug fixes in block creation and directory security

master
Kevin Froman 2020-11-23 03:47:50 +00:00
parent de271794fd
commit e831a27ae3
7 changed files with 46 additions and 23 deletions

View File

@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [7.1.0] - 2020-11-23
* Check for ownership of existing dirs in createdirs, this prevents the rare edge case where a user might use a home directory in a location an attacker could write (allowing arbitrary code execution via plugins). This was already partially mitigated by the chmod of the home directory in any case, but this further fixes the issue.
## [7.0.0] - 2020-11-22 ## [7.0.0] - 2020-11-22
* Removed communicator timers * Removed communicator timers

View File

@ -5,5 +5,5 @@ echo "Enter to continue, ctrl-c to stop."
read read
git pull origin master git pull origin master
pip install -r --require-hashes requirements.txt pip3 install -r --require-hashes requirements.txt
./onionr.sh reset-plugins ./onionr.sh reset-plugins

View File

@ -23,7 +23,7 @@ import filepaths
DENIABLE_PEER_ADDRESS = "OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA" DENIABLE_PEER_ADDRESS = "OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA"
PASSWORD_LENGTH = 25 PASSWORD_LENGTH = 25
ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net' ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net'
ONIONR_VERSION = '7.0.0' ONIONR_VERSION = '7.1.0'
ONIONR_VERSION_CODENAME = 'Genesis' ONIONR_VERSION_CODENAME = 'Genesis'
ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION) ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
API_VERSION = '2' # increments of 1; only change when something fundamental about how the API works changes. This way other nodes know how to communicate without learning too much information about you. API_VERSION = '2' # increments of 1; only change when something fundamental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.

View File

@ -95,6 +95,11 @@ class Timeout(Exception):
# file exceptions # file exceptions
class InsecureDirectoryUsage(IOError):
"""This occurs when a directory used by the daemon is not owned by the user.
This is important to stop code execution attacks"""
pass
class DiskAllocationReached(Exception): class DiskAllocationReached(Exception):
pass pass

View File

@ -116,24 +116,26 @@ class SubprocessPOW:
metadata['n'] = secrets.randbits(16) metadata['n'] = secrets.randbits(16)
puzzle = self.puzzle puzzle = self.puzzle
difficulty = self.difficulty difficulty = self.difficulty
try:
while True: while True:
# Break if shutdown received # Break if shutdown received
try: try:
if pipe.poll() and pipe.recv() == 'shutdown': if pipe.poll() and pipe.recv() == 'shutdown':
break
except KeyboardInterrupt:
break break
except KeyboardInterrupt: # Load nonce into block metadata
break metadata['c'] = nonce
# Load nonce into block metadata # Serialize metadata, combine with block data
metadata['c'] = nonce payload = json.dumps(metadata).encode() + b'\n' + data
# Serialize metadata, combine with block data # Check sha3_256 hash of block, compare to puzzle
payload = json.dumps(metadata).encode() + b'\n' + data # Send payload if puzzle finished
# Check sha3_256 hash of block, compare to puzzle token = sha3_hash(payload)
# Send payload if puzzle finished # ensure token is string
token = sha3_hash(payload) token = bytesconverter.bytes_to_str(token)
# ensure token is string if puzzle == token[0:difficulty]:
token = bytesconverter.bytes_to_str(token) pipe.send(payload)
if puzzle == token[0:difficulty]: break
pipe.send(payload) nonce += 1
break except KeyboardInterrupt:
nonce += 1 pass

View File

@ -4,9 +4,12 @@ Create required Onionr directories
""" """
import os import os
import stat import stat
from pwd import getpwuid
from getpass import getuser
from . import identifyhome from . import identifyhome
import filepaths import filepaths
import onionrexceptions
""" """
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -24,6 +27,10 @@ import filepaths
home = identifyhome.identify_home() home = identifyhome.identify_home()
def find_owner(filename):
return getpwuid(os.stat(filename).st_uid).pw_name
def create_dirs(): def create_dirs():
"""Create onionr data-related directories in """Create onionr data-related directories in
order of the hardcoded list below, order of the hardcoded list below,
@ -33,6 +40,11 @@ def create_dirs():
for path in gen_dirs: for path in gen_dirs:
if not os.path.exists(path): if not os.path.exists(path):
os.makedirs(path) os.makedirs(path)
else:
if getuser() != find_owner(path):
raise onionrexceptions.InsecureDirectoryUsage(
"Directory " + path +
" already exists and is not owned by the same user")
os.chmod(home, stat.S_IRWXU) os.chmod(home, stat.S_IRWXU)

View File

@ -1 +1 @@
1606002757 1606103134