diff options
-rw-r--r-- | config/config.exs | 7 | ||||
-rw-r--r-- | installation/caddyfile-pleroma.example | 1 | ||||
-rw-r--r-- | installation/pleroma-apache.conf | 60 | ||||
-rw-r--r-- | installation/pleroma.nginx | 16 | ||||
-rw-r--r-- | installation/pleroma.vcl | 10 | ||||
-rw-r--r-- | lib/pleroma/uploaders/local.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/endpoint.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/account_view.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/oauth/oauth_controller.ex | 16 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 3 | ||||
-rw-r--r-- | test/web/mastodon_api/account_view_test.exs | 8 |
12 files changed, 110 insertions, 33 deletions
diff --git a/config/config.exs b/config/config.exs index b29300c3c..d88a56adf 100644 --- a/config/config.exs +++ b/config/config.exs @@ -14,7 +14,9 @@ config :pleroma, Pleroma.Upload, uploader: Pleroma.Uploaders.Local, strip_exif: false -config :pleroma, Pleroma.Uploaders.Local, uploads: "uploads" +config :pleroma, Pleroma.Uploaders.Local, + uploads: "uploads", + uploads_url: "{{base_url}}/media/{{file}}" config :pleroma, Pleroma.Uploaders.S3, bucket: nil, @@ -30,7 +32,8 @@ config :pleroma, Pleroma.Web.Endpoint, protocol: "https", secret_key_base: "aK4Abxf29xU9TTDKre9coZPUgevcVCFQJe/5xP/7Lt4BEif6idBIbjupVbOrbKxl", render_errors: [view: Pleroma.Web.ErrorView, accepts: ~w(json)], - pubsub: [name: Pleroma.PubSub, adapter: Phoenix.PubSub.PG2] + pubsub: [name: Pleroma.PubSub, adapter: Phoenix.PubSub.PG2], + secure_cookie_flag: true # Configures Elixir's Logger config :logger, :console, diff --git a/installation/caddyfile-pleroma.example b/installation/caddyfile-pleroma.example index ed24fc16c..2c1efde2d 100644 --- a/installation/caddyfile-pleroma.example +++ b/installation/caddyfile-pleroma.example @@ -22,6 +22,7 @@ social.domain.tld { Referrer-Policy "same-origin" Strict-Transport-Security "max-age=31536000; includeSubDomains;" Expect-CT "enforce, max-age=2592000" + Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://social.domain.tld; upgrade-insecure-requests;" } # If you do not want remote frontends to be able to access your Pleroma backend server, remove these lines. diff --git a/installation/pleroma-apache.conf b/installation/pleroma-apache.conf index bb6d32587..992c0c900 100644 --- a/installation/pleroma-apache.conf +++ b/installation/pleroma-apache.conf @@ -1,26 +1,56 @@ +#Example configuration for when Apache httpd and Pleroma are on the same host. +#Needed modules: headers proxy proxy_http proxy_wstunnel rewrite ssl +#This assumes a Debian style Apache config. Put this in /etc/apache2/sites-available +#Install your TLS certificate, possibly using Let's Encrypt. +#Replace 'pleroma.example.com' with your instance's domain wherever it appears + +ServerName pleroma.example.com +ServerTokens Prod + +ErrorLog ${APACHE_LOG_DIR}/error.log +CustomLog ${APACHE_LOG_DIR}/access.log combined + <VirtualHost *:80> - #Example configuration for when Apache httpd and Pleroma are on the same host. - #Needed modules: proxy proxy_http proxy_wstunnel rewrite - #This assumes a Debian style Apache config. Put this in /etc/apache2/sites-available - #Doesn't include SSL, just run certbot and let it take care of that. - - - #Change this: - ServerName pleroma.example.com - + Redirect permanent / https://pleroma.example.com +</VirtualHost> + +<VirtualHost *:443> + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/pleroma.example.com/cert.pem + SSLCertificateKeyFile /etc/letsencrypt/live/pleroma.example.com/privkey.pem + SSLCertificateChainFile /etc/letsencrypt/live/pleroma.example.com/fullchain.pem + + # Mozilla modern configuration, tweak to your needs + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + SSLCompression off + SSLSessionTickets off + + Header always set X-Xss-Protection "1; mode=block" + Header always set X-Frame-Options "DENY" + Header always set X-Content-Type-Options "nosniff" + Header always set Referrer-Policy same-origin + Header always set Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://pleroma.example.tld; upgrade-insecure-requests;" + + # Uncomment this only after you get HTTPS working. + # Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" + RewriteEngine On RewriteCond %{HTTP:Connection} Upgrade [NC] RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteRule /(.*) ws://localhost:4000/$1 [P,L] - + ProxyRequests off ProxyPass / http://localhost:4000/ ProxyPassReverse / http://localhost:4000/ - - #Change this too: + RequestHeader set Host "pleroma.example.com" ProxyPreserveHost On - - ErrorLog ${APACHE_LOG_DIR}/error.log - CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> + +# OCSP Stapling, only in httpd 2.3.3 and later +SSLUseStapling on +SSLStaplingResponderTimeout 5 +SSLStaplingReturnResponderErrors off +SSLStaplingCache shmcb:/var/run/ocsp(128000)
\ No newline at end of file diff --git a/installation/pleroma.nginx b/installation/pleroma.nginx index a333d116c..37871ea5b 100644 --- a/installation/pleroma.nginx +++ b/installation/pleroma.nginx @@ -71,16 +71,16 @@ server { } # stop removing lines here. - add_header X-XSS-Protection "1; mode=block"; - add_header X-Permitted-Cross-Domain-Policies none; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Referrer-Policy same-origin; - add_header X-Download-Options noopen; - add_header Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://example.tld; upgrade-insecure-requests;"; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Frame-Options "DENY" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "same-origin" always; + add_header X-Download-Options "noopen" always; + add_header Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://example.tld; upgrade-insecure-requests;" always; # Uncomment this only after you get HTTPS working. - # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; + # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; diff --git a/installation/pleroma.vcl b/installation/pleroma.vcl index 63c1cb74d..74490be2a 100644 --- a/installation/pleroma.vcl +++ b/installation/pleroma.vcl @@ -119,3 +119,13 @@ sub vcl_pipe { set bereq.http.connection = req.http.connection; } } + +sub vcl_deliver { + set resp.http.X-Frame-Options = "DENY"; + set resp.http.X-XSS-Protection = "1; mode=block"; + set resp.http.X-Content-Type-Options = "nosniff"; + set resp.http.Referrer-Policy = "same-origin"; + set resp.http.Content-Security-Policy = "default-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://" + req.http.host + "; upgrade-insecure-requests;"; + # Uncomment this only after you get HTTPS working. + # set resp.http.Strict-Transport-Security= "max-age=31536000; includeSubDomains"; +} diff --git a/lib/pleroma/uploaders/local.ex b/lib/pleroma/uploaders/local.ex index d4624661f..d96481c8d 100644 --- a/lib/pleroma/uploaders/local.ex +++ b/lib/pleroma/uploaders/local.ex @@ -42,6 +42,10 @@ defmodule Pleroma.Uploaders.Local do end defp url_for(file) do - "#{Web.base_url()}/media/#{file}" + settings = Application.get_env(:pleroma, Pleroma.Uploaders.Local) + + Keyword.get(settings, :uploads_url) + |> String.replace("{{file}}", file) + |> String.replace("{{base_url}}", Web.base_url()) end end diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index 1e5ac2721..955bd61f3 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -49,7 +49,11 @@ defmodule Pleroma.Web.Endpoint do Plug.Session, store: :cookie, key: "_pleroma_key", - signing_salt: "CqaoopA2" + signing_salt: "CqaoopA2", + http_only: true, + secure: + Application.get_env(:pleroma, Pleroma.Web.Endpoint) |> Keyword.get(:secure_cookie_flag), + extra: "SameSite=Strict" ) plug(Pleroma.Web.Router) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 49a8655f0..f2fcc76ad 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -1188,4 +1188,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do json(conn, []) end end + + def filters(conn, _) do + json(conn, []) + end end diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 85aac493f..7915933be 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -54,7 +54,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do source: %{ note: "", privacy: user_info.default_scope, - sensitive: "false" + sensitive: false } } end @@ -75,8 +75,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do followed_by: User.following?(target, user), blocking: User.blocks?(user, target), muting: false, + muting_notifications: false, requested: false, - domain_blocking: false + domain_blocking: false, + showing_reblogs: false } end diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index a5fb32a4e..160cedd8e 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -60,11 +60,13 @@ defmodule Pleroma.Web.OAuth.OAuthController do fixed_token = fix_padding(params["code"]), %Authorization{} = auth <- Repo.get_by(Authorization, token: fixed_token, app_id: app.id), - {:ok, token} <- Token.exchange_token(app, auth) do + {:ok, token} <- Token.exchange_token(app, auth), + {:ok, inserted_at} <- DateTime.from_naive(token.inserted_at, "Etc/UTC") do response = %{ token_type: "Bearer", access_token: token.token, refresh_token: token.refresh_token, + created_at: DateTime.to_unix(inserted_at), expires_in: 60 * 10, scope: "read write follow" } @@ -116,6 +118,18 @@ defmodule Pleroma.Web.OAuth.OAuthController do token_exchange(conn, params) end + def token_revoke(conn, %{"token" => token} = params) do + with %App{} = app <- get_app_from_request(conn, params), + %Token{} = token <- Repo.get_by(Token, token: token, app_id: app.id), + {:ok, %Token{}} <- Repo.delete(token) do + json(conn, %{}) + else + _error -> + # RFC 7009: invalid tokens [in the request] do not cause an error response + json(conn, %{}) + end + end + defp fix_padding(token) do token |> Base.url_decode64!(padding: false) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index f3604d465..856679899 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -103,6 +103,7 @@ defmodule Pleroma.Web.Router do get("/authorize", OAuthController, :authorize) post("/authorize", OAuthController, :create_authorization) post("/token", OAuthController, :token_exchange) + post("/revoke", OAuthController, :token_revoke) end scope "/api/v1", Pleroma.Web.MastodonAPI do @@ -171,6 +172,8 @@ defmodule Pleroma.Web.Router do delete("/filters/:id", MastodonAPIController, :delete_filter) get("/suggestions", MastodonAPIController, :suggestions) + + get("/filters", MastodonAPIController, :filters) end scope "/api/web", Pleroma.Web.MastodonAPI do diff --git a/test/web/mastodon_api/account_view_test.exs b/test/web/mastodon_api/account_view_test.exs index 5393732eb..e1e07fbcd 100644 --- a/test/web/mastodon_api/account_view_test.exs +++ b/test/web/mastodon_api/account_view_test.exs @@ -53,7 +53,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do source: %{ note: "", privacy: "public", - sensitive: "false" + sensitive: false } } @@ -90,7 +90,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do source: %{ note: "", privacy: "public", - sensitive: "false" + sensitive: false } } @@ -123,8 +123,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do followed_by: false, blocking: true, muting: false, + muting_notifications: false, requested: false, - domain_blocking: false + domain_blocking: false, + showing_reblogs: false } assert expected == AccountView.render("relationship.json", %{user: user, target: other_user}) |