Add AllowTextureFromURL option, default false

Adds the `AllowTextureFromURL` config option and makes it false by
default. Admins can still set skins and capes by URL, via the front end
or the API, regardless of this setting. Allowing users to specify
textures via URL is a possible security concern and doesn't really
improve the UX that much, so we should make it opt-in.

For https://github.com/unmojang/drasl/issues/116.
This commit is contained in:
Evan Goode 2024-11-22 14:53:05 -05:00
parent 30d3612409
commit 1b6fdf2341
4 changed files with 38 additions and 26 deletions

View File

@ -20,10 +20,10 @@ repos:
rev: 3.0.0 rev: 3.0.0
hooks: hooks:
- id: alejandra-system - id: alejandra-system
- repo: https://github.com/pre-commit/mirrors-prettier # - repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.3 # rev: v3.0.3
hooks: # hooks:
- id: prettier # - id: prettier
- repo: local - repo: local
hooks: hooks:
- id: swag - id: swag

View File

@ -63,6 +63,7 @@ type Config struct {
AllowChangingPlayerName bool AllowChangingPlayerName bool
AllowMultipleAccessTokens bool AllowMultipleAccessTokens bool
AllowSkins bool AllowSkins bool
AllowTextureFromURL bool
ApplicationOwner string ApplicationOwner string
ApplicationName string ApplicationName string
BaseURL string BaseURL string
@ -108,6 +109,7 @@ func DefaultConfig() Config {
AllowCapes: true, AllowCapes: true,
AllowChangingPlayerName: true, AllowChangingPlayerName: true,
AllowSkins: true, AllowSkins: true,
AllowTextureFromURL: false,
ApplicationName: "Drasl", ApplicationName: "Drasl",
ApplicationOwner: "Anonymous", ApplicationOwner: "Anonymous",
BaseURL: "", BaseURL: "",

View File

@ -449,6 +449,9 @@ func (app *App) UpdateUser(
} }
if skinURL != nil { if skinURL != nil {
if !app.Config.AllowTextureFromURL && !callerIsAdmin {
return User{}, NewBadRequestUserError("Setting a skin from a URL is not allowed.")
}
res, err := MakeHTTPClient().Get(*skinURL) res, err := MakeHTTPClient().Get(*skinURL)
if err != nil { if err != nil {
return User{}, NewBadRequestUserError("Couldn't download skin from that URL: %s", err) return User{}, NewBadRequestUserError("Couldn't download skin from that URL: %s", err)
@ -481,6 +484,9 @@ func (app *App) UpdateUser(
return User{}, NewBadRequestUserError("Can't specify both a cape file and a cape URL.") return User{}, NewBadRequestUserError("Can't specify both a cape file and a cape URL.")
} }
if capeURL != nil { if capeURL != nil {
if !app.Config.AllowTextureFromURL && !callerIsAdmin {
return User{}, NewBadRequestUserError("Setting a cape from a URL is not allowed.")
}
res, err := MakeHTTPClient().Get(*capeURL) res, err := MakeHTTPClient().Get(*capeURL)
if err != nil { if err != nil {
return User{}, NewBadRequestUserError("Couldn't download cape from that URL: %s", err) return User{}, NewBadRequestUserError("Couldn't download cape from that URL: %s", err)

View File

@ -352,19 +352,21 @@
{{ if or .App.Config.AllowSkins .User.IsAdmin }} {{ if or .App.Config.AllowSkins .User.IsAdmin }}
<h4>Skin</h4> <h4>Skin</h4>
<p> <p>
<label for="skin-url">URL to skin file</label><br /> <label for="skin-file">Upload a skin</label><br />
<input
type="text"
name="skinUrl"
id="skin-url"
class="long"
placeholder="Leave blank to keep"
/>
</p>
<p>
<label for="skin-file">or instead, upload a skin</label><br />
<input type="file" name="skinFile" id="skin-file" /> <input type="file" name="skinFile" id="skin-file" />
</p> </p>
{{ if or .App.Config.AllowTextureFromURL .User.IsAdmin }}
<p>
<label for="skin-url">or instead, provide a URL to a skin</label><br />
<input
type="text"
name="skinUrl"
id="skin-url"
class="long"
placeholder="Leave blank to keep"
/>
</p>
{{ end }}
<p> <p>
<label for="delete-skin" <label for="delete-skin"
>or instead, check the box to delete your current skin >or instead, check the box to delete your current skin
@ -394,19 +396,21 @@
{{ if or .App.Config.AllowCapes .User.IsAdmin }} {{ if or .App.Config.AllowCapes .User.IsAdmin }}
<h4>Cape</h4> <h4>Cape</h4>
<p> <p>
<label for="cape-url">URL to cape file</label><br /> <label for="cape-file">Upload a cape</label><br />
<input
type="text"
name="capeUrl"
id="cape-url"
class="long"
placeholder="Leave blank to keep"
/>
</p>
<p>
<label for="cape-file">or instead, upload a cape</label><br />
<input type="file" name="capeFile" id="cape-file" /> <input type="file" name="capeFile" id="cape-file" />
</p> </p>
{{ if or .App.Config.AllowTextureFromURL .User.IsAdmin }}
<p>
<label for="cape-url">or instead, provide a URL to a cape</label><br />
<input
type="text"
name="capeUrl"
id="cape-url"
class="long"
placeholder="Leave blank to keep"
/>
</p>
{{ end }}
<p> <p>
<label for="delete-cape" <label for="delete-cape"
>or instead, check the box to delete your current cape >or instead, check the box to delete your current cape