fsc-cd2025/readme.md
2018-01-02 11:14:34 -08:00

124 lines
4.7 KiB
Markdown

## fsc
This mod is designed to help write more secure formspec handling
code. It achieves this by throwing out the concept of "formspec
names" entirely and giving each formspec shown to the player a unique,
random ID. The player can only then submit form data using this unique
ID, and, the handling code can invalidate the ID during processing
automatically.
This reduces the risk that an attacker can forge formspec data and
send uninvited packets to the server. The server will discard any
form data that appears to come from a client that is attempting to
use old or incorrect fsc-created forms and will note this event in
the minetest log.
Because of the simplicity of the approach, mods will no longer need
to focus on basic formspec handling code and can instead spent their
time verifying the proper permissions and input data correctness.
This mod also provides a much more simple way to maintain a formspec
"context" and pass it along to subsequent formspecs. This makes
writing formspec code simpler as the context does not need to be
maintained outside the formspec handling or creation code, and no
memory leakage needs to be worried about.
A player can also only ever obtain one context, and attempting to
use an invalid or outdated context will result in all current valid
formspec contexts being revoked. Combined together, all these features
make formspecs a lot safer to work with.
## Usage
The basic workflow of `fsc` contains of a single function call. Outside
of this function call, there are no other API functions or data.
```
function fsc.show(name, formspec, context, callback)
-- `name`: a playername,
-- `formspec`: a valid formspec string,
-- `context`: any data, may be `nil`
-- `callback`: function(player, fields, context).
```
The return value of `fsc.show()` is always `nil` - it returns nothing.
The callback function will only be called if basic sanity checks on the data
pass requirements. You can implement it simply as follows:
```
local function callback(player, fields, context)
-- `player`: player object,
-- `fields`: table containing formspec data returned by the player client,
-- `context`: any data, will never be `nil`. If no context was passed
-- to `fsc.show()`, it will contain `{}`
return true
end
```
The return value of the callback may be `nil` or `true`. If you return
`nil`, the context is not invalidated, and the player may submit the
formspec using the same ID again. This is useful if the player merely
selects a list item or otherwise performs an action in the form that
does not cause the form to be closed on the client, and you wish to
keep the form open.
If you return `true`, or if you return `nil` and `fields.quit` is set,
then the fsc code will invalidate the ID and close the formspec. You
should return `true` unless you want to keep the form open to the
player.
Making a simple callback handler that shows a new form is therefore
relatively straightforward. The below example passes the current
context data through to the new form. The old form will close, and
the new form will appear to the player with the new content.
```
local function callback(player, fields, context)
local name = player:get_player_name()
if fields.rename then
fsc.show(name,
"field[new_name;What is the new name?;" .. minetest.formspec_escape(context.old_name) .. "]",
context,
callback)
return
else
-- do something else
return true
end
end
```
In some cases, you may wish to show a form without having the
need for a callback, in case the content is just informational and
non-interactive. In that case, you can omit a callback handler by
just inserting an empty callback handler, as follows:
`fsc.show(name, formspec, {}, function() end)`
## Node Formspecs
Node formspecs are not handled. Due to the nature of node/inventory
formspecs, it is inherently impossible to perform the same checks on
node/inventory formspecs as `fsc` can do for (normal) formspecs.
## License
FormSpec Context ('fsc') mod for minetest, licensed under the `ISC` license:
Copyright (C) 2018 Auke Kok <sofar@foo-projects.org>
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.