Redis Policies

These methods exist on the policy.redis object as seen in the following example:

const REDIS = 'redis://redis-01.example.org:6379/1';
(policy) => {
  policy.redis.allowConnect(REDIS)
  policy.redis.allowCommand(REDIS, 'BGSAVE');
  policy.redis.allowCommandKeys(REDIS, 'GET', 'user-session-*');
}

intrinsic.virtualizeLib('redis')

Note that to enable Redis we need to first call .virtualizeLib('redis'):

// Intrinsic for Lambda
module.exports = new IntrinsicLambda()
  .virtualizeLib('redis')
  // ...
  .run();

// Intrinsic for Node.js
intrinsic(__filename)
  .virtualizeLib('redis')
  // ...
  .run();

Calling this method allows your application to load the redis module and enable policies for it. Otherwise, the connection would be treated as an ordinary TCP connection without any inspection of the data being sent.

NOTE: At this time Intrinsic only supports the redis module. If you rely on an alternative module, such as ioredis, please contact us and we will add support.

You will need to call this if you either see the following error, or if you otherwise want to enable Redis connections to be established from your Node.js application:

POLICY_VIOLATION sb: "/-[[GET]]" | tcp://redis-01.example.org:6379 not in outbound net whitelist

policy.redis.disableDefaults()

By default, your application is allowed to execute the following Redis commands:

  • AUTH: Authenticates the connection
  • INFO server: The redis module automatically calls at startup
  • SELECT: Select a database
  • PING: Keepalive purposes
  • QUIT: Gracefully disconnect
  • MULTI: Atomic method chaining

If you would like to disable those operations and manually build a more restrictive list you can do so by calling disableDefaults().

policy.redis.allowConnect(conn)

The allowConnect() method allows your application to make a connection to a Redis instance as described by the conn string. This string needs to contain the hostname and a database, as well as a port if it differs from the default 6379 value. If you use a database other than the default 0, provide it as the URL path.

const connection = 'redis://redis-01.example.org:6379/1';
// ...
(policy) => {
  policy.redis.allowConnect(connection);
}

Chances are your application will establish a connection when it first runs, not when an incoming request is made. For this reason it is usually most common to call the allowConnect() method from within the allRoutes policy.

This policy is required if you see the following violation:

RedisConnectionPolicyViolation: POLICY_VIOLATION sb: "fallback"
  | connection "redis://r.example.com:6379/0" not in Redis connection whitelist

policy.redis.allowCommandKeys(conn, cmd, key)

The allowCommandKeys() method allows your application to run a Redis command, but only with the specified key pattern. The first conn argument is the connection string. The second cmd argument is the name of the Redis command to execute. This can be a single-word command, such as KEYS, or a multiple-word command, such as MEMORY USAGE. The third argument, key, is a glob pattern for matching keys. It can be an exact string, like homepage-cache, or more complex, like user-session-*.

This policy is required if you see the following violation:

RedisCommandPolicyViolation: POLICY_VIOLATION sb: "fallback"
  | command "LOLWUT" with keys "key1, key2" via connection
  "redis://r.example.com:6379/0" not in Redis command whitelist

policy.redis.allowCommand(conn, cmd)

The allowCommand() method allows your application to run a Redis command. The first conn argument is the connection string. The second cmd argument is the name of the Redis command to execute. This can be a single-word command, such as SAVE, or a multiple-word command, such as MEMORY STATS.

NOTE: It is always preferable to use the allowCommandKeys() method over allowCommand() whenever a command is associated with a key. If you were to run allowCommand(REDIS, 'GET'), then a sandbox would be able to get the content of any key, regardless of its name.

This policy is required if you see the following violation:

RedisCommandPolicyViolation: POLICY_VIOLATION sb: "fallback"
  | command "BGSAVE" via connection
  "redis://r.example.com:6379/0" not in Redis command whitelist

policy.redis.allowInfoSection(conn, section)

The allowInfoSection() method allows your application to retrieve data from the various sections in an INFO result. By default your application is only allowed to get information from the server section, as that section is required by the redis module.

NOTE: that if you simply run INFO, any section which isn't whitelisted will be removed from the result. If you provide a section name, such as INFO clients, and have only whitelisted cpu, then you will receive an empty response.

Supported Sections

Here is a list of currently supported Redis INFO sections:

  • server: Enabled, required by redis
  • clients: Disabled, potential for a sidechain attack
  • memory: Disabled, potential for a sidechain attack
  • persistence: Disabled, potential for a sidechain attack
  • stats: Disabled, potential for a sidechain attack
  • replication: Disabled, potential for a sidechain attack
  • cpu: Disabled, potential for a sidechain attack
  • cluster: Disabled
  • keyspace: Disabled, potential for a sidechain attack

Most of them are disabled due to their potential to be used for inter-sandbox communication.

This policy does not have an associated error with it. When running the INFO or INFO sectionName command, any non-whitelisted sections will simply be stripped from the results. This is because the redis module depends on the output.