Guidelines for Writing Secure Extensions
A collection of guidelines on how to write secure extensions to Foswiki.
Organization of scripts, data & code
- Client executed software (Javascript) should not be stored in locations directly writable by the web interface. Consider creating a subdirectory below the Topic directory in pub/System so that Foswiki can't write directly into the location.
Example: Plugin MyJSPlugin accesses javacript files. Store the javascript files in pub/System/MyJSPlugin/scripts/... |
- Server executed software (Perl, PHP, etc.) should never be stored in a web readable/writable location. Server code should be stored in
tools/
or lib/
, never pub/
- Don't assume that controls like
.htaccess
in Foswiki web accessible directories will work on all systems. Not all servers allow override of the server directories.
- Avoid use of relative directory traversal, such as
../../loc/file
Workareas and temporary files
- Use the the Perl function:
File::Temp
or related File::Spec
functions to get temporary files that are not needed beyond the current request.
- Obtain longer life persistent work file storage using the
Foswiki::Func
functions getWorkArea
, readFile
and saveFile
.
- The
$Foswiki::cfg{WorkingDir}/tmp
directory is reserved for session security related files and should not be used as a general work area.
Calling external programs
- Always use
Foswiki::Sandbox
for execution, never call the programs directly.
- Helper scripts should be located in
tools/
, never in bin/
Programs in bin/
can be directly invoked from browser input.
- Sanitize all input. Never trust the content of strings passed from browser input.
Use of Foswiki::Func
- Always interact with Foswiki using the
Foswiki::Func
interface. Never call other Foswiki routines directly
- Carefully read and understand the security implications of the Foswiki::Funccalls.
- For example:
Foswiki::Func::readTopic
states "Read topic text and meta data, regardless of access permissions." Any extension using readTopic
directly to read outside of the current topic must call Foswiki::Func::checkAccessPermissions
before using readTopic
.
- Don't directly access attachments using the file system. Use
Foswiki::Func
routines. Future releases may move to other forms of backend storage. And accessing the file system directly bypasses security checking on the attachments.
- Note that some
Foswiki::Func
calls can expose information that the current users would not be entitled. For example, e-mail address or particular group membership. These functions have to exist so that utilities like MailerContrib can function. When presenting information to the user, be sure to understand whether or not the Foswiki::Func
calls you are using enforce access rules.
- Most topic and attachment interaction can be done with
Foswiki::Meta
as well as Foswiki::Func
-
Foswiki::Meta
does not check access rules. Most Foswiki::Func
calls check access permission.
- If your plugin is reading or writing topic data using
Foswiki::Meta
be sure to verify permission first with Foswiki::Meta::haveAccess
HTTP POST
versus GET
- Always use
POST
to send changes to Foswiki scripts. GET
should only ever be used to retrieve data, never to write it.
- When writing REST handlers that write to the database, reject requests that use any method other than
POST
.
Plugin Configuration
- Any extension parameters that control access outside of the Foswiki environment should be limited to the
bin/configure
maintained LocalSite.cfg
. Never code external program paths, file storage paths, etc. in Foswiki macros or in URL parameters.
- Don't use configuration settings in Plugin topics. Use global preferences instead. Global preferences can be finalised if you want to prevent them being changed. Use of plugin preferences can result in accidental overwriting when the plugin is upgraded, potentially compromising security.
REST Handlers
REST handlers can be registered by plugins, typically for specialized functions, such as implementing JSON interaction with Foswiki. REST handlers are called by the
rest
script and frequently need special handling. In Foswiki 1.1, the
rest
script is in the
{AuthScripts}
list meaning that Foswiki will not allow access from non-authenticated users.
The best practice is to explicitly set the REST handler security requirements in the call to
registerRESTHandler
. This makes the handler immune to the upcoming changes in the defaults planned in Foswiki 1.2. The three options available are:
-
authenticate
- Specify if Foswiki core should require an authenticated session before allowing access to the rest handler. Default in Foswiki 1.1.x is false, but
rest
is in the {AuthScripts}
list. Disable this if you want the WikiGuest to access this handler.
-
validate
- Specify if Foswiki core should validate a Strikeone key to prevent cross-site request forgery. Defaults to false in 1.1.x, will default to true in 1.2.
-
http_allow
- Specifies the list of valid HTTP methods allowed for this handler. 1.1 default is
'POST'
, only when authenticate
is true. Foswiki 1.2 will default to POST
. If the handler does make any updates, then setting this to 'POST,GET'
is safe. Updates should always be restricted to POST
requests.
-
description
- Set an optional description for display by the %RESTHANDLERS% macro.
With Foswiki 1.2, rest
will be removed from {AuthScripts}
and instead security will be determined on a handler by handler basis. The per-handler default will change from the Foswiki 1.1 defaults. This may require plugin changes for Foswiki 1.2, however these changes may be made today by explicitly setting these values
Other Perl considerations
- Always validate input from the user (e.g. in files or from the browser) before using it in any eval clauses.