How to secure a static file using python flask.
0
When it come to adding a file to your site it is very important to secure it from unknown access, it could be either
you photos, videos or even audio, So in this article we will be learning how to secure a file on a
internet.
Note:- We are going to use Python Flask as an example, if not flask you can take idea of what we are
going to do.
How we normally send a file.
This is how we normally send a static file.
from flask import Flask, jsonify, request, abort, send_from_directory, send_file, make_response, render_template, url_for, redirect, Response
app = Flask(__name__)
@app.route("/")
def player():
return send_file("---/---/----.png")
if __name__ == '__main__':
app.run()
This method have one issue it is now kind of a public url. When ever you hit a request to "/" it send you this file. But we don't want that so what we can do is add some extra logic before delivering file. Eg
How to send a file
from flask import Flask, send_file, abort
app = Flask(__name__)
@app.route("/")
def player():
token = request.args.get('token')
if not tokenIsValid(token):
abort(400)
return send_file("---/---/----.png")
@app.before_request
def check():
key = request.args.get('key')
if not keyIsValid(key):
abort(400)
if __name__ == '__main__':
app.run()
Above method now make sure that only a request with valid key and token have access. Awesome now your file is secure from unknown access.
You have a static file?
If you have a static file stored on drive or anything else above won't work for you, So what to do? May be this can help you
@app.route("/api/audio")
def stream_audio():
file = request.args.get('file')
token = request.args.get('token')
if not fileExist(file) or not IsTokenValid(token):
abort(400)
url = url_for('yehee', _external=True)
# make sure "url" is you drive url or else
return redirect(url)
# Assuming it is your public url like google drive link or .....
@app.route("/im_public_url")
def yehee():
# add you logic here
return send_file("path/to/file")
Now the problem looks like solved right? Hold on we have dev tools on browser which tells that the requested url redirected us to "url" you passed in "return redirect(url) ", What to do next?
May be this works for you
At first what we do is download a file of "url", And forward that file, This is how we perform that:-
def generate_audio(url):
response = requests.get(url, stream=True)
response.content
if response.status_code == 200:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
yield chunk
else:
break
else:
return None
# For my eg i m using audio file you can use any
@app.route("/api/audio")
def stream_audio():
file = request.args.get('id')
if not strongValidationPassed(file):
abort(400)
url = "https://mydoamin.com/audio/123.mp3"
audio = generate_audio(url)
return Response(audio, mimetype="audio/mpeg")
Nothing worked?
If above method didn't worked for you then you probably have a huge file, so you have only few solution
- Store the file on your own server
- SSR(server side rendering), Use this technique to prevent from exposed of url.
- Adding of validation on you service provider like firebase offers AppCheck like wise other
Hope You got basic idea of how to prevent from exposed of url. For me the download of file worked, because i m dealing with small file.