195 lines
6.9 KiB
Python
195 lines
6.9 KiB
Python
|
|
# ===================================Flask HOOK========================#
|
|||
|
|
from YakPanel.app import *
|
|||
|
|
|
|||
|
|
# Flask请求勾子
|
|||
|
|
@app.before_request
|
|||
|
|
def request_check():
|
|||
|
|
if request.method not in ['GET', 'POST']: return abort(404)
|
|||
|
|
|
|||
|
|
# 获取客户端真实IP
|
|||
|
|
x_real_ip = request.headers.get('X-Real-Ip')
|
|||
|
|
if x_real_ip:
|
|||
|
|
request.remote_addr = x_real_ip
|
|||
|
|
request.environ.setdefault('REMOTE_PORT', public.get_remote_port())
|
|||
|
|
|
|||
|
|
g.request_time = time.time()
|
|||
|
|
g.return_message = False
|
|||
|
|
# 路由和URI长度过滤
|
|||
|
|
if len(request.path) > 256: return abort(403)
|
|||
|
|
if len(request.url) > 1024: return abort(403)
|
|||
|
|
# URI过滤
|
|||
|
|
if not uri_match.match(request.path): return abort(403)
|
|||
|
|
# POST参数过滤
|
|||
|
|
if request.path in [
|
|||
|
|
'/login',
|
|||
|
|
'/safe',
|
|||
|
|
# '/v2_safe',
|
|||
|
|
'/hook',
|
|||
|
|
'/public',
|
|||
|
|
'/down',
|
|||
|
|
'/get_app_bind_status',
|
|||
|
|
'/check_bind',
|
|||
|
|
'/userRegister',
|
|||
|
|
]:
|
|||
|
|
pdata = request.form.to_dict()
|
|||
|
|
for k in pdata.keys():
|
|||
|
|
if len(k) > 48: return abort(403)
|
|||
|
|
if len(pdata[k]) > 256: return abort(403)
|
|||
|
|
# SESSIONID过滤
|
|||
|
|
session_id = request.cookies.get(app.config['SESSION_COOKIE_NAME'], '')
|
|||
|
|
if session_id and not session_id_match.match(session_id): return abort(403)
|
|||
|
|
|
|||
|
|
# 请求头过滤
|
|||
|
|
# if not public.filter_headers():
|
|||
|
|
# return abort(403)
|
|||
|
|
|
|||
|
|
if session.get('debug') == 1: return
|
|||
|
|
g.get_csrf_html_token_key = public.get_csrf_html_token_key()
|
|||
|
|
|
|||
|
|
if app.config['BASIC_AUTH_OPEN']:
|
|||
|
|
if request.path in [
|
|||
|
|
'/public', '/download', '/mail_sys', '/hook', '/down',
|
|||
|
|
'/check_bind', '/get_app_bind_status'
|
|||
|
|
]:
|
|||
|
|
return
|
|||
|
|
auth = request.authorization
|
|||
|
|
if not comm.get_sk(): return
|
|||
|
|
if not auth: return send_authenticated()
|
|||
|
|
tips = '_capnis.com'
|
|||
|
|
if public.md5(auth.username.strip() + tips) != app.config['BASIC_AUTH_USERNAME'] \
|
|||
|
|
or public.md5(auth.password.strip() + tips) != app.config['BASIC_AUTH_PASSWORD']:
|
|||
|
|
return send_authenticated()
|
|||
|
|
|
|||
|
|
if not request.path in [
|
|||
|
|
'/safe',
|
|||
|
|
# '/v2_safe',
|
|||
|
|
'/hook',
|
|||
|
|
'/public',
|
|||
|
|
'/mail_sys',
|
|||
|
|
'/down'
|
|||
|
|
]:
|
|||
|
|
ip_check = public.check_ip_panel()
|
|||
|
|
if ip_check: return ip_check
|
|||
|
|
|
|||
|
|
if request.path.startswith('/static/') or request.path == '/code':
|
|||
|
|
if not 'login' in session and not 'admin_auth' in session and not 'down' in session:
|
|||
|
|
return abort(401)
|
|||
|
|
domain_check = public.check_domain_panel()
|
|||
|
|
if domain_check: return domain_check
|
|||
|
|
if public.is_local():
|
|||
|
|
not_networks = ['uninstall_plugin', 'install_plugin', 'UpdatePanel']
|
|||
|
|
if request.args.get('action') in not_networks:
|
|||
|
|
return public.returnJson(
|
|||
|
|
False,
|
|||
|
|
'This feature cannot be used in offline mode!'), json_header
|
|||
|
|
|
|||
|
|
if request.path in [
|
|||
|
|
'/site', '/ftp', '/database', '/soft', '/control', '/firewall',
|
|||
|
|
'/files', '/xterm', '/crontab', '/config'
|
|||
|
|
]:
|
|||
|
|
if public.is_error_path():
|
|||
|
|
return redirect('/error', 302)
|
|||
|
|
if not request.path in ['/config']:
|
|||
|
|
if session.get('password_expire', False):
|
|||
|
|
return redirect('/modify_password', 302)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# Flask 请求结束勾子
|
|||
|
|
@app.teardown_request
|
|||
|
|
def request_end(reques=None):
|
|||
|
|
if request.method not in ['GET', 'POST']: return
|
|||
|
|
if not request.path.startswith('/static/'):
|
|||
|
|
public.write_request_log(reques)
|
|||
|
|
#当路由为/plugin时,不检测g.return_message
|
|||
|
|
# if not request.path.startswith('/plugin'):
|
|||
|
|
if request.path.startswith('/sitetest'):
|
|||
|
|
if 'return_message' in g:
|
|||
|
|
if not g.return_message:
|
|||
|
|
public.print_log("当前为网站路由,且未使用统一响应函数public.return_message")
|
|||
|
|
return abort(403)
|
|||
|
|
# return public.returnJson(
|
|||
|
|
# False, 'Request failed!Request not using unified response!'
|
|||
|
|
# ), json_header
|
|||
|
|
else:
|
|||
|
|
g.return_message = False
|
|||
|
|
public.print_log("当前为网站路由,且已使用统一响应函数public.return_message")
|
|||
|
|
if 'api_request' in g:
|
|||
|
|
if g.api_request:
|
|||
|
|
session.clear()
|
|||
|
|
|
|||
|
|
|
|||
|
|
# Flask 404页面勾子
|
|||
|
|
@app.errorhandler(404)
|
|||
|
|
def error_404(e):
|
|||
|
|
if request.method not in ['GET', 'POST']: return
|
|||
|
|
if not session.get('login', None):
|
|||
|
|
g.auth_error = True
|
|||
|
|
return public.error_not_login()
|
|||
|
|
errorStr = '''<html>
|
|||
|
|
<head><title>404 Not Found</title></head>
|
|||
|
|
<body>
|
|||
|
|
<center><h1>404 Not Found</h1></center>
|
|||
|
|
<hr><center>nginx</center>
|
|||
|
|
</body>
|
|||
|
|
</html>'''
|
|||
|
|
headers = {"Content-Type": "text/html"}
|
|||
|
|
return Response(errorStr, status=404, headers=headers)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# Flask 403页面勾子
|
|||
|
|
@app.errorhandler(403)
|
|||
|
|
def error_403(e):
|
|||
|
|
if request.method not in ['GET', 'POST']: return
|
|||
|
|
if not session.get('login', None):
|
|||
|
|
g.auth_error = True
|
|||
|
|
return public.error_not_login()
|
|||
|
|
errorStr = '''<html>
|
|||
|
|
<head><title>403 Forbidden</title></head>
|
|||
|
|
<body>
|
|||
|
|
<center><h1>403 Forbidden</h1></center>
|
|||
|
|
<hr><center>nginx</center>
|
|||
|
|
</body>
|
|||
|
|
</html>'''
|
|||
|
|
headers = {"Content-Type": "text/html"}
|
|||
|
|
return Response(errorStr, status=403, headers=headers)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# Flask 500页面勾子
|
|||
|
|
@app.errorhandler(500)
|
|||
|
|
def error_500(e):
|
|||
|
|
if request.method not in ['GET', 'POST']: return
|
|||
|
|
if not session.get('login', None):
|
|||
|
|
g.auth_error = True
|
|||
|
|
return public.error_not_login()
|
|||
|
|
ss = '''404 Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
|
|||
|
|
|
|||
|
|
During handling of the above exception, another exception occurred:'''
|
|||
|
|
error_info = public.get_error_info().strip().split(ss)[-1].strip()
|
|||
|
|
_form = request.form.to_dict()
|
|||
|
|
if 'username' in _form: _form['username'] = '******'
|
|||
|
|
if 'password' in _form: _form['password'] = '******'
|
|||
|
|
if 'phone' in _form: _form['phone'] = '******'
|
|||
|
|
request_info = '''REQUEST_DATE: {request_date}
|
|||
|
|
PAN_VERSION: {panel_version}
|
|||
|
|
OS_VERSION: {os_version}
|
|||
|
|
REMOTE_ADDR: {remote_addr}
|
|||
|
|
REQUEST_URI: {method} {full_path}
|
|||
|
|
REQUEST_FORM: {request_form}
|
|||
|
|
USER_AGENT: {user_agent}'''.format(
|
|||
|
|
request_date=public.getDate(),
|
|||
|
|
remote_addr=public.GetClientIp(),
|
|||
|
|
method=request.method,
|
|||
|
|
full_path=public.xsssec(request.full_path),
|
|||
|
|
request_form=public.xsssec(str(_form)),
|
|||
|
|
user_agent=public.xsssec(request.headers.get('User-Agent')),
|
|||
|
|
panel_version=public.version(),
|
|||
|
|
os_version=public.get_os_version())
|
|||
|
|
|
|||
|
|
result = public.readFile(
|
|||
|
|
public.get_panel_path() +
|
|||
|
|
'/YakPanel/templates/default/panel_error.html').format(
|
|||
|
|
error_title=error_info.split("\n")[-1],
|
|||
|
|
request_info=request_info,
|
|||
|
|
error_msg=error_info)
|
|||
|
|
return Resp(result, 500)
|