diff options
| author | Ben Fuhrmannek | 2021-08-18 13:34:29 +0200 |
|---|---|---|
| committer | Ben Fuhrmannek | 2021-08-18 13:34:29 +0200 |
| commit | 06e1790f1054dd9e02af0e469abfb18d6ca0ff8d (patch) | |
| tree | b00b87a02467c2d50bb5a695f6eba646375e1479 /config/suhosin.rules | |
| parent | 6bf949fdd0870316f13340c08462288fffce9508 (diff) | |
ported Suhosin rules to Snuffleupagus rules
Diffstat (limited to '')
| -rw-r--r-- | config/suhosin.rules | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/config/suhosin.rules b/config/suhosin.rules new file mode 100644 index 0000000..4beb4c8 --- /dev/null +++ b/config/suhosin.rules | |||
| @@ -0,0 +1,281 @@ | |||
| 1 | ## This file is part of the Suhosin-NG (SNG) PHP Hardening project | ||
| 2 | ## - see https://suhosin.org/ for more information. | ||
| 3 | ## | ||
| 4 | ## Snuffleupagus compatibility: Version 0.7.0 with SNG patches and above | ||
| 5 | ## https://github.com/sektioneins/snuffleupagus | ||
| 6 | ## | ||
| 7 | ############################# ### # --------- | ||
| 8 | ## | ||
| 9 | ## This file documents the effort to port as many Suhosin features as possible to Snuffleupagus rules. | ||
| 10 | ## It is meant as a proof of concept and it will serve multiple purposes: | ||
| 11 | ## * Create a reasonably secure configuration for Snuffleupagus. | ||
| 12 | ## * Make it apparent which Suhosin features cannot be easily implemented in SP by just using configuration | ||
| 13 | ## rules. These will be collected and some features will be implemented as part of the Suhosin-NG project. | ||
| 14 | ## * Create a base set of Snuffleupagus rules to make the expert task of configuring a PHP hardening | ||
| 15 | ## extension accessible to a broader audience. This base set of rules will be integrated into a Tool - | ||
| 16 | ## see Milestone 6 (MS6) here: https://github.com/sektioneins/suhosin-ng/projects/1 | ||
| 17 | ## * Provide more configuration examples. | ||
| 18 | ## | ||
| 19 | ############################# ### # --------- | ||
| 20 | |||
| 21 | ## Let's enable relevant features first. | ||
| 22 | sp.ini_protection.enable(); | ||
| 23 | |||
| 24 | ## ===================== | ||
| 25 | ## Logging Configuration | ||
| 26 | ## ===================== | ||
| 27 | |||
| 28 | ## suhosin.log.syslog | ||
| 29 | ## suhosin.log.syslog.facility | ||
| 30 | ## suhosin.log.syslog.priority | ||
| 31 | ## suhosin.log.sapi | ||
| 32 | ## suhosin.log.stdout | ||
| 33 | ## suhosin.log.file | ||
| 34 | ## suhosin.log.file.name | ||
| 35 | ## suhosin.log.file.time | ||
| 36 | ## suhosin.log.script | ||
| 37 | ## suhosin.log.script.name | ||
| 38 | ## suhosin.log.phpscript | ||
| 39 | ## suhosin.log.phpscript.name | ||
| 40 | ## suhosin.log.phpscript.is_safe | ||
| 41 | ## suhosin.log.use-x-forwarded-for | ||
| 42 | |||
| 43 | ## SP will always use either REMOTE_ADDR or HTTP_X_FORWARDED_FOR. | ||
| 44 | |||
| 45 | ## Logging output can be one of | ||
| 46 | sp.log_media("php"); | ||
| 47 | #sp.log_media("syslog"); | ||
| 48 | |||
| 49 | ## More logging options are not implemented in SP. | ||
| 50 | |||
| 51 | ## ================ | ||
| 52 | ## Executor Options | ||
| 53 | ## ================ | ||
| 54 | |||
| 55 | ## suhosin.executor.max_depth | ||
| 56 | ## Not implemented in SP. | ||
| 57 | |||
| 58 | ## suhosin.executor.include.max_traversal | ||
| 59 | ## SP example for max_traversal = 3 | ||
| 60 | sp.disable_function.function_r("^(require|include)(_once)?$").value_r("\\.\\./+\\.\\./+\\.\\./+").drop(); | ||
| 61 | |||
| 62 | ## suhosin.executor.include.whitelist | ||
| 63 | ## suhosin.executor.include.blacklist | ||
| 64 | ## SP version with wrapper whitelist and regex matching include/require: | ||
| 65 | sp.wrappers_whitelist.list("file,php,phar"); | ||
| 66 | sp.disable_function.function_r("^(require|include)(_once)?$").value_r("^php://(stdin|stdout|stderr|input|output|memory|temp)").drop(); | ||
| 67 | |||
| 68 | ## suhosin.executor.include.allow_writable_files | ||
| 69 | ## SP can enable readonly protection | ||
| 70 | #sp.readonly_exec.enable(); | ||
| 71 | |||
| 72 | ## suhosin.executor.func.whitelist | ||
| 73 | ## suhosin.executor.func.blacklist | ||
| 74 | #sp.disable_function.function("...").drop(); | ||
| 75 | |||
| 76 | ## suhosin.executor.eval.whitelist | ||
| 77 | ## suhosin.executor.eval.blacklist | ||
| 78 | #sp.eval_blacklist.list("system,exec,shell_exec"); | ||
| 79 | |||
| 80 | ## suhosin.executor.disable_eval | ||
| 81 | #sp.disable_function.function("eval").drop(); | ||
| 82 | |||
| 83 | |||
| 84 | ## suhosin.executor.disable_emodifier | ||
| 85 | ## This is actually not needed anymore in PHP 7 and above | ||
| 86 | |||
| 87 | ## suhosin.executor.allow_symlink | ||
| 88 | ## SP can simply disable the symlink function. | ||
| 89 | ## Other ways to create symlinks should be disabled as well, e.g. system("ln -s ...") | ||
| 90 | #sp.disable_function.function("symlink").drop(); | ||
| 91 | #sp.disable_function.function("system").drop(); | ||
| 92 | #sp.disable_function.function("shell_exec").drop(); | ||
| 93 | #sp.disable_function.function("exec").drop(); | ||
| 94 | #sp.disable_function.function("proc_open").drop(); | ||
| 95 | |||
| 96 | |||
| 97 | ## | ||
| 98 | ## ============ | ||
| 99 | ## Misc Options | ||
| 100 | ## ============ | ||
| 101 | ## | ||
| 102 | |||
| 103 | ## suhosin.simulation | ||
| 104 | ## SP provides individual .simulation() switches for most features. | ||
| 105 | |||
| 106 | ## suhosin.perdir | ||
| 107 | ## Not implemented in SP. | ||
| 108 | |||
| 109 | |||
| 110 | ## suhosin.protectkey | ||
| 111 | ## SP does not actually need to protect its secret key this way, as it is not a native PHP ini directive shown in phpinfo() | ||
| 112 | |||
| 113 | ## suhosin.coredump | ||
| 114 | ## SP can be started in gdb/lldb, so this feature may not be needed. | ||
| 115 | |||
| 116 | ## suhosin.stealth | ||
| 117 | ## Not implemented in SP. | ||
| 118 | ## If ionCube support or similar extensions should ever be requested to run with SP, this feature may be implemented some day. | ||
| 119 | |||
| 120 | ## suhosin.apc_bug_workaround | ||
| 121 | ## This is not a thing anymore with PHP7+ | ||
| 122 | |||
| 123 | ## suhosin.disable.display_errors | ||
| 124 | #sp.ini.key("display_errors").set("0").ro(); | ||
| 125 | #sp.ini.key("display_startup_errors").set("0").ro(); | ||
| 126 | #sp.ini.key("expose_php").set("0").ro(); | ||
| 127 | |||
| 128 | ## suhosin.multiheader | ||
| 129 | ## There is a PHP filter in place to prevent multiple headers in one header() call - let's hope it works. | ||
| 130 | |||
| 131 | ## suhosin.mail.protect | ||
| 132 | sp.disable_function.function("mail").param("to").value_r("\\n").alias("newline in mail() To:").drop(); | ||
| 133 | sp.disable_function.function("mail").param("subject").value_r("\\n").alias("newline in mail() Subject:").drop(); | ||
| 134 | sp.disable_function.function("mail").param("additional_headers").param_type("STRING").drop(); | ||
| 135 | sp.disable_function.function("mail").param("additional_headers").param_type("NULL").allow(); | ||
| 136 | sp.disable_function.function("mail").param("additional_headers").key_r("^(to|b?cc)$").drop(); | ||
| 137 | |||
| 138 | |||
| 139 | ## suhosin.memory_limit | ||
| 140 | ## SP can either disable or limit the memory_limit setting | ||
| 141 | #sp.ini.key("memory_limit").ro(); | ||
| 142 | sp.ini.key("memory_limit").min("4M").max("256M").rw(); | ||
| 143 | |||
| 144 | |||
| 145 | ## ======================== | ||
| 146 | ## SQL Injection Protection | ||
| 147 | ## ======================== | ||
| 148 | |||
| 149 | ## suhosin.sql.bailout_on_error | ||
| 150 | ## SP example for mysqli and PDO | ||
| 151 | #sp.disable_function.function("mysqli_query").ret("FALSE").drop(); | ||
| 152 | #sp.disable_function.function("mysqli::query").ret("FALSE").drop(); | ||
| 153 | #sp.disable_function.function("mysqli_real_query").ret("FALSE").drop(); | ||
| 154 | #sp.disable_function.function("mysqli::real_query").ret("FALSE").drop(); | ||
| 155 | #sp.disable_function.function("mysqli_prepare").ret("FALSE").drop(); | ||
| 156 | #sp.disable_function.function("mysqli::prepare").ret("FALSE").drop(); | ||
| 157 | #sp.disable_function.function("mysqli_stmt_execute").ret("FALSE").drop(); | ||
| 158 | #sp.disable_function.function("mysqli_stmt::execute").ret("FALSE").drop(); | ||
| 159 | #sp.disable_function.function("mysqli_execute").ret("FALSE").drop(); | ||
| 160 | #sp.disable_function.function("PDO::query").ret("FALSE").drop(); | ||
| 161 | #sp.disable_function.function("PDO::prepare").ret("FALSE").drop(); | ||
| 162 | #sp.disable_function.function("PDO::exec").ret("FALSE").drop(); | ||
| 163 | #sp.disable_function.function("PDOStatement::execute").ret("FALSE").drop(); | ||
| 164 | |||
| 165 | |||
| 166 | ## suhosin.sql.user_match | ||
| 167 | ## suhosin.sql.user_prefix | ||
| 168 | ## suhosin.sql.user_postfix | ||
| 169 | ## SP example for mysqli | ||
| 170 | set SQL_USER "^public_"; | ||
| 171 | sp.disable_function.function("mysqli::__construct").param("username").value_r(SQL_USER).allow(); | ||
| 172 | sp.disable_function.function("mysqli::__construct").drop(); | ||
| 173 | sp.disable_function.function("mysqli_connect").param("username").value_r(SQL_USER).allow(); | ||
| 174 | sp.disable_function.function("mysqli_connect").drop(); | ||
| 175 | sp.disable_function.function("mysqli::change_user").param("username").value_r(SQL_USER).allow(); | ||
| 176 | sp.disable_function.function("mysqli::change_user").drop(); | ||
| 177 | sp.disable_function.function("mysqli_change_user").param("username").value_r(SQL_USER).allow(); | ||
| 178 | sp.disable_function.function("mysqli_change_user").drop(); | ||
| 179 | |||
| 180 | ## suhosin.sql.comment | ||
| 181 | ## suhosin.sql.opencomment | ||
| 182 | ## Not implemented in SP. | ||
| 183 | ## It is possible to try and find common injection patterns such as ' or 1=1 -- via regex, | ||
| 184 | ## but that would likely trigger valid SQL strings containing these patterns as well. The same argument | ||
| 185 | ## applies to multiselect and union: | ||
| 186 | |||
| 187 | ## suhosin.sql.multiselect | ||
| 188 | ## suhosin.sql.union | ||
| 189 | ## Not implemented in SP. | ||
| 190 | |||
| 191 | |||
| 192 | ## ============================== | ||
| 193 | ## Transparent Encryption Options | ||
| 194 | ## ============================== | ||
| 195 | |||
| 196 | ## suhosin.session.cryptkey | ||
| 197 | ## suhosin.session.cryptua | ||
| 198 | ## suhosin.cookie.cryptkey | ||
| 199 | ## suhosin.cookie.cryptua | ||
| 200 | |||
| 201 | ## SP's session encryption and cookie encryption features rely on a secret key that is derived from | ||
| 202 | ## * the user agent string from the environment variable HTTP_USER_AGENT | ||
| 203 | ## * the value of the environment variable specified using sp.global.cookie_env_var(), | ||
| 204 | ## usually either REMOTE_ADDR or SSL_SESSION_ID | ||
| 205 | ## * a very secret key as specified using sp.global.secret_key() | ||
| 206 | sp.global.secret_key("c6a0e02b3b818f7559d5f85303d8fe44"); ## this key should be unique to your installation. | ||
| 207 | sp.global.cookie_env_var("REMOTE_ADDR"); | ||
| 208 | #sp.global.cookie_env_var("SSL_SESSION_ID"); | ||
| 209 | |||
| 210 | ## suhosin.session.encrypt | ||
| 211 | sp.session.encrypt(); | ||
| 212 | |||
| 213 | ## suhosin.cookie.encrypt | ||
| 214 | ## suhosin.cookie.cryptlist | ||
| 215 | ## suhosin.cookie.plainlist | ||
| 216 | #sp.cookie.name("my_cookie_name").encrypt(); | ||
| 217 | #sp.cookie.name_r("^enc_[a-z]+$").encrypt(); | ||
| 218 | |||
| 219 | ## suhosin.session.cryptdocroot | ||
| 220 | ## suhosin.session.cryptraddr | ||
| 221 | ## suhosin.session.checkraddr | ||
| 222 | ## suhosin.cookie.cryptdocroot | ||
| 223 | ## suhosin.cookie.cryptraddr | ||
| 224 | ## suhosin.cookie.checkraddr | ||
| 225 | ## For SP to include the document root or part of the IP address in the encryption key, the .cookie_env_var() | ||
| 226 | ## can be constructed by the web server to include these values. | ||
| 227 | |||
| 228 | |||
| 229 | ## ================= | ||
| 230 | ## Filtering Options | ||
| 231 | ## ================= | ||
| 232 | |||
| 233 | ## suhosin.filter.action | ||
| 234 | ## suhosin.cookie|get|post|request.max_array_depth | ||
| 235 | ## suhosin.cookie|get|post|request.max_array_index_length | ||
| 236 | ## suhosin.cookie|get|post.max_name_length | ||
| 237 | ## suhosin.request.max_varname_length | ||
| 238 | ## suhosin.cookie|get|post|request.max_totalname_length | ||
| 239 | ## suhosin.cookie|get|post|request.max_value_length | ||
| 240 | ## suhosin.cookie|get|post|request.max_vars | ||
| 241 | ## suhosin.cookie|get|post|request.disallow_nul | ||
| 242 | ## suhosin.cookie|get|post|request.disallow_ws | ||
| 243 | ## suhosin.request.array_index_blacklist | ||
| 244 | ## suhosin.request.array_index_whitelist | ||
| 245 | ## suhosin.upload.max_uploads | ||
| 246 | ## suhosin.upload.max_newlines | ||
| 247 | ## suhosin.upload.disallow_elf | ||
| 248 | ## suhosin.upload.disallow_binary | ||
| 249 | ## suhosin.upload.remove_binary | ||
| 250 | ## suhosin.upload.allow_utf8 | ||
| 251 | ## Not implemented in SP. | ||
| 252 | |||
| 253 | ## suhosin.upload.verification_script | ||
| 254 | #sp.upload_validation.script("/var/www/is_valid_php.py").enable(); | ||
| 255 | |||
| 256 | |||
| 257 | ## suhosin.session.max_id_length | ||
| 258 | ## suhosin.server.encode | ||
| 259 | ## suhosin.server.strip | ||
| 260 | ## Not implemented in SP. | ||
| 261 | |||
| 262 | ## suhosin.rand.seedingkey | ||
| 263 | ## suhosin.rand.reseed_every_request | ||
| 264 | ## suhosin.srand.ignore | ||
| 265 | ## suhosin.mt_srand.ignore | ||
| 266 | ## Instead of removing srand()/mt_srand(), SP basically replaces rand()/mt_rand() with the more secure random_int() | ||
| 267 | sp.harden_random.enable(); | ||
| 268 | |||
| 269 | ############################# ### # --------- | ||
| 270 | ## | ||
| 271 | ## features included in SP that are not covered by Suhosin rule equivalents | ||
| 272 | ## - see https://snuffleupagus.readthedocs.io/ for more information | ||
| 273 | |||
| 274 | # sp.unserialize_hmac.enable(); | ||
| 275 | # sp.global_strict.enable(); | ||
| 276 | sp.auto_cookie_secure.enable(); | ||
| 277 | #sp.cookie.name("cookie1").samesite("lax"); | ||
| 278 | #sp.cookie.name("cookie2").samesite("strict");; | ||
| 279 | sp.disable_xxe.enable(); | ||
| 280 | #sp.sloppy_comparison.enable(); | ||
| 281 | |||
