Drop media base_url default and recommend different domain
Same-domain setups enabled now at least two exploits, so they ought to be discouraged and definitely not be the default.
This commit is contained in:
parent
bdefbb8fd9
commit
fef773ca35
7 changed files with 41 additions and 4 deletions
|
@ -9,6 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
- `Pleroma.Upload, :base_url` now MUST be configured explicitly;
|
||||||
|
use of the same domain as the instance is **strongly** discouraged
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
- Critical security issue allowing Akkoma to be used as a vector for
|
- Critical security issue allowing Akkoma to be used as a vector for
|
||||||
|
|
|
@ -598,7 +598,8 @@ the source code is here: [kocaptcha](https://github.com/koto-bank/kocaptcha). Th
|
||||||
* `uploader`: Which one of the [uploaders](#uploaders) to use.
|
* `uploader`: Which one of the [uploaders](#uploaders) to use.
|
||||||
* `filters`: List of [upload filters](#upload-filters) to use.
|
* `filters`: List of [upload filters](#upload-filters) to use.
|
||||||
* `link_name`: When enabled Akkoma will add a `name` parameter to the url of the upload, for example `https://instance.tld/media/corndog.png?name=corndog.png`. This is needed to provide the correct filename in Content-Disposition headers when using filters like `Pleroma.Upload.Filter.Dedupe`
|
* `link_name`: When enabled Akkoma will add a `name` parameter to the url of the upload, for example `https://instance.tld/media/corndog.png?name=corndog.png`. This is needed to provide the correct filename in Content-Disposition headers when using filters like `Pleroma.Upload.Filter.Dedupe`
|
||||||
* `base_url`: The base URL to access a user-uploaded file. Useful when you want to host the media files via another domain or are using a 3rd party S3 provider.
|
* `base_url`: The base URL to access a user-uploaded file; MUST be configured explicitly.
|
||||||
|
Using a (sub)domain distinct from the instance endpoint is **strongly** recommended.
|
||||||
* `proxy_remote`: If you're using a remote uploader, Akkoma will proxy media requests instead of redirecting to it.
|
* `proxy_remote`: If you're using a remote uploader, Akkoma will proxy media requests instead of redirecting to it.
|
||||||
* `proxy_opts`: Proxy options, see `Pleroma.ReverseProxy` documentation.
|
* `proxy_opts`: Proxy options, see `Pleroma.ReverseProxy` documentation.
|
||||||
* `filename_display_max_length`: Set max length of a filename to display. 0 = no limit. Default: 30.
|
* `filename_display_max_length`: Set max length of a filename to display. 0 = no limit. Default: 30.
|
||||||
|
|
|
@ -17,6 +17,16 @@ This sets the Akkoma application server to only listen to the localhost interfac
|
||||||
|
|
||||||
This sets the `secure` flag on Akkoma’s session cookie. This makes sure, that the cookie is only accepted over encrypted HTTPs connections. This implicitly renames the cookie from `pleroma_key` to `__Host-pleroma-key` which enforces some restrictions. (see [cookie prefixes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Cookie_prefixes))
|
This sets the `secure` flag on Akkoma’s session cookie. This makes sure, that the cookie is only accepted over encrypted HTTPs connections. This implicitly renames the cookie from `pleroma_key` to `__Host-pleroma-key` which enforces some restrictions. (see [cookie prefixes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Cookie_prefixes))
|
||||||
|
|
||||||
|
### `Pleroma.Upload, :uploader, :base_url`
|
||||||
|
|
||||||
|
> Recommended value: *anything on a different domain than the instance endpoint; e.g. https://media.myinstance.net/*
|
||||||
|
|
||||||
|
Uploads are user controlled and (unless you’re running a true single-user
|
||||||
|
instance) should therefore not be considered trusted. But the domain is used
|
||||||
|
as a pivilege boundary e.g. by HTTP content security policy and ActivityPub.
|
||||||
|
Having uploads on the same domain enabled several past vulnerabilities
|
||||||
|
able to be exploited by malicious users.
|
||||||
|
|
||||||
### `:http_security`
|
### `:http_security`
|
||||||
|
|
||||||
> Recommended value: `true`
|
> Recommended value: `true`
|
||||||
|
|
|
@ -20,6 +20,7 @@ def run(["gen" | rest]) do
|
||||||
output: :string,
|
output: :string,
|
||||||
output_psql: :string,
|
output_psql: :string,
|
||||||
domain: :string,
|
domain: :string,
|
||||||
|
media_url: :string,
|
||||||
instance_name: :string,
|
instance_name: :string,
|
||||||
admin_email: :string,
|
admin_email: :string,
|
||||||
notify_email: :string,
|
notify_email: :string,
|
||||||
|
@ -64,6 +65,14 @@ def run(["gen" | rest]) do
|
||||||
":"
|
":"
|
||||||
) ++ [443]
|
) ++ [443]
|
||||||
|
|
||||||
|
media_url =
|
||||||
|
get_option(
|
||||||
|
options,
|
||||||
|
:media_url,
|
||||||
|
"What base url will uploads use? (e.g https://media.example.com/media)\n" <>
|
||||||
|
" Generally this should NOT use the same domain as the instance "
|
||||||
|
)
|
||||||
|
|
||||||
name =
|
name =
|
||||||
get_option(
|
get_option(
|
||||||
options,
|
options,
|
||||||
|
@ -207,6 +216,7 @@ def run(["gen" | rest]) do
|
||||||
EEx.eval_file(
|
EEx.eval_file(
|
||||||
template_dir <> "/sample_config.eex",
|
template_dir <> "/sample_config.eex",
|
||||||
domain: domain,
|
domain: domain,
|
||||||
|
media_url: media_url,
|
||||||
port: port,
|
port: port,
|
||||||
email: email,
|
email: email,
|
||||||
notify_email: notify_email,
|
notify_email: notify_email,
|
||||||
|
|
|
@ -39,6 +39,8 @@ defmodule Pleroma.Upload do
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
@mix_env Mix.env()
|
||||||
|
|
||||||
@type source ::
|
@type source ::
|
||||||
Plug.Upload.t()
|
Plug.Upload.t()
|
||||||
| (data_uri_string :: String.t())
|
| (data_uri_string :: String.t())
|
||||||
|
@ -228,6 +230,13 @@ defp url_from_spec(%__MODULE__{name: name}, base_url, {:file, path}) do
|
||||||
|
|
||||||
defp url_from_spec(_upload, _base_url, {:url, url}), do: url
|
defp url_from_spec(_upload, _base_url, {:url, url}), do: url
|
||||||
|
|
||||||
|
if @mix_env == :test do
|
||||||
|
defp choose_base_url(prim, sec \\ nil),
|
||||||
|
do: prim || sec || Pleroma.Web.Endpoint.url() <> "/media/"
|
||||||
|
else
|
||||||
|
defp choose_base_url(prim, sec \\ nil), do: prim || sec
|
||||||
|
end
|
||||||
|
|
||||||
def base_url do
|
def base_url do
|
||||||
uploader = Config.get([Pleroma.Upload, :uploader])
|
uploader = Config.get([Pleroma.Upload, :uploader])
|
||||||
upload_base_url = Config.get([Pleroma.Upload, :base_url])
|
upload_base_url = Config.get([Pleroma.Upload, :base_url])
|
||||||
|
@ -235,7 +244,7 @@ def base_url do
|
||||||
|
|
||||||
case uploader do
|
case uploader do
|
||||||
Pleroma.Uploaders.Local ->
|
Pleroma.Uploaders.Local ->
|
||||||
upload_base_url || Pleroma.Web.Endpoint.url() <> "/media/"
|
choose_base_url(upload_base_url)
|
||||||
|
|
||||||
Pleroma.Uploaders.S3 ->
|
Pleroma.Uploaders.S3 ->
|
||||||
bucket = Config.get([Pleroma.Uploaders.S3, :bucket])
|
bucket = Config.get([Pleroma.Uploaders.S3, :bucket])
|
||||||
|
@ -261,7 +270,7 @@ def base_url do
|
||||||
end
|
end
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
public_endpoint || upload_base_url || Pleroma.Web.Endpoint.url() <> "/media/"
|
choose_base_url(public_endpoint, upload_base_url)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -78,6 +78,8 @@ config :joken, default_signer: "<%= jwt_secret %>"
|
||||||
|
|
||||||
config :pleroma, configurable_from_database: <%= db_configurable? %>
|
config :pleroma, configurable_from_database: <%= db_configurable? %>
|
||||||
|
|
||||||
|
config :pleroma, Pleroma.Upload,
|
||||||
<%= if Kernel.length(upload_filters) > 0 do
|
<%= if Kernel.length(upload_filters) > 0 do
|
||||||
"config :pleroma, Pleroma.Upload, filters: #{inspect(upload_filters)}"
|
" filters: #{inspect(upload_filters)},"
|
||||||
end %>
|
end %>
|
||||||
|
base_url: "<%= media_url %>"
|
||||||
|
|
|
@ -39,6 +39,8 @@ test "running gen" do
|
||||||
tmp_path() <> "setup.psql",
|
tmp_path() <> "setup.psql",
|
||||||
"--domain",
|
"--domain",
|
||||||
"test.pleroma.social",
|
"test.pleroma.social",
|
||||||
|
"--media-url",
|
||||||
|
"https://media.pleroma.social/media",
|
||||||
"--instance-name",
|
"--instance-name",
|
||||||
"Pleroma",
|
"Pleroma",
|
||||||
"--admin-email",
|
"--admin-email",
|
||||||
|
@ -92,6 +94,7 @@ test "running gen" do
|
||||||
assert generated_config =~ "configurable_from_database: true"
|
assert generated_config =~ "configurable_from_database: true"
|
||||||
assert generated_config =~ "http: [ip: {127, 0, 0, 1}, port: 4000]"
|
assert generated_config =~ "http: [ip: {127, 0, 0, 1}, port: 4000]"
|
||||||
assert generated_config =~ "filters: [Pleroma.Upload.Filter.Exiftool]"
|
assert generated_config =~ "filters: [Pleroma.Upload.Filter.Exiftool]"
|
||||||
|
assert generated_config =~ "base_url: \"https://media.pleroma.social/media\""
|
||||||
assert File.read!(tmp_path() <> "setup.psql") == generated_setup_psql()
|
assert File.read!(tmp_path() <> "setup.psql") == generated_setup_psql()
|
||||||
assert File.exists?(Path.expand("./test/instance/static/robots.txt"))
|
assert File.exists?(Path.expand("./test/instance/static/robots.txt"))
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue