feat: add iframe proxy for enhanced security
Introduced a proxy mechanism for handling iframes to improve security by preventing direct embedding of external content. External iframe URLs are now encoded and passed through a proxy endpoint, which renders a new template warning users about potential security risks. Additionally, added button styles to CSS for consistent user experience and created an iframe security notice template.
This commit is contained in:
parent
e96a39448a
commit
2afc069724
4 changed files with 35 additions and 2 deletions
|
@ -4,6 +4,7 @@ from flask import url_for
|
||||||
|
|
||||||
from small.models.nodes import Page, Paragraph, Text, Image, IFrame, GithubGist
|
from small.models.nodes import Page, Paragraph, Text, Image, IFrame, GithubGist
|
||||||
|
|
||||||
|
from urllib.parse import quote
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,9 +75,12 @@ class MediumClient:
|
||||||
gist_id = iframe["href"].split("/")[-1]
|
gist_id = iframe["href"].split("/")[-1]
|
||||||
children = [GithubGist(id=gist_id)]
|
children = [GithubGist(id=gist_id)]
|
||||||
else:
|
else:
|
||||||
|
src = quote(iframe["iframeSrc"] or iframe["href"], safe="")
|
||||||
|
url = url_for("proxy.iframe") + f"?url={src}"
|
||||||
|
|
||||||
children = [
|
children = [
|
||||||
IFrame(
|
IFrame(
|
||||||
src=iframe["iframeSrc"] or iframe["href"],
|
src=url,
|
||||||
width=iframe["iframeWidth"],
|
width=iframe["iframeWidth"],
|
||||||
height=iframe["iframeHeight"],
|
height=iframe["iframeHeight"],
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,6 +18,24 @@ a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a .btn {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #1a73e8;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a .btn:hover {
|
||||||
|
background-color: #0d6efd;
|
||||||
|
}
|
||||||
|
|
||||||
|
a .btn:active {
|
||||||
|
background-color: #0b5ed7;
|
||||||
|
}
|
||||||
|
|
||||||
/* Header Styles */
|
/* Header Styles */
|
||||||
header {
|
header {
|
||||||
border-bottom: 1px solid #e0e0e0;
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
|
6
src/small/templates/iframe.html
Normal file
6
src/small/templates/iframe.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<div class="error-container">
|
||||||
|
<h1>iframe blocked</h1>
|
||||||
|
<p>The article you are viewing has embedded external content from <code>{{ url }}</code>.</p>
|
||||||
|
<p>For security reasons, this content is blocked by default. You can view the content by clicking the button below.</p>
|
||||||
|
<a href="{{ url }}" class="btn">View content</a>
|
||||||
|
</div>
|
|
@ -1,4 +1,4 @@
|
||||||
from flask import Blueprint, abort
|
from flask import Blueprint, abort, render_template, request
|
||||||
|
|
||||||
from requests import get
|
from requests import get
|
||||||
|
|
||||||
|
@ -13,3 +13,8 @@ def image(original_width, id):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error fetching image: {str(e)}")
|
print(f"Error fetching image: {str(e)}")
|
||||||
abort(500)
|
abort(500)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/iframe/")
|
||||||
|
def iframe():
|
||||||
|
return render_template("iframe.html", url=request.args.get("url"))
|
||||||
|
|
Loading…
Reference in a new issue