vlc security: As i've seen very little improvement on that front, i've decided to...
authorDamien Fouilleul <damienf@videolan.org>
Wed, 16 Jan 2008 19:30:12 +0000 (19:30 +0000)
committerDamien Fouilleul <damienf@videolan.org>
Wed, 16 Jan 2008 19:30:12 +0000 (19:30 +0000)
- most vlc options are considered safe, only a handful are particularily unsafe and need be declared as such in their definition (they mostly deal with writing to an output file or URL)
- unsafe options are only considered potentially harmful when used as an input option, ie. the ':option' format. Configuration options are always considered safe 'i.e --option'
- unsafe options are associated with a global security policy, which dictates how these are handled. At the moment, The policy can be either block, allow or prompt, and is set using the '--security-policy' option (which itself is considered unsafe ;)

the policy can be set by the user at the command line or in the preferences, it curently defaults to prompt, which is the desirable state for deskop use. However, it can be overriden depending on context, for example, the activex and mozilla will force the security-policy to block regardless of preference settins.

the code is a bit rough at the moment, but i will optimize/clean it up if the dev community this approach is worth keeping.

try the following example, and you'll see quickly what i mean:

./vlc -vvv <a mrl> :sout=#transcode{vcodec=mp1v,vb=1024,acodec=mpga,ab=192}:standard{mux=ts,dst=vlc-output.ts,access=file}"

Enjoy,
   Damien

14 files changed:
include/vlc_configuration.h
modules/access_filter/record.c
modules/access_filter/timeshift.c
modules/audio_output/file.c
modules/demux/demuxdump.c
modules/demux/ts.c
modules/misc/logger.c
modules/stream_out/es.c
modules/stream_out/rtp.c
modules/stream_out/standard.c
src/config/chain.c
src/libvlc-module.c
src/misc/variables.c
src/modules/entry.c

index 8894b40..9432b32 100644 (file)
@@ -191,7 +191,7 @@ struct module_config_t
     vlc_bool_t   b_autosave;      /* Config will be auto-saved at exit time */
     vlc_bool_t   b_unsaveable;                    /* Config should be saved */
 
-    vlc_bool_t   b_safe;
+    vlc_bool_t   b_unsafe;
 };
 
 /*****************************************************************************
@@ -282,7 +282,7 @@ enum vlc_config_properties
     VLC_CONFIG_OLDNAME,
     /* former option name (args=const char *) */
 
-    VLC_CONFIG_SAFE,
+    VLC_CONFIG_UNSAFE,
     /* tag as modifiable by untrusted input item "sources" (args=none) */
 };
 
@@ -472,8 +472,8 @@ VLC_EXPORT( int, vlc_config_set, (module_config_t *, int, ...) );
 #define change_unsaveable() \
     vlc_config_set (p_config, VLC_CONFIG_VOLATILE)
 
