Security

Overview

By default, requests that modify existing files or account settings are authenticated, but requests to upload or deliver files are not. Requests are authenticated by checking a policy string that is signed by a shared secret. Applications can be configured on an individual basis so that every request is authenticated. All security settings are configurable in the Developer Portal.

Request Default Authentication
Modifies existing file yes
Modifies account settings yes
Uploads new file no
Delivers file no

Policies and Signatures

Authentication and authorization against our APIs relies on Base64URL-encoded JSON “policies” and HMAC-SHA256 “signatures”. The policy determines which actions are authorized and the signature authenticates the policy. Depending on the API, these values may be required as part of the path, query parameters, or body of a request.

The secret used for signing is automatically generated for each application. The secret should be carefully protected and never exposed client-side. A secure application stack requires backend code that generates and signs short-lived and limited-scope policies for clients. The secret can be regenerated as needed, but this will invalidate existing signatures.

Policy Structure

A policy must contain an “expiry” but can exclude all other values. A minimal policy, containing only an expiry, permits nearly all requests. The “call” value limits the types of requests allowed, and additional values limit request parameters. Getting EXIF data from image files requires explicit permission.

This policy allows any request except one to get EXIF data:

{
  "expiry": 501379200
}

This policy only allows uploading and saving to custom storage:

{
  "expiry": 501379200,
  "call": ["pick", "store"]
}

Policy Keys

A valid policy must contain an “expiry” value set in the future, but can exclude any other values.

Key Value Purpose
expiry Unix timestamp Sets policy expiration
call Array of call names Limits allowed requests, defaults to all
handle ID string Limits file modifications to a single file
container Regex Limits storage containers allowed for uploads
path Regex Limits storage paths allowed for uploads
url Regex Limits source URL’s allowed for transformations
minSize Size in bytes Sets a min size for uploads
maxSize Size in bytes Sets a max size for uploads

Calls

Policies without a “call” array allow every call by default except “exif”. Requests to get EXIF data require the “exif” call explicitly.

Name Allows
pick Uploading
read Reading
remove Deleting
store Saving to custom storage (also need “pick”)
write Overwriting (not new uploads)
convert Converting (and using the document viewer)
exif Getting exif metadata for image files
stat Getting file metadata
runWorkflow Running workflow jobs

Example

The Developer Portal contains a widget to create and sign policies and each of the SDK’s contain helper functionality for the same. The below example shows how to create and use a policy for file delivery.

Create a JSON policy string:

{
  "expiry": 1523595600,
  "call": ["read", "convert"],
  "handle": "bfTNCigRLq0QMOrsFKzb"
}

Base64URL encode the policy string:

ewogICJleHBpcnkiOiAxNTIzNTk1NjAwLAogICJjYWxsIjogWyJyZWFkIiwgImNvbnZlcnQiXSwKICAiaGFuZGxlIjogImJmVE5DaWdSTHEwUU1PcnNGS3piIgp9

Create a HMAC-SHA256 signature of the encoded policy (using ‘mysecret’ as key):

5191e4c6c304c08296eab217ee05236a5bacaab9b581b535d5922a41079b77e0

Using the policy and signature with a download URL:

https://cdn.filestackcontent.com/bfTNCigRLq0QMOrsFKzb?policy=ewogICJleHBpcnkiOiAxNTIzNTk1NjAwLAogICJjYWxsIjogWyJyZWFkIiwgImNvbnZlcnQiXSwKICAiaGFuZGxlIjogImJmVE5DaWdSTHEwUU1PcnNGS3piIgp9&signature=5191e4c6c304c08296eab217ee05236a5bacaab9b581b535d5922a41079b77e0

Using the policy and signature with a resize transformation URL:

https://cdn.filestackcontent.com/resize=width:300/security=policy:ewogICJleHBpcnkiOiAxNTIzNTk1NjAwLAogICJjYWxsIjogWyJyZWFkIiwgImNvbnZlcnQiXSwKICAiaGFuZGxlIjogImJmVE5DaWdSTHEwUU1PcnNGS3piIgp9,signature:5191e4c6c304c08296eab217ee05236a5bacaab9b581b535d5922a41079b77e0/bfTNCigRLq0QMOrsFKzb

Domain Whitelisting

Domain Whitelisting feature allows you to control where your Filestack integrations can be used.

Domain Whitelisting for Upload

Domain whitelisting prevents File Picker from being embedded on unapproved websites. Whitelisting works by blocking requests that don’t contain an approved domain in the “Origin” header. It’s one way of securing your solution and your resources, so others don’t attempt to piggyback on your account. At the same time, it isn’t entirely foolproof on its own. It’s trivial to spoof an “Origin” header outside the browser, however, so while whitelisting prevents another website freeloading off of an API key, it does not protect against attacks generally. To truly protect an account against attacks or abuse, configure it to authenticate every request with security policies.

Domain Whitelisting for Delivery and Transformations

Delivery domains whitelisting provides developers with the ability to provide a list of domains from where their files can be downloaded from. This will limit abusers that either steal API keys or use someone else’s files on their websites. Ideologically it works in the same way as upload whitelisting. Again, this is not the ultimate security measurement to protect API keys. This feature only protects the usage of content on unauthorized websites. Although it is still possible to download files directly (for example with curl or by putting URL directly in the browser). To truly protect your assets, configure security policies.

Format and restrictions

Domains should be passed in a limited glob format.

* - matches any number of characters, but not separators;

? - matches a single character, but not separators;

{ } - allows for a comma-separated list of “or” expressions;

[ ] - specifies a range - if you did: m[a-d]m it can become anything that starts and ends with m and has any character a to d in-between. For example, these would work: mam, mbm, mcm, mdm.

Domains may include port mydomain.com:8080 . In that case, incoming requests also need to have a matching port specified.

Protocol is ignored http:// = https://. If you provided domain with protocol included, it will be automatically removed on save.

We do not accept parentheses ( ) in domain patterns. However, you can still use curly brackets { } in your patterns.

Maximum 20 patterns per whitelist type can be passed. If you need to set more, please contact support or sales.

Examples

PATTERN FIXTURE MATCH
mydomain.com:8080 mydomain.com:8080 ✔ true
mydomain.com:8080 mydomain.com ✘ false
*domain.* mydomain.com ✔ true
*domain.* www.domain.com ✘ false
*.domain.* www.domain.com ✔ true
subdomain.*.com subdomain.domain.com ✔ true
subdomain.*.com subdomain.d1.d2.com ✘ false
mydomain.{com,org} mydomain.com ✔ true
mydomain.{com,org} mydomain.org ✔ true
mydomain.{com,org} mydomain.io ✘ false
[a-n]*domain.com my1domain.com ✔ true
[a-n]*domain.com one1domain.com ✘ false