Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
slapos
Commits
9f966b19
Commit
9f966b19
authored
Feb 20, 2023
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
theia: make /public/ really public, but prevent JS execution
parent
00ac69e6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
38 additions
and
26 deletions
+38
-26
software/theia/buildout.hash.cfg
software/theia/buildout.hash.cfg
+1
-1
software/theia/instance-theia.cfg.jinja.in
software/theia/instance-theia.cfg.jinja.in
+28
-16
software/theia/test/test.py
software/theia/test/test.py
+9
-9
No files found.
software/theia/buildout.hash.cfg
View file @
9f966b19
...
...
@@ -15,7 +15,7 @@
[instance-theia]
_update_hash_filename_ = instance-theia.cfg.jinja.in
md5sum =
3648844f372a96974582e7281c9987dd
md5sum =
a9d4ace568acdd5002d587816ab91737
[instance]
_update_hash_filename_ = instance.cfg.in
...
...
software/theia/instance-theia.cfg.jinja.in
View file @
9f966b19
...
...
@@ -15,7 +15,6 @@ theia-environment-parts =
theia-parts =
frontend-instance
python-server
promises
parts =
...
...
@@ -123,8 +122,7 @@ config-port = $${frontend-instance:port}
<= monitor-promise-base
promise = check_socket_listening
name = $${:_buildout_section_name_}.py
config-host = $${python-server-port:ip}
config-port = $${python-server-port:port}
config-pathname = $${python-server:socket}
[frontend-authentication-promise]
<= monitor-promise-base
...
...
@@ -262,13 +260,14 @@ content =
log global
bind $${:ip}:$${:port} ssl crt $${frontend-instance-certificate:cert-file} alpn h2,http/1.1
# writing twice the same ACL is doing OR
acl is_public path_beg /public/
acl is_public path /$${frontend-instance-favicon.ico:filename}
acl is_public path /$${frontend-instance-theia.webmanifest:filename}
acl is_public path /$${frontend-instance-theia-serviceworker.js:filename}
acl auth_ok http_auth(basic-auth-list)
# No authentication for
some files
# No authentication for
public folder
http-request auth unless auth_ok || is_public
use_backend static if { path_beg /$${frontend-instance-fonts:folder-name} } || { path_beg /$${frontend-instance-slapos.css:folder-name} } || { path /$${frontend-instance-logo:filename} } ||
{ path_beg /public/ } ||
is_public
use_backend static if { path_beg /$${frontend-instance-fonts:folder-name} } || { path_beg /$${frontend-instance-slapos.css:folder-name} } || { path /$${frontend-instance-logo:filename} } || is_public
default_backend nodejs
backend nodejs
...
...
@@ -277,7 +276,9 @@ content =
backend static
log global
server static_backend $${python-server-port:ip}:$${python-server-port:port}
server static_backend $${python-server:socket}
option forwardfor
http-response set-header Content-Security-Policy "default-src 'self'; img-src 'self' data:; script-src 'none'"
ip = $${frontend-instance-port:ip}
hostname = [$${:ip}]
...
...
@@ -387,17 +388,28 @@ filename = favicon.ico
# Local Python Server
# -------------------
[python-server-port]
recipe = slapos.cookbook:free_port
minimum = 3000
maximum = 3100
ip = {{ ipv4_random }}
[python-server]
recipe = slapos.cookbook:wrapper
wrapper-path = $${directory:services}/$${:_buildout_section_name_}
command-line = $${buildout:executable} -m http.server $${python-server-port:port} --bind $${python-server-port:ip} --directory $${directory:frontend-static}
recipe = slapos.recipe.template
output = $${directory:services}/$${:_buildout_section_name_}
socket = $${directory:run}/$${:_buildout_section_name_}.sock
inline =
#!$${buildout:executable}
import atexit, os, socketserver
from http import server
class Server(socketserver.ThreadingUnixStreamServer):
daemon_threads = True
class Handler(server.SimpleHTTPRequestHandler):
def address_string(self): # insecure but ok for logging
return self.headers.get("X-Forwarded-For", "local")
s = "$${:socket}"
os.chdir("$${directory:frontend-static}")
def cleanup():
try:
os.remove(s)
except FileNotFoundError:
pass
atexit.register(cleanup)()
Server(s, Handler).serve_forever()
# Common Environment
# ------------------
...
...
software/theia/test/test.py
View file @
9f966b19
...
...
@@ -146,16 +146,16 @@ class TestTheia(TheiaTestCase):
)).
geturl
()
self
.
get
(
authenticated_url
)
# there's a public folder to serve file
with
open
(
'{}/srv/frontend-static/public/test_file'
.
format
(
self
.
getPath
()),
'w'
)
as
f
:
# there's a public folder to serve file
(no need for authentication)
with
open
(
self
.
getPath
()
+
'/srv/frontend-static/public/test_file'
,
'w'
)
as
f
:
f
.
write
(
"hello"
)
resp
=
self
.
get
(
urljoin
(
authenticated_url
,
'/public/'
))
self
.
assertIn
(
'test_file'
,
resp
.
text
)
resp
=
self
.
get
(
urljoin
(
authenticated_url
,
'/public/test_file'
)
)
self
.
assertEqual
(
'hello'
,
resp
.
text
)
# make sure public folder is protected
resp
=
self
.
get
(
urljoin
(
url
,
'/public/test_file'
),
requests
.
codes
.
unauthorized
)
def
get
(
path_info
):
resp
=
self
.
get
(
urljoin
(
url
,
path_info
)
)
self
.
assertIn
(
'Content-Security-Policy'
,
resp
.
headers
)
return
resp
.
text
self
.
assertIn
(
'test_file'
,
get
(
'/public/'
))
self
.
assertEqual
(
'hello'
,
get
(
'/public/test_file'
)
)
# there's a (not empty) favicon (no need for authentication)
resp
=
self
.
get
(
urljoin
(
url
,
'/favicon.ico'
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment