Any Script can get called anytime by anyone
In the last days we had a discussion with a client about FileMaker 2024 and the quick open feature. The user may press Command-K (macOS) or Control-K (Windows) and search for things. This includes layouts and scripts and they can go to layouts and run scripts, when you wouldn't expect it.
We love to give everyone a reminder on a little security thing: Any script in FileMaker may get called anywhere by anyone.
When you write a script, you usually make assumptions. The script expects to be in a certain layout on a specific record to do its job. You expect it to be called because a user pressed a specific button or used the custom menu to only call it in a specific situation. But your script can be triggered:
- with the open quickly feature in FileMaker 2024.
- using the script menu, maybe after switching back to standard menus.
- via Apple Script
- via Data API
- via fmp:// URL
- via various plugins
- via another FileMaker file where someone writes a script to perform a script in your file.
- via Siri intents
- via notification response trigger
While you could put in some guard rails using the permissions and denying linking your file to another one, we hardly ever want to restrict calling triggers via fmp URLs or plugin since we use that regularly for integrations like with the WebViewer.
Your script should check for context. For example if you expect to be run in a specific layout, you may check with Get(LayoutName) for the current layout name. But then please also check with Get(FileName) for the file name, since you may have the same layout name in a second file! But what would stop someone from having a second file with same name?
The solution is to pick a specific layout in a database and then have FileMaker go there. If you are on that layout already, nothing will happen. Switching layouts may fail due to a validation in the current record in some table, by missing permissions to enter the layout for the current user or by a layout trigger blocking us. We need to check for errors after each "Go To Layout" and exit in case of an error.
Let's check this sample script. It's for exporting records, but the current user may not have the privilege fmexport allowed. That is a specific extended privilege we created and assigned to a few user groups to allow some specific accounts to do exports, but not the normal users entering data. This check should catch a lot of unintended execution of the script. You may add checks to prevent this to run via Data API or FileMaker Go if you like. This script only runs manually in FileMaker Pro or as a scheduled script on the server.
# Stop user messing around
Allow User Abort [ Off ]
Set Error Capture [ On ]
#
#
# Check if current user has privilege
If [ Position ( Get ( CurrentExtendedPrivileges ) ; "fmexport" ; 1 ; 1 ) > 0 ]
# user got privileges for running export script
Else
Show Custom Dialog [ "No records?" ; "Please find some records first." ]
Exit Script [ Text Result: "not allowed" ]
End If
#
#
# Check for some platforms. Deny for FileMaker Go or WebDirect
If [ Get(SystemPlatform) = 3 ]
Exit Script [ Text Result: "Script not allowed to be run in FileMaker Go" ]
End If
If [ Get(SystemPlatform) = 4 ]
Exit Script [ Text Result: "Script not allowed to be run in Web Direct" ]
End If
If [ Position ( Get(ApplicationVersion) ; "Data API" ; 1 ; 1 ) > 1 ]
Exit Script [ Text Result: "Script not allowed to be run in Data API" ]
End If
#
#
# Move to right layout if needed
Go to Layout [ “Orders” (MySolution) ; Animation: None ]
Set Variable [ $LastError ; Value: Get(LastError) ]
If [ $LastError ≠ 0 ]
# Failed to go to the layout
Exit Script [ Text Result: ]
End If
#
#
# check whether we have records
If [ Get(FoundCount) = 0 ]
Show Custom Dialog [ "No records?" ; "Please find some records first." ]
Exit Script [ Text Result: ]
End If
Once we passed the checks for extended privileges, for the current platform, moved to the layout and even checked if we got records for the export. Now the data export script can do its job and export the data.
What do you think? Should every script get such a 40 line prelude?
Maybe at least some more dangerous scripts that delete data or export data.