-#define change_safe() \
-    vlc_config_set (p_config, VLC_CONFIG_SAFE)
+#define change_unsafe() \
+    vlc_config_set (p_config, VLC_CONFIG_UNSAFE)
 
 /****************************************************************************
  * config_chain_t:
index 6ae910a..b9585a1 100644 (file)
@@ -57,6 +57,7 @@ vlc_module_begin();
 
     add_directory( "record-path", NULL, NULL,
                    RECORD_PATH_TXT, RECORD_PATH_LONGTXT, VLC_TRUE );
+        change_unsafe();
 
     set_callbacks( Open, Close );
 
index fd141c8..788ca3d 100644 (file)
@@ -65,6 +65,7 @@ vlc_module_begin();
     add_integer( "timeshift-granularity", 50, NULL, GRANULARITY_TEXT,
                  GRANULARITY_LONGTEXT, VLC_TRUE );
     add_directory( "timeshift-dir", 0, 0, DIR_TEXT, DIR_LONGTEXT, VLC_FALSE );
+        change_unsafe();
     add_bool( "timeshift-force", VLC_FALSE, NULL, FORCE_TEXT, FORCE_LONGTEXT,
               VLC_FALSE );
 vlc_module_end();
index 5ac85e3..788671f 100644 (file)
@@ -116,6 +116,7 @@ vlc_module_begin();
                  CHANNELS_TEXT, CHANNELS_LONGTEXT, VLC_TRUE );
     add_file( "audiofile-file", "audiofile.wav", NULL, FILE_TEXT,
               FILE_LONGTEXT, VLC_FALSE );
+        change_unsafe();
     add_bool( "audiofile-wav", 1, NULL, WAV_TEXT, WAV_LONGTEXT, VLC_TRUE );
 
     set_capability( "audio output", 0 );
index 7023ffb..d1a3fc5 100644 (file)
@@ -51,6 +51,7 @@ vlc_module_begin();
     set_capability( "demux2", 0 );
     add_file( "demuxdump-file", "stream-demux.dump", NULL, FILE_TEXT,
               FILE_LONGTEXT, VLC_FALSE );
+        change_unsafe();
     add_bool( "demuxdump-append", 0, NULL, APPEND_TEXT, APPEND_LONGTEXT,
               VLC_FALSE );
     set_callbacks( Open, Close );
index 7c9d52d..817a69f 100644 (file)
@@ -148,6 +148,7 @@ vlc_module_begin();
     add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, VLC_TRUE );
 
     add_file( "ts-dump-file", NULL, NULL, TSDUMP_TEXT, TSDUMP_LONGTEXT, VLC_FALSE );
+        change_unsafe();
     add_bool( "ts-dump-append", 0, NULL, APPEND_TEXT, APPEND_LONGTEXT, VLC_FALSE );
     add_integer( "ts-dump-size", 16384, NULL, DUMPSIZE_TEXT,
                  DUMPSIZE_LONGTEXT, VLC_TRUE );
index 4f50d34..61cb45a 100644 (file)
@@ -135,6 +135,7 @@ vlc_module_begin();
 
     add_file( "logfile", NULL, NULL,
              N_("Log filename"), N_("Specify the log filename."), VLC_FALSE );
+        change_unsafe();
     add_string( "logmode", "text", NULL, LOGMODE_TEXT, LOGMODE_LONGTEXT,
                 VLC_FALSE );
         change_string_list( mode_list, mode_list_text, 0 );
index 33defda..9987947 100644 (file)
@@ -93,10 +93,13 @@ vlc_module_begin();
 
     add_string( SOUT_CFG_PREFIX "dst", "", NULL, DEST_TEXT,
                 DEST_LONGTEXT, VLC_TRUE );
+        change_unsafe();
     add_string( SOUT_CFG_PREFIX "dst-audio", "", NULL, DESTA_TEXT,
                 DESTA_LONGTEXT, VLC_TRUE );
+        change_unsafe();
     add_string( SOUT_CFG_PREFIX "dst-video", "", NULL, DESTV_TEXT,
                 DESTV_LONGTEXT, VLC_TRUE );
+        change_unsafe();
 
     set_callbacks( Open, Close );
 vlc_module_end();
index 7a2f28e..c422897 100644 (file)
@@ -147,6 +147,7 @@ vlc_module_begin();
 
     add_string( SOUT_CFG_PREFIX "dst", "", NULL, DST_TEXT,
                 DST_LONGTEXT, VLC_TRUE );
+        change_unsafe();
     add_string( SOUT_CFG_PREFIX "sdp", "", NULL, SDP_TEXT,
                 SDP_LONGTEXT, VLC_TRUE );
     add_string( SOUT_CFG_PREFIX "mux", "", NULL, MUX_TEXT,
index 2f4f5d7..3f50459 100644 (file)
@@ -95,6 +95,7 @@ vlc_module_begin();
                 MUX_LONGTEXT, VLC_FALSE );
     add_string( SOUT_CFG_PREFIX "dst", "", NULL, DST_TEXT,
                 DST_LONGTEXT, VLC_FALSE );
+        change_unsafe();
 
     add_bool( SOUT_CFG_PREFIX "sap", VLC_FALSE, NULL, SAP_TEXT, SAP_LONGTEXT,
               VLC_TRUE );
index 4d71bd5..53cd9e3 100644 (file)
@@ -30,6 +30,8 @@
 #include <vlc/vlc.h>
 #include "libvlc.h"
 
+#include "vlc_interface.h"
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -314,6 +316,30 @@ void __config_ChainParse( vlc_object_t *p_this, const char *psz_prefix,
                  msg_Warn( p_this, "Option %s is obsolete. Use %s instead.",
                            name, psz_name );
             }
+            if( p_conf->b_unsafe )
+            {
+                int policy = config_GetInt( p_this, "security-policy" );
+                switch( policy )
+                {
+                    case 0: /* block */
+                        msg_Err( p_this, "option %s is unsafe and is blocked by security policy", psz_name );
+                        return;
+                    case 1: /* allow */
+                        break;
+                    case 2: /* prompt */
+                    {
+                        char description[256];
+                        snprintf(description, sizeof(description), _("playlist item is making use of the following unsafe option '%s', which may be harmful if used in a malicious way, authorize it ?"), psz_name);
+                        if( DIALOG_OK_YES != intf_UserYesNo( p_this, _("WARNING: Unsafe Playlist"), description, _("Yes"), _("No"), NULL) )
+                        {
+                            msg_Err( p_this, "option %s is unsafe and is blocked by security policy", psz_name );
+                            return;
+                        }
+                    }
+                    default:
+                        ;
+                }
+            }
         }
         /* </Check if the option is deprecated> */
 
index 0d655a6..156de1d 100644 (file)
@@ -977,6 +977,14 @@ static const char *ppsz_clock_descriptions[] =
 #define MINIMIZE_THREADS_LONGTEXT N_( \
      "This option minimizes the number of threads needed to run VLC.")
 
+#define SECURITY_POLICY_TEXT N_("Policy for handling unsafe options.")
+#define SECURITY_POLICY_LONGTEXT N_( \
+     "This option dictates the default policy when processing options " \
+     "which may be harmful when used in a malicious way.")
+
+static int pi_secpolicy_values[] = { 0, 1, 2 };
+static const char *ppsz_secpolicy_descriptions[] = { N_("Block"), N_("Allow"), N_("Prompt") };
+
 #define PLUGIN_PATH_TEXT N_("Modules search path")
 #define PLUGIN_PATH_LONGTEXT N_( \
     "Additional path for VLC to look for its modules.")
@@ -1481,6 +1489,7 @@ vlc_module_begin();
     set_section( N_("Snapshot") , NULL );
     add_directory( "snapshot-path", NULL, NULL, SNAP_PATH_TEXT,
                    SNAP_PATH_LONGTEXT, VLC_FALSE );
+        change_unsafe();
     add_string( "snapshot-prefix", "vlcsnap-", NULL, SNAP_PREFIX_TEXT,
                    SNAP_PREFIX_LONGTEXT, VLC_FALSE );
     add_string( "snapshot-format", "png", NULL, SNAP_FORMAT_TEXT,
@@ -1786,12 +1795,20 @@ vlc_module_begin();
     add_directory( "plugin-path", NULL, NULL, PLUGIN_PATH_TEXT,
                    PLUGIN_PATH_LONGTEXT, VLC_TRUE );
         change_need_restart();
+        change_unsafe();
 
     set_section( N_("Performance options"), NULL );
     add_bool( "minimize-threads", 0, NULL, MINIMIZE_THREADS_TEXT,
               MINIMIZE_THREADS_LONGTEXT, VLC_TRUE );
         change_need_restart();
 
+    set_section( N_("Security options"), NULL );
+    add_integer( "security-policy", 2, NULL, SECURITY_POLICY_TEXT,
+              SECURITY_POLICY_LONGTEXT, VLC_TRUE );
+        change_integer_list( pi_secpolicy_values, ppsz_secpolicy_descriptions, 0 );
+        change_unsafe();
+        change_need_restart();
+
 #if !defined(__APPLE__) && !defined(SYS_BEOS) && defined(PTHREAD_COND_T_IN_PTHREAD_H)
     add_bool( "rt-priority", VLC_FALSE, NULL, RT_PRIORITY_TEXT,
               RT_PRIORITY_LONGTEXT, VLC_TRUE );
index 2719da6..0a53ab8 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "libvlc.h"
 
+#include "vlc_interface.h"
+
 /*****************************************************************************
  * Private types
  *****************************************************************************/
@@ -1090,6 +1092,35 @@ void __var_OptionParse( vlc_object_t *p_obj, const char *psz_option )
     if( ( i_type != VLC_VAR_BOOL ) &&
         ( !psz_value || !*psz_value ) ) goto cleanup; /* Invalid value */
 
+    /* check if option is unsafe */
+    {
+        module_config_t *p_config = config_FindConfig( p_obj, psz_name );
+        if( p_config->b_unsafe )
+        {
+            int policy = config_GetInt( p_obj, "security-policy" );
+            switch( policy )
+            {
+                case 0: /* block */
+                    msg_Err( p_obj, "option %s is unsafe and is blocked by security policy", psz_name );
+                    return;
+                case 1: /* allow */
+                    break;
+                case 2: /* prompt */
+                {
+                    char description[256];
+                    snprintf(description, sizeof(description), _("playlist item is making use of the following unsafe option '%s', which may be harmful if used in a malicious way, authorize it ?"), psz_name);
+                    if( DIALOG_OK_YES != intf_UserYesNo( p_obj, _("WARNING: Unsafe Playlist"), description, _("Yes"), _("No"), NULL) )
+                    {
+                        msg_Err( p_obj, "option %s is unsafe and is blocked by security policy", psz_name );
+                        return;
+                    }
+                }
+                default:
+                    ;
+            }
+        }
+    }
+
     /* Create the variable in the input object.
      * Children of the input object will be able to retreive this value
      * thanks to the inheritance property of the object variables. */
index ded2372..ac006c9 100644 (file)
@@ -407,8 +407,8 @@ int vlc_config_set (module_config_t *restrict item, int id, ...)
             break;
         }
 
-        case VLC_CONFIG_SAFE:
-            item->b_safe = VLC_TRUE;
+        case VLC_CONFIG_UNSAFE:
+            item->b_unsafe = VLC_TRUE;
             ret = 0;
             break;
     }