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.

Use of Foswiki::Meta

  • 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


  • 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:
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.
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.
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.
Set an optional description for display by the %RESTHANDLERS% macro.

ALERT! 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.

BasicForm edit

TopicClassification DeveloperDocumentation
TopicSummary How to write extensions that don't compromise server or Foswiki security
Topic revision: r8 - 02 Nov 2016, FlorianSchlichting
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy