Security of simple client/server desktop app I am writing an application aimed at the desktop but using web technologies. It will have an HTML interface and a server written in Python using Flask will do all of the filesystem interaction. It will have the ability to edit user settings so I want to make it impossible for other users to interfere. This is a little tricky because the server and client communicate using HTTP over a localhost port.

The program is split between 3 files:

run.py - controls the start up and shut down of the server and client.

import os
import json
import time
import signal

secret_file = os.path.join(os.environ['HOME'], '.myapp.secret')
if os.path.exists(secret_file):
    os.remove(secret_file)

os.system("python server.py &amp;")

while not os.path.exists(secret_file):
    time.sleep(0.1)

f = open(secret_file)
secret = json.load(f)

url = 'http://localhost:' + str(secret['port']) + '/' + secret['key']

os.system("python client.py " + url)


os.kill(secret['pid'], signal.SIGINT)


server.py

from flask import Flask, request, Response
import socket
import random
import json
import sys
import os

app = Flask(__name__)
key = ''.join(random.sample(
    "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM", 
    random.randint(8, 24)
))
port = 0
secret_file = os.path.join(os.environ['HOME'], '.myapp.secret')

@app.route('/&lt;authkey&gt;')
def hello(authkey):
    if authkey == key:
        return 'Hello, world!'
    else:
        return Response('Access Denied', 401)

def broadcast(port):
    s = json.dumps({
        'key' : key,
        'port' : port,
    'pid' : os.getpid()
    })
    f = open(
        secret_file,
        'w'
    )
    f.write(s)
    os.chmod(secret_file, 0400)
    f.close()


if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 0))
    port = sock.getsockname()[1]
    broadcast(port)
    sock.close()
    app.run(port=port)


client.py

This is a simple GTK window with a webkit widget that renders the page. It renders the URL passed to it by the first argument.

Is this sufficiently secure? Also, are there any other problems that I have not considered?
The important thing you want to enforce is that only the same local user can see the hello world.

You're relying at least on the inability of any random user to


listen in on someone else's sockets.
read another user's files
otherwise learn the secret
execute random python code in your server
And the inability for a remote attacker to connect to your socket.


1, 2 and 4 depend how well you've secured your system (no privilege elevation or random suid files lying around). 4 also depends on the security of flask and the rest of your python stack.

Five can be broken, depending on how your firewall is configured (someone could use connection tracking to get your socket forwarded, even though it is bound to localhost). You'd be better off using unix domain sockets.

The second is broken, because you chmod the file only after you've written to it. That gives a window for the attacker to open the file. In fact the attacker could even write to the file and execute arbitrary commands, which is why you should never use os.system, and you should use urlparse to build the url.

The third is broken in two ways:


the secret appears in the process list
the server won't take the same time to compare strings that are mostly right and mostly wrong. The attacker can guess the length of the secret, and guess the secret letter by letter (timing attack).