forked from rDrama/rDrama
sanitize
parent
c34d641284
commit
095e5cb0af
|
@ -11,6 +11,8 @@ from random import random, choice
|
|||
import signal
|
||||
import time
|
||||
import requests
|
||||
import cssutils
|
||||
import tldextract
|
||||
|
||||
TLDS = ('ac','ad','ae','aero','af','ag','ai','al','am','an','ao','aq','ar','arpa','as','asia','at','au','aw','ax','az','ba','bb','bd','be','bf','bg','bh','bi','biz','bj','bm','bn','bo','br','bs','bt','bv','bw','by','bz','ca','cafe','cat','cc','cd','cf','cg','ch','ci','ck','cl','club','cm','cn','co','com','coop','cr','cu','cv','cx','cy','cz','de','dj','dk','dm','do','dz','ec','edu','ee','eg','er','es','et','eu','fi','fj','fk','fm','fo','fr','ga','gb','gd','ge','gf','gg','gh','gi','gl','gm','gn','gov','gp','gq','gr','gs','gt','gu','gw','gy','hk','hm','hn','hr','ht','hu','id','ie','il','im','in','info','int','io','iq','ir','is','it','je','jm','jo','jobs','jp','ke','kg','kh','ki','km','kn','kp','kr','kw','ky','kz','la','lb','lc','li','lk','lr','ls','lt','lu','lv','ly','ma','mc','md','me','mg','mh','mil','mk','ml','mm','mn','mo','mobi','mp','mq','mr','ms','mt','mu','museum','mv','mw','mx','my','mz','na','name','nc','ne','net','nf','ng','ni','nl','no','np','nr','nu','nz','om','org','pa','pe','pf','pg','ph','pk','pl','pm','pn','post','pr','pro','ps','pt','pw','py','qa','re','ro','rs','ru','rw','sa','sb','sc','sd','se','sg','sh','si','sj','sk','sl','sm','sn','so','social','sr','ss','st','su','sv','sx','sy','sz','tc','td','tel','tf','tg','th','tj','tk','tl','tm','tn','to','tp','tr','travel','tt','tv','tw','tz','ua','ug','uk','us','uy','uz','va','vc','ve','vg','vi','vn','vu','wf','win','ws','xn','xxx','xyz','ye','yt','yu','za','zm','zw')
|
||||
|
||||
|
@ -326,3 +328,20 @@ def filter_emojis_only(title, edit=False, graceful=False):
|
|||
|
||||
if len(title) > 1500 and not graceful: abort(400)
|
||||
else: return title
|
||||
|
||||
|
||||
def sanitize_css(rule):
|
||||
if isinstance(rule, cssutils.css.CSSStyleRule):
|
||||
|
||||
for property in rule.style.children():
|
||||
for pv in property.propertyValue:
|
||||
if isinstance(pv, cssutils.css.URIValue):
|
||||
domain = tldextract.extract(pv.uri).registered_domain
|
||||
if domain not in approved_embed_hosts:
|
||||
return f"The domain '{domain}' is not allowed, please use one of these domains\n\n{approved_embed_hosts}."
|
||||
|
||||
if getattr(rule, "children", None):
|
||||
for child in rule.children():
|
||||
clean_block(child)
|
||||
|
||||
return False
|
|
@ -12,6 +12,7 @@ from files.helpers.sanitize import filter_emojis_only
|
|||
from files.helpers.discord import add_role
|
||||
from shutil import copyfile
|
||||
import requests
|
||||
import cssutils
|
||||
|
||||
GUMROAD_TOKEN = environ.get("GUMROAD_TOKEN", "").strip()
|
||||
GUMROAD_ID = environ.get("GUMROAD_ID", "tfcvri").strip()
|
||||
|
@ -641,6 +642,19 @@ def settings_profilecss_get(v):
|
|||
@auth_required
|
||||
def settings_profilecss(v):
|
||||
profilecss = request.values.get("profilecss").strip().replace('\\', '').strip()[:4000]
|
||||
|
||||
parser = cssutils.CSSParser(raiseExceptions=True,fetcher=lambda url: None)
|
||||
|
||||
try: css = parser.parseString(profilecss)
|
||||
except Exception as e: return {"error": str(e)}, 400
|
||||
|
||||
for rule in css:
|
||||
error = sanitize_css(rule)
|
||||
if error: return render_template("settings_profilecss.html", error=error, v=v)
|
||||
|
||||
profilecss = css.cssText.decode('utf-8')
|
||||
|
||||
|
||||
v.profilecss = profilecss
|
||||
g.db.add(v)
|
||||
g.db.commit()
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from files.__main__ import app, limiter, mail
|
||||
from files.helpers.alerts import *
|
||||
from files.helpers.wrappers import *
|
||||
from files.helpers.sanitize import sanitize_css
|
||||
from files.classes import *
|
||||
from .front import frontlist
|
||||
|
||||
|
||||
import cssutils
|
||||
|
||||
@app.post("/exile/post/<pid>")
|
||||
@is_not_permabanned
|
||||
|
@ -336,7 +336,23 @@ def post_sub_css(v, sub):
|
|||
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
||||
sub.css = request.values.get('css', '').strip()
|
||||
css = request.values.get('css', '').strip()
|
||||
|
||||
|
||||
parser = cssutils.CSSParser(raiseExceptions=True,fetcher=lambda url: None)
|
||||
|
||||
try: css = parser.parseString(css)
|
||||
except Exception as e: return {"error": str(e)}, 400
|
||||
|
||||
for rule in css:
|
||||
error = sanitize_css(rule)
|
||||
if error: return render_template('sub/settings.html', v=v, sidebar=sub.sidebar, sub=sub, error=error)
|
||||
|
||||
css = css.cssText.decode('utf-8')
|
||||
|
||||
sub.css = css
|
||||
|
||||
|
||||
g.db.add(sub)
|
||||
|
||||
g.db.commit()
|
||||
|
|
|
@ -4,6 +4,18 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
{% if error %}
|
||||
<div class="alert alert-danger alert-dismissible fade show mb-3 mt-4" role="alert">
|
||||
<i class="fas fa-exclamation-circle my-auto"></i>
|
||||
<span>
|
||||
{{error}}
|
||||
</span>
|
||||
<button class="close" data-bs-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true"><i class="far fa-times"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if msg %}
|
||||
<div class="alert alert-success alert-dismissible fade show my-3" role="alert">
|
||||
<i class="fas fa-check-circle my-auto" aria-hidden="true"></i>
|
||||
|
@ -111,8 +123,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col col-md-8">
|
||||
<div class="settings">
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
beautifulsoup4
|
||||
bleach==4.1.0
|
||||
cssutils
|
||||
Flask
|
||||
Flask-Caching
|
||||
Flask-Compress
|
||||
|
@ -20,9 +21,10 @@ qrcode
|
|||
redis
|
||||
requests
|
||||
SQLAlchemy
|
||||
tldextract
|
||||
psycopg2-binary
|
||||
pusher_push_notifications
|
||||
pyenchant
|
||||
youtube-dl
|
||||
yattag
|
||||
webptools
|
||||
webptools
|
Loading…
Reference in New Issue