SlideShare une entreprise Scribd logo
1  sur  81
Télécharger pour lire hors ligne
Securing Web Apps with NGINX 
http://wallarm.com 
Stephan Ilyin, si@wallarm.com
How many of you have 
your websites hacked?
Each application 
probably has 
vulnerabilities
… and someday it 
can be hacked
How to harder/secure 
your application?
How deal with attacks 
to your application? 
Chapter 1.
Tip #1. mod_security 
can be a good choice
Mod_security rocks! 
• Open-source. Finally available for NGINX 
• It works! It can be quite efficient in detecting 
attacks 
• Supports virtual patching 
• It is incredible customisable
server { 
listen 80; 
server_name localhost; 
location / { 
ModSecurityEnabled on; 
ModSecurityConfig modsecurity.conf; 
ModSecurityPass @backend; 
} 
location @backend { 
proxy_pass http://localhost:8011; 
proxy_read_timeout 180s; 
} 
}
but mod_security 
is not so good! 
• Relies on regex 
• It is expensive in performance prospective 
• If you use default rulesets, you will get a huge number 
of false-positives 
• Rules tuning is a hard job (difficult to maintain) 
• Signatures never covers all the attacks 
• REGEXs can be bypassed
What rules look like 
# ShellShock virtual patch (Bash attack) 
SecRule REQUEST_HEADERS 
"^(s*)s+{" "phase:1,deny,id: 
1000000,t:urlDecode,status: 
400,log,msg:'CVE-2014-6271 - Bash 
Attack'"
Good practice (imho) 
• Use public ruleset — for monitoring mode 
• Craft rules from scratch specifically for your 
application — for blocking mode
More rules = 
More overhead!
Using phases is good idea 
1. Request headers (REQUEST_HEADERS) 
2. Request body (REQUEST_BODY) 
3. Response headers (RESPONSE_HEADERS) 
4. Response body (RESPONSE_BODY) 
5. Logging (LOGGING)
SecRule phase 2 
SecRule REQUEST_BODY "/+etc/+passwd" 
"t:none,ctl:ResponseBodyAccess=On,msg:'- 
IN- PASSWD path detected', phase: 
2,pass,log,auditlog,id:'10001',t:urlDeco 
de,t:lowercase,severity:1"
SecRule phase 4 
SecRule RESPONSE_BODY "root:x:0:0" 
"id:'20001',ctl:auditLogParts=+E, msg:'- 
OUT- Content of PASSWD detected!',phase: 
4,allow,log,auditlog,t:lowercase,severit 
y:0"
Handbook by Ivan Ristic. Must read!
Tip #2. Give a chance to 
naxsi (another WAF for 
NGINX)
Why naxsi? 
• NAXSI means Nginx Anti Xss & Sql Injection 
(but do more) 
• Naxsi doesn't rely on a signature base (regex)! 
https://github.com/nbs-system/naxsi
naxsi rules 
• Reads a small subset of simple scoring rules 
(naxsi_core.rules) containing 99% of known 
patterns involved in websites vulnerabilities. 
• For example, '<', '|' or 'drop' are not supposed to 
be part of a URI.
This rule triggers on select or other SQL operators 
MainRule "rx:select|union|update|delete| 
insert|table|from|ascii|hex|unhex|drop" 
"msg:sql keywords" "mz:BODY|URL|ARGS| 
$HEADERS_VAR:Cookie" "s:$SQL:4" id:1000;
naxsi setup 
http { 
include /etc/nginx/naxsi_core.rules; 
include /etc/nginx/mime.types; 
[...] 
}
But! Ruleset is not enough! 
• Those patterns may match legitimate queries! 
• Therefore, naxsi relies on whitelists to avoid false 
positives 
• Nxutil tool helps the administrator to create the 
appropriate whitelist 
• there are pre-generated whitelists for some CMS 
(e.g. WordPress)
LearningMode; #Enables learning mode 
SecRulesEnabled; 
#SecRulesDisabled; 
DeniedUrl "/RequestDenied"; 
## check rules 
CheckRule "$SQL >= 8" BLOCK; 
CheckRule "$RFI >= 8" BLOCK; 
CheckRule "$TRAVERSAL >= 4" BLOCK; 
CheckRule "$EVADE >= 4" BLOCK; 
CheckRule "$XSS >= 8" BLOCK;
naxsi ruleset
naxsi whitelist
Naxsi pros and cons 
Pros: 
• Pretty fast! 
• Update independent 
• Resistant to many waf-bypass techniques 
Cons: 
• You need to use LearningMode with each 
significant code deployment
Tip #3. 
Try repsheet 
(behaviour based security)
Watch Aaron Bedra’s talk 
http://getrepsheet.com/
Tip #4. 
And there is also 
Wallarm WAF based on NGINX
http://wallarm.com
How deal with DDoS? 
Chapter 2.
How to deal with DDoS? 
• The traditional technique for self-defense is to read 
the HTTP server’s log file, write a pattern for grep 
(to catch bot requests), and ban anyone who falls 
under it. 
• That’s not easy! 
• The following are tips on where to place pillows in 
advance so it won’t hurt so much when you fall.
Tip #5. 
Use test_cookie module
Use test_cookie module 
• Usually HTTP-flooding bots are pretty stupid 
• Lack HTTP cookie and redirect mechanisms 
• Testcookie-nginx works as a quick filter between 
the bots and the backend during L7 DDoS attacks, 
allowing you to screen out junk requests
Use test_cookie module 
Straightforward checks: 
• Whether the client can perform HTTP Redirect 
• Whether it supports JavaScript 
• Whether it supports Flash
Use test_cookie module 
In addition to its merits, test_cookies also has its 
drawbacks: 
• Cuts out all bots (including Googlebot) 
• Creates problems for users with Links and w3m browsers 
• Does not protect against bots with full-browser-stack 
https://github.com/kyprizel/testcookie-nginx-module
Tip #6. Code 444
Code 444 
• The goal of DDoSers is often the most resource-intensive 
part of the site. 
• A typical example is a search engine. Naturally, it 
can be exploited by charging tens of thousands of 
queries 
• So what can we do?
Code 444 
• Temporarily disable this search function 
• Nginx supports custom code 444, which allows you 
to simply close the connection and give nothing in 
response
Code 444 
location /search { 
return 444; 
}
Tip #7. Use ipset
Ban bots’ IPs with ipset 
• If you’re sure that location/search requests are 
coming only from bots 
• Ban bots (getting 444) with a simple shell script 
ipset -N ban iphash 
tail -f access.log | while read LINE; do 
echo “$LINE” | cut -d’”’ -f3 | cut -d’ ‘ 
-f2 | grep -q 444 && ipset -A ban “${L%% 
*}”; done
Tip #8. Banning based 
on geographic indicators
Tip #8. Banning based on 
geographic indicators 
• You can strictly limit certain countries that make 
you feel uneasy 
• But. It is a bad practice! GeoIP data isn’t 
completely accurate!
Tip #8. Banning based on 
geographic indicators 
• Connect to the nginx GeoIP module 
• Display the geographic indicator information on the 
access log 
• grep the nginx access log and add clients by 
geographic indicators to the ban list.
Tip #9. You can use 
neural network!
Tip #9. You can use neural 
network 
• Bad request: 
0.0.0.0 - - [20/Dec/2011:20:00:08 +0400] "POST 
/forum/index.php HTTP/1.1" 503 107 "http:// 
www.mozilla-europe.org/" “-" 
• Good request: 
0.0.0.0 - - [20/Dec/2011:15:00:03 +0400] 
"GET /forum/rss.php?topic=347425 HTTP/1.0" 200 
1685 "-" "Mozilla/5.0 (Windows; U; Windows NT 
5.1; pl; rv:1.9) Gecko/2008052906 Firefox/3.0"
Tip #9. You can use neural 
network 
Use Machine Learning (ML) to detect bots: 
• use neural network (e.g. PyBrain) 
• stuffed logs inside 
• analyse the requests for classification 
between "bad" and "good" clients under DDoS 
A good proof-of-concept: 
https://github.com/SaveTheRbtz/junk/tree/master/ 
neural_networks_vs_ddos
Tip #9. You can use neural 
network 
• Useful to have the access.log before a DDoS 
attack, because it lists virtually 100% of your 
legitimate clients 
• It is an excellent dataset for neural network training
Tip #10. 
Keep track of the number 
of requests per second
Tip #10. Keep track of the 
number of requests per second 
• You can estimate this value with the following shell 
command 
echo $(($(fgrep -c "$(env LC_ALL=C date 
--date=@$(($(date +%s)-60)) +%d/%b/%Y: 
%H:%M)" “$ACCESS_LOG”)/60))
Tuning the web server 
• Of course, you put nginx on silent and hope that 
everything will be OK. 
• However, things are not always OK. 
• So the administrator of any server should devote a 
lot of time to tweaking and tuning nginx.
Tip #11. 
Limit buffer sizes and 
timeouts in NGINX
Every resource has a limit 
• Every resource has a limit. In particular, this applies 
to memory. 
• the size of the header and all buffers need to be 
limited to adequate values on the client and on the 
server as a whole
Limit buffers 
• client_header_buffer_size 
• large_client_header_buffers 
• client_body_buffer_size 
• client_max_body_size
And time_outs 
• reset_timeout_connection 
• client_header_timeout 
• client_body_timeout 
• keepalive_timeout 
• send_timeout
Question: what are the 
correct parameters for the 
buffers and timeouts?
• There’s no universal recipe here 
• But there is a proven approach you can try
How to limit 
buffers and timeout? 
1. Mathematically arrange the 
minimum parameter value. 
2. Launch site test runs. 
3. If the site’s full functionality works without a 
problem, the parameter is set. 
4. If not, increase the parameter value and 
go to step 2.
Tip #12. 
Limit connections in NGINX 
(limit_conn and limit_req)
Ideally you need to test application to 
see how many requests it can handle 
and set that value in the NGINX 
configuration
http { 
limit_conn_zone $binary_remote_addr zone=download_c:10m; 
limit_req_zone $binary_remote_addr zone=search_r:10m 
rate=1r/s; 
server { 
location /download/ { 
limit_conn download_c 1; 
.. 
} 
location /search/ { 
limit_req zone=search_r burst=5; 
.. 
} 
} 
}
What to limit? 
• It makes sense to set limits for limit_conn and 
limit_req for locations where it’s costly to implement 
scripts 
• You can also fail2ban utility here: 
http://www.fail2ban.org
Bad practices / 
How not to configure NGINX 
Chapter 3.
Bad practices 
• NGINX has secure-enough defaults 
• Sometimes administrators can make mistakes 
cooking it
Tip #13. 
Be careful with 
rewrite with $uri
rewrite with $uri 
• Everyone knows $uri / 
(“normalized" URI of the request) 
• normalization is decoding the text encoded in the 
'%XX' form, resolving references to the relative path 
components '.' and '..', and possible compression 
of two or more adjacent slashes into a single slash
rewrite with $uri 
Typical HTTP -> HTTPS redirect snippet: 
location / { 
rewrite ^ https://$host/$uri; 
} 
location / { 
return 302 https://$host$uri; 
} 
What can go wrong? CRLF (%0d%0a) comes to play
rewrite with $uri 
• Request 
GET /test%0d%0aSet-Cookie:%20malicious%3d1 HTTP/1.0 
Host: yourserver.com 
• Respond 
HTTP/1.1 302 Moved Temporarily 
Server: nginx 
Date: Mon, 02 Jun 2014 13:08:09 GMT 
Content-Type: text/html 
Content-Length: 154 
Connection: close 
Location: https://yourserver.com/test 
Set-Cookie: malicious=1
Use $request_uri 
instead of $uri
Tip #14. Pay attention 
to try_files
try_files 
• try_files checks the existence of files in the 
specified order and uses the first found file for 
request processing 
• if none of the files were found, an internal redirect 
to the URI specified in the last parameter is made
try_files 
There is a Django project 
$ tree /your/django/project/root 
+-- media 
+---- some_static.css 
+-- djangoproject 
+---- __init__.py 
+---- settings.py 
+---- urls.py 
+---- wsgi.py 
+-- manage.py
try_files 
Administrators decide to serve static files with nginx and use 
this configuration 
root /your/django/project/root; 
location / { 
try_files $uri @django; 
} 
location @django { 
proxy_pass http://django_backend; 
}
try_files: what’s wrong? 
• NGINX will first try to serve static file from root, and 
only if it does not exists pass the request to 
@django location 
• Therefore, anyone can access manage.py and all 
of the project sources (including djangoproject/ 
settings.py)
Tip #15. Use 
disable_symlinks 
if_not_owner
Hosters usually do this 
location /static/ { 
root /home/someuser/www_root/static; 
}
What’s the problem? 
User can create symlink to any file available to nginx 
worker (including files of another users)! 
[root@server4 www]# ls -alh 
total 144K 
drwxr-x--- 6 usertest nobody 4.0K Apr 10 20:09 . 
drwx--x--x 13 usertest usertest 4.0K Apr 7 02:16 .. 
-rw-r--r-- 1 usertest usertest 184 Apr 6 21:29 .htaccess 
lrwxrwxrwx 1 usertest usertest 38 Apr 6 22:48 im1.txt -> /home/ 
another_user/public_html/config.php 
-rw-r--r-- 1 usertest usertest 3 May 3 2011 index.html
What you can do 
1. Turn off symlinks (and users will suffer) 
2. Use option disable_symlinks if_not_owner 
(best choice)
Slides: 
bit.ly/nginx_secure_webapps 
http://wallarm.com 
Stephan Ilyin, si@wallarm.com

Contenu connexe

Tendances

Securing your web infrastructure
Securing your web infrastructureSecuring your web infrastructure
Securing your web infrastructureWP Engine
 
Microservices on Application Container Cloud Service
Microservices on Application Container Cloud ServiceMicroservices on Application Container Cloud Service
Microservices on Application Container Cloud ServiceMaarten Smeets
 
Attack-driven defense
Attack-driven defenseAttack-driven defense
Attack-driven defenseZane Lackey
 
JAX London 2015: Java vs Nodejs
JAX London 2015: Java vs NodejsJAX London 2015: Java vs Nodejs
JAX London 2015: Java vs NodejsChris Bailey
 
O'Reilly Software Architecture Conf: Cloud Economics
O'Reilly Software Architecture Conf: Cloud EconomicsO'Reilly Software Architecture Conf: Cloud Economics
O'Reilly Software Architecture Conf: Cloud EconomicsChris Bailey
 
BSides London 2017 - Hunt Or Be Hunted
BSides London 2017 - Hunt Or Be HuntedBSides London 2017 - Hunt Or Be Hunted
BSides London 2017 - Hunt Or Be HuntedAlex Davies
 
JavaOne 2014: Java vs JavaScript
JavaOne 2014:   Java vs JavaScriptJavaOne 2014:   Java vs JavaScript
JavaOne 2014: Java vs JavaScriptChris Bailey
 
Tw noche geek quito webappsec
Tw noche geek quito   webappsecTw noche geek quito   webappsec
Tw noche geek quito webappsecThoughtworks
 
How to Build a Pure Evil Magento Module
How to Build a Pure Evil Magento ModuleHow to Build a Pure Evil Magento Module
How to Build a Pure Evil Magento ModuleAOE
 
High-Performance Magento in the Cloud
High-Performance Magento in the CloudHigh-Performance Magento in the Cloud
High-Performance Magento in the CloudAOE
 
(WEB304) Running and Scaling Magento on AWS | AWS re:Invent 2014
(WEB304) Running and Scaling Magento on AWS | AWS re:Invent 2014(WEB304) Running and Scaling Magento on AWS | AWS re:Invent 2014
(WEB304) Running and Scaling Magento on AWS | AWS re:Invent 2014Amazon Web Services
 
Rock-solid Magento Development and Deployment Workflows
Rock-solid Magento Development and Deployment WorkflowsRock-solid Magento Development and Deployment Workflows
Rock-solid Magento Development and Deployment WorkflowsAOE
 
IBM Monitoring and Diagnostics Tools - Health Center 3.0.2
IBM Monitoring and Diagnostics Tools - Health Center 3.0.2IBM Monitoring and Diagnostics Tools - Health Center 3.0.2
IBM Monitoring and Diagnostics Tools - Health Center 3.0.2Chris Bailey
 
(WEB305) Migrating Your Website to AWS | AWS re:Invent 2014
(WEB305) Migrating Your Website to AWS | AWS re:Invent 2014(WEB305) Migrating Your Website to AWS | AWS re:Invent 2014
(WEB305) Migrating Your Website to AWS | AWS re:Invent 2014Amazon Web Services
 
Fix me if you can - DrupalCon prague
Fix me if you can - DrupalCon pragueFix me if you can - DrupalCon prague
Fix me if you can - DrupalCon praguehernanibf
 
HackFest 2015 - Rasp vs waf
HackFest 2015 - Rasp vs wafHackFest 2015 - Rasp vs waf
HackFest 2015 - Rasp vs wafIMMUNIO
 

Tendances (20)

Securing your web infrastructure
Securing your web infrastructureSecuring your web infrastructure
Securing your web infrastructure
 
Microservices on Application Container Cloud Service
Microservices on Application Container Cloud ServiceMicroservices on Application Container Cloud Service
Microservices on Application Container Cloud Service
 
B wapp – bee bug – installation
B wapp – bee bug – installationB wapp – bee bug – installation
B wapp – bee bug – installation
 
Attack-driven defense
Attack-driven defenseAttack-driven defense
Attack-driven defense
 
JAX London 2015: Java vs Nodejs
JAX London 2015: Java vs NodejsJAX London 2015: Java vs Nodejs
JAX London 2015: Java vs Nodejs
 
O'Reilly Software Architecture Conf: Cloud Economics
O'Reilly Software Architecture Conf: Cloud EconomicsO'Reilly Software Architecture Conf: Cloud Economics
O'Reilly Software Architecture Conf: Cloud Economics
 
Csp and http headers
Csp and http headersCsp and http headers
Csp and http headers
 
BSides London 2017 - Hunt Or Be Hunted
BSides London 2017 - Hunt Or Be HuntedBSides London 2017 - Hunt Or Be Hunted
BSides London 2017 - Hunt Or Be Hunted
 
JavaOne 2014: Java vs JavaScript
JavaOne 2014:   Java vs JavaScriptJavaOne 2014:   Java vs JavaScript
JavaOne 2014: Java vs JavaScript
 
Tw noche geek quito webappsec
Tw noche geek quito   webappsecTw noche geek quito   webappsec
Tw noche geek quito webappsec
 
Android Pentesting
Android PentestingAndroid Pentesting
Android Pentesting
 
How to Build a Pure Evil Magento Module
How to Build a Pure Evil Magento ModuleHow to Build a Pure Evil Magento Module
How to Build a Pure Evil Magento Module
 
High-Performance Magento in the Cloud
High-Performance Magento in the CloudHigh-Performance Magento in the Cloud
High-Performance Magento in the Cloud
 
(WEB304) Running and Scaling Magento on AWS | AWS re:Invent 2014
(WEB304) Running and Scaling Magento on AWS | AWS re:Invent 2014(WEB304) Running and Scaling Magento on AWS | AWS re:Invent 2014
(WEB304) Running and Scaling Magento on AWS | AWS re:Invent 2014
 
Zap vs burp
Zap vs burpZap vs burp
Zap vs burp
 
Rock-solid Magento Development and Deployment Workflows
Rock-solid Magento Development and Deployment WorkflowsRock-solid Magento Development and Deployment Workflows
Rock-solid Magento Development and Deployment Workflows
 
IBM Monitoring and Diagnostics Tools - Health Center 3.0.2
IBM Monitoring and Diagnostics Tools - Health Center 3.0.2IBM Monitoring and Diagnostics Tools - Health Center 3.0.2
IBM Monitoring and Diagnostics Tools - Health Center 3.0.2
 
(WEB305) Migrating Your Website to AWS | AWS re:Invent 2014
(WEB305) Migrating Your Website to AWS | AWS re:Invent 2014(WEB305) Migrating Your Website to AWS | AWS re:Invent 2014
(WEB305) Migrating Your Website to AWS | AWS re:Invent 2014
 
Fix me if you can - DrupalCon prague
Fix me if you can - DrupalCon pragueFix me if you can - DrupalCon prague
Fix me if you can - DrupalCon prague
 
HackFest 2015 - Rasp vs waf
HackFest 2015 - Rasp vs wafHackFest 2015 - Rasp vs waf
HackFest 2015 - Rasp vs waf
 

Similaire à How to secure your web applications with NGINX

introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.jsorkaplan
 
MongoDB at MapMyFitness
MongoDB at MapMyFitnessMongoDB at MapMyFitness
MongoDB at MapMyFitnessMapMyFitness
 
Resilience Testing
Resilience Testing Resilience Testing
Resilience Testing Ran Levy
 
Best Practices for Building WordPress Applications
Best Practices for Building WordPress ApplicationsBest Practices for Building WordPress Applications
Best Practices for Building WordPress ApplicationsTaylor Lovett
 
Open source security
Open source securityOpen source security
Open source securitylrigknat
 
Best Practices for WordPress in Enterprise
Best Practices for WordPress in EnterpriseBest Practices for WordPress in Enterprise
Best Practices for WordPress in EnterpriseTaylor Lovett
 
owasp top 10 security risk categories and CWE
owasp top 10 security risk categories and CWEowasp top 10 security risk categories and CWE
owasp top 10 security risk categories and CWEArun Voleti
 
Malware Analysis For The Enterprise
Malware Analysis For The EnterpriseMalware Analysis For The Enterprise
Malware Analysis For The EnterpriseJason Ross
 
Best practices-wordpress-enterprise
Best practices-wordpress-enterpriseBest practices-wordpress-enterprise
Best practices-wordpress-enterpriseTaylor Lovett
 
FreeSWITCH as a Microservice
FreeSWITCH as a MicroserviceFreeSWITCH as a Microservice
FreeSWITCH as a MicroserviceEvan McGee
 
DEF CON 27 - ORANGE TSAI and MEH CHANG - infiltrating corporate intranet like...
DEF CON 27 - ORANGE TSAI and MEH CHANG - infiltrating corporate intranet like...DEF CON 27 - ORANGE TSAI and MEH CHANG - infiltrating corporate intranet like...
DEF CON 27 - ORANGE TSAI and MEH CHANG - infiltrating corporate intranet like...Felipe Prado
 
Pluggable Infrastructure with CI/CD and Docker
Pluggable Infrastructure with CI/CD and DockerPluggable Infrastructure with CI/CD and Docker
Pluggable Infrastructure with CI/CD and DockerBob Killen
 
Kubernetes and container security
Kubernetes and container securityKubernetes and container security
Kubernetes and container securityVolodymyr Shynkar
 
CENTRAL MANAGEMENT OF NETWORK AND CALL SERVICES
CENTRAL MANAGEMENT OF NETWORK AND CALL SERVICESCENTRAL MANAGEMENT OF NETWORK AND CALL SERVICES
CENTRAL MANAGEMENT OF NETWORK AND CALL SERVICESNazmul Hossain Rakib
 
How to measure your security response readiness?
How to measure your security response readiness?How to measure your security response readiness?
How to measure your security response readiness?Tomasz Jakubowski
 
Cm9 secure code_training_1day_input sanitization
Cm9 secure code_training_1day_input sanitizationCm9 secure code_training_1day_input sanitization
Cm9 secure code_training_1day_input sanitizationdcervigni
 
Open source: Top issues in the top enterprise packages
Open source: Top issues in the top enterprise packagesOpen source: Top issues in the top enterprise packages
Open source: Top issues in the top enterprise packagesRogue Wave Software
 
Performance tuning Grails applications SpringOne 2GX 2014
Performance tuning Grails applications SpringOne 2GX 2014Performance tuning Grails applications SpringOne 2GX 2014
Performance tuning Grails applications SpringOne 2GX 2014Lari Hotari
 
Groovy In the Cloud
Groovy In the CloudGroovy In the Cloud
Groovy In the CloudJim Driscoll
 
Cloud Foundry Summit 2015: 12 Factor Apps For Operations
Cloud Foundry Summit 2015: 12 Factor Apps For OperationsCloud Foundry Summit 2015: 12 Factor Apps For Operations
Cloud Foundry Summit 2015: 12 Factor Apps For OperationsVMware Tanzu
 

Similaire à How to secure your web applications with NGINX (20)

introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.js
 
MongoDB at MapMyFitness
MongoDB at MapMyFitnessMongoDB at MapMyFitness
MongoDB at MapMyFitness
 
Resilience Testing
Resilience Testing Resilience Testing
Resilience Testing
 
Best Practices for Building WordPress Applications
Best Practices for Building WordPress ApplicationsBest Practices for Building WordPress Applications
Best Practices for Building WordPress Applications
 
Open source security
Open source securityOpen source security
Open source security
 
Best Practices for WordPress in Enterprise
Best Practices for WordPress in EnterpriseBest Practices for WordPress in Enterprise
Best Practices for WordPress in Enterprise
 
owasp top 10 security risk categories and CWE
owasp top 10 security risk categories and CWEowasp top 10 security risk categories and CWE
owasp top 10 security risk categories and CWE
 
Malware Analysis For The Enterprise
Malware Analysis For The EnterpriseMalware Analysis For The Enterprise
Malware Analysis For The Enterprise
 
Best practices-wordpress-enterprise
Best practices-wordpress-enterpriseBest practices-wordpress-enterprise
Best practices-wordpress-enterprise
 
FreeSWITCH as a Microservice
FreeSWITCH as a MicroserviceFreeSWITCH as a Microservice
FreeSWITCH as a Microservice
 
DEF CON 27 - ORANGE TSAI and MEH CHANG - infiltrating corporate intranet like...
DEF CON 27 - ORANGE TSAI and MEH CHANG - infiltrating corporate intranet like...DEF CON 27 - ORANGE TSAI and MEH CHANG - infiltrating corporate intranet like...
DEF CON 27 - ORANGE TSAI and MEH CHANG - infiltrating corporate intranet like...
 
Pluggable Infrastructure with CI/CD and Docker
Pluggable Infrastructure with CI/CD and DockerPluggable Infrastructure with CI/CD and Docker
Pluggable Infrastructure with CI/CD and Docker
 
Kubernetes and container security
Kubernetes and container securityKubernetes and container security
Kubernetes and container security
 
CENTRAL MANAGEMENT OF NETWORK AND CALL SERVICES
CENTRAL MANAGEMENT OF NETWORK AND CALL SERVICESCENTRAL MANAGEMENT OF NETWORK AND CALL SERVICES
CENTRAL MANAGEMENT OF NETWORK AND CALL SERVICES
 
How to measure your security response readiness?
How to measure your security response readiness?How to measure your security response readiness?
How to measure your security response readiness?
 
Cm9 secure code_training_1day_input sanitization
Cm9 secure code_training_1day_input sanitizationCm9 secure code_training_1day_input sanitization
Cm9 secure code_training_1day_input sanitization
 
Open source: Top issues in the top enterprise packages
Open source: Top issues in the top enterprise packagesOpen source: Top issues in the top enterprise packages
Open source: Top issues in the top enterprise packages
 
Performance tuning Grails applications SpringOne 2GX 2014
Performance tuning Grails applications SpringOne 2GX 2014Performance tuning Grails applications SpringOne 2GX 2014
Performance tuning Grails applications SpringOne 2GX 2014
 
Groovy In the Cloud
Groovy In the CloudGroovy In the Cloud
Groovy In the Cloud
 
Cloud Foundry Summit 2015: 12 Factor Apps For Operations
Cloud Foundry Summit 2015: 12 Factor Apps For OperationsCloud Foundry Summit 2015: 12 Factor Apps For Operations
Cloud Foundry Summit 2015: 12 Factor Apps For Operations
 

Dernier

Enterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze IncEnterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze Incrobinwilliams8624
 
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.Sharon Liu
 
Watermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security ChallengesWatermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security ChallengesShyamsundar Das
 
eAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionseAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionsNirav Modi
 
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine HarmonyLeveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmonyelliciumsolutionspun
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxJoão Esperancinha
 
AI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human BeautyAI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human BeautyRaymond Okyere-Forson
 
IA Generativa y Grafos de Neo4j: RAG time
IA Generativa y Grafos de Neo4j: RAG timeIA Generativa y Grafos de Neo4j: RAG time
IA Generativa y Grafos de Neo4j: RAG timeNeo4j
 
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...OnePlan Solutions
 
Sales Territory Management: A Definitive Guide to Expand Sales Coverage
Sales Territory Management: A Definitive Guide to Expand Sales CoverageSales Territory Management: A Definitive Guide to Expand Sales Coverage
Sales Territory Management: A Definitive Guide to Expand Sales CoverageDista
 
OpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorOpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorShane Coughlan
 
Generative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilGenerative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilVICTOR MAESTRE RAMIREZ
 
JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIIvo Andreev
 
Growing Oxen: channel operators and retries
Growing Oxen: channel operators and retriesGrowing Oxen: channel operators and retries
Growing Oxen: channel operators and retriesSoftwareMill
 
online pdf editor software solutions.pdf
online pdf editor software solutions.pdfonline pdf editor software solutions.pdf
online pdf editor software solutions.pdfMeon Technology
 
Streamlining Your Application Builds with Cloud Native Buildpacks
Streamlining Your Application Builds  with Cloud Native BuildpacksStreamlining Your Application Builds  with Cloud Native Buildpacks
Streamlining Your Application Builds with Cloud Native BuildpacksVish Abrams
 
Deep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - DatacampDeep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - DatacampVICTOR MAESTRE RAMIREZ
 
Kawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in TrivandrumKawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in TrivandrumKawika Technologies
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadIvo Andreev
 

Dernier (20)

Enterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze IncEnterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze Inc
 
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
20240319 Car Simulator Plan.pptx . Plan for a JavaScript Car Driving Simulator.
 
Watermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security ChallengesWatermarking in Source Code: Applications and Security Challenges
Watermarking in Source Code: Applications and Security Challenges
 
eAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionseAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspections
 
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine HarmonyLeveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
Leveraging DxSherpa's Generative AI Services to Unlock Human-Machine Harmony
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptx
 
AI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human BeautyAI Embracing Every Shade of Human Beauty
AI Embracing Every Shade of Human Beauty
 
IA Generativa y Grafos de Neo4j: RAG time
IA Generativa y Grafos de Neo4j: RAG timeIA Generativa y Grafos de Neo4j: RAG time
IA Generativa y Grafos de Neo4j: RAG time
 
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
 
Sales Territory Management: A Definitive Guide to Expand Sales Coverage
Sales Territory Management: A Definitive Guide to Expand Sales CoverageSales Territory Management: A Definitive Guide to Expand Sales Coverage
Sales Territory Management: A Definitive Guide to Expand Sales Coverage
 
OpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS CalculatorOpenChain Webinar: Universal CVSS Calculator
OpenChain Webinar: Universal CVSS Calculator
 
Generative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilGenerative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-Council
 
JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AI
 
Growing Oxen: channel operators and retries
Growing Oxen: channel operators and retriesGrowing Oxen: channel operators and retries
Growing Oxen: channel operators and retries
 
online pdf editor software solutions.pdf
online pdf editor software solutions.pdfonline pdf editor software solutions.pdf
online pdf editor software solutions.pdf
 
Streamlining Your Application Builds with Cloud Native Buildpacks
Streamlining Your Application Builds  with Cloud Native BuildpacksStreamlining Your Application Builds  with Cloud Native Buildpacks
Streamlining Your Application Builds with Cloud Native Buildpacks
 
Deep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - DatacampDeep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - Datacamp
 
Kawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in TrivandrumKawika Technologies pvt ltd Software Development Company in Trivandrum
Kawika Technologies pvt ltd Software Development Company in Trivandrum
 
Salesforce AI Associate Certification.pptx
Salesforce AI Associate Certification.pptxSalesforce AI Associate Certification.pptx
Salesforce AI Associate Certification.pptx
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and Bad
 

How to secure your web applications with NGINX

  • 1. Securing Web Apps with NGINX http://wallarm.com Stephan Ilyin, si@wallarm.com
  • 2. How many of you have your websites hacked?
  • 3. Each application probably has vulnerabilities
  • 4. … and someday it can be hacked
  • 5. How to harder/secure your application?
  • 6. How deal with attacks to your application? Chapter 1.
  • 7. Tip #1. mod_security can be a good choice
  • 8. Mod_security rocks! • Open-source. Finally available for NGINX • It works! It can be quite efficient in detecting attacks • Supports virtual patching • It is incredible customisable
  • 9. server { listen 80; server_name localhost; location / { ModSecurityEnabled on; ModSecurityConfig modsecurity.conf; ModSecurityPass @backend; } location @backend { proxy_pass http://localhost:8011; proxy_read_timeout 180s; } }
  • 10. but mod_security is not so good! • Relies on regex • It is expensive in performance prospective • If you use default rulesets, you will get a huge number of false-positives • Rules tuning is a hard job (difficult to maintain) • Signatures never covers all the attacks • REGEXs can be bypassed
  • 11. What rules look like # ShellShock virtual patch (Bash attack) SecRule REQUEST_HEADERS "^(s*)s+{" "phase:1,deny,id: 1000000,t:urlDecode,status: 400,log,msg:'CVE-2014-6271 - Bash Attack'"
  • 12. Good practice (imho) • Use public ruleset — for monitoring mode • Craft rules from scratch specifically for your application — for blocking mode
  • 13. More rules = More overhead!
  • 14. Using phases is good idea 1. Request headers (REQUEST_HEADERS) 2. Request body (REQUEST_BODY) 3. Response headers (RESPONSE_HEADERS) 4. Response body (RESPONSE_BODY) 5. Logging (LOGGING)
  • 15. SecRule phase 2 SecRule REQUEST_BODY "/+etc/+passwd" "t:none,ctl:ResponseBodyAccess=On,msg:'- IN- PASSWD path detected', phase: 2,pass,log,auditlog,id:'10001',t:urlDeco de,t:lowercase,severity:1"
  • 16. SecRule phase 4 SecRule RESPONSE_BODY "root:x:0:0" "id:'20001',ctl:auditLogParts=+E, msg:'- OUT- Content of PASSWD detected!',phase: 4,allow,log,auditlog,t:lowercase,severit y:0"
  • 17. Handbook by Ivan Ristic. Must read!
  • 18. Tip #2. Give a chance to naxsi (another WAF for NGINX)
  • 19. Why naxsi? • NAXSI means Nginx Anti Xss & Sql Injection (but do more) • Naxsi doesn't rely on a signature base (regex)! https://github.com/nbs-system/naxsi
  • 20. naxsi rules • Reads a small subset of simple scoring rules (naxsi_core.rules) containing 99% of known patterns involved in websites vulnerabilities. • For example, '<', '|' or 'drop' are not supposed to be part of a URI.
  • 21. This rule triggers on select or other SQL operators MainRule "rx:select|union|update|delete| insert|table|from|ascii|hex|unhex|drop" "msg:sql keywords" "mz:BODY|URL|ARGS| $HEADERS_VAR:Cookie" "s:$SQL:4" id:1000;
  • 22. naxsi setup http { include /etc/nginx/naxsi_core.rules; include /etc/nginx/mime.types; [...] }
  • 23. But! Ruleset is not enough! • Those patterns may match legitimate queries! • Therefore, naxsi relies on whitelists to avoid false positives • Nxutil tool helps the administrator to create the appropriate whitelist • there are pre-generated whitelists for some CMS (e.g. WordPress)
  • 24. LearningMode; #Enables learning mode SecRulesEnabled; #SecRulesDisabled; DeniedUrl "/RequestDenied"; ## check rules CheckRule "$SQL >= 8" BLOCK; CheckRule "$RFI >= 8" BLOCK; CheckRule "$TRAVERSAL >= 4" BLOCK; CheckRule "$EVADE >= 4" BLOCK; CheckRule "$XSS >= 8" BLOCK;
  • 27. Naxsi pros and cons Pros: • Pretty fast! • Update independent • Resistant to many waf-bypass techniques Cons: • You need to use LearningMode with each significant code deployment
  • 28. Tip #3. Try repsheet (behaviour based security)
  • 29. Watch Aaron Bedra’s talk http://getrepsheet.com/
  • 30. Tip #4. And there is also Wallarm WAF based on NGINX
  • 32. How deal with DDoS? Chapter 2.
  • 33. How to deal with DDoS? • The traditional technique for self-defense is to read the HTTP server’s log file, write a pattern for grep (to catch bot requests), and ban anyone who falls under it. • That’s not easy! • The following are tips on where to place pillows in advance so it won’t hurt so much when you fall.
  • 34. Tip #5. Use test_cookie module
  • 35. Use test_cookie module • Usually HTTP-flooding bots are pretty stupid • Lack HTTP cookie and redirect mechanisms • Testcookie-nginx works as a quick filter between the bots and the backend during L7 DDoS attacks, allowing you to screen out junk requests
  • 36. Use test_cookie module Straightforward checks: • Whether the client can perform HTTP Redirect • Whether it supports JavaScript • Whether it supports Flash
  • 37. Use test_cookie module In addition to its merits, test_cookies also has its drawbacks: • Cuts out all bots (including Googlebot) • Creates problems for users with Links and w3m browsers • Does not protect against bots with full-browser-stack https://github.com/kyprizel/testcookie-nginx-module
  • 39. Code 444 • The goal of DDoSers is often the most resource-intensive part of the site. • A typical example is a search engine. Naturally, it can be exploited by charging tens of thousands of queries • So what can we do?
  • 40. Code 444 • Temporarily disable this search function • Nginx supports custom code 444, which allows you to simply close the connection and give nothing in response
  • 41. Code 444 location /search { return 444; }
  • 42. Tip #7. Use ipset
  • 43. Ban bots’ IPs with ipset • If you’re sure that location/search requests are coming only from bots • Ban bots (getting 444) with a simple shell script ipset -N ban iphash tail -f access.log | while read LINE; do echo “$LINE” | cut -d’”’ -f3 | cut -d’ ‘ -f2 | grep -q 444 && ipset -A ban “${L%% *}”; done
  • 44. Tip #8. Banning based on geographic indicators
  • 45. Tip #8. Banning based on geographic indicators • You can strictly limit certain countries that make you feel uneasy • But. It is a bad practice! GeoIP data isn’t completely accurate!
  • 46. Tip #8. Banning based on geographic indicators • Connect to the nginx GeoIP module • Display the geographic indicator information on the access log • grep the nginx access log and add clients by geographic indicators to the ban list.
  • 47. Tip #9. You can use neural network!
  • 48. Tip #9. You can use neural network • Bad request: 0.0.0.0 - - [20/Dec/2011:20:00:08 +0400] "POST /forum/index.php HTTP/1.1" 503 107 "http:// www.mozilla-europe.org/" “-" • Good request: 0.0.0.0 - - [20/Dec/2011:15:00:03 +0400] "GET /forum/rss.php?topic=347425 HTTP/1.0" 200 1685 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9) Gecko/2008052906 Firefox/3.0"
  • 49. Tip #9. You can use neural network Use Machine Learning (ML) to detect bots: • use neural network (e.g. PyBrain) • stuffed logs inside • analyse the requests for classification between "bad" and "good" clients under DDoS A good proof-of-concept: https://github.com/SaveTheRbtz/junk/tree/master/ neural_networks_vs_ddos
  • 50. Tip #9. You can use neural network • Useful to have the access.log before a DDoS attack, because it lists virtually 100% of your legitimate clients • It is an excellent dataset for neural network training
  • 51. Tip #10. Keep track of the number of requests per second
  • 52. Tip #10. Keep track of the number of requests per second • You can estimate this value with the following shell command echo $(($(fgrep -c "$(env LC_ALL=C date --date=@$(($(date +%s)-60)) +%d/%b/%Y: %H:%M)" “$ACCESS_LOG”)/60))
  • 53. Tuning the web server • Of course, you put nginx on silent and hope that everything will be OK. • However, things are not always OK. • So the administrator of any server should devote a lot of time to tweaking and tuning nginx.
  • 54. Tip #11. Limit buffer sizes and timeouts in NGINX
  • 55. Every resource has a limit • Every resource has a limit. In particular, this applies to memory. • the size of the header and all buffers need to be limited to adequate values on the client and on the server as a whole
  • 56. Limit buffers • client_header_buffer_size • large_client_header_buffers • client_body_buffer_size • client_max_body_size
  • 57. And time_outs • reset_timeout_connection • client_header_timeout • client_body_timeout • keepalive_timeout • send_timeout
  • 58. Question: what are the correct parameters for the buffers and timeouts?
  • 59. • There’s no universal recipe here • But there is a proven approach you can try
  • 60. How to limit buffers and timeout? 1. Mathematically arrange the minimum parameter value. 2. Launch site test runs. 3. If the site’s full functionality works without a problem, the parameter is set. 4. If not, increase the parameter value and go to step 2.
  • 61. Tip #12. Limit connections in NGINX (limit_conn and limit_req)
  • 62. Ideally you need to test application to see how many requests it can handle and set that value in the NGINX configuration
  • 63. http { limit_conn_zone $binary_remote_addr zone=download_c:10m; limit_req_zone $binary_remote_addr zone=search_r:10m rate=1r/s; server { location /download/ { limit_conn download_c 1; .. } location /search/ { limit_req zone=search_r burst=5; .. } } }
  • 64. What to limit? • It makes sense to set limits for limit_conn and limit_req for locations where it’s costly to implement scripts • You can also fail2ban utility here: http://www.fail2ban.org
  • 65. Bad practices / How not to configure NGINX Chapter 3.
  • 66. Bad practices • NGINX has secure-enough defaults • Sometimes administrators can make mistakes cooking it
  • 67. Tip #13. Be careful with rewrite with $uri
  • 68. rewrite with $uri • Everyone knows $uri / (“normalized" URI of the request) • normalization is decoding the text encoded in the '%XX' form, resolving references to the relative path components '.' and '..', and possible compression of two or more adjacent slashes into a single slash
  • 69. rewrite with $uri Typical HTTP -> HTTPS redirect snippet: location / { rewrite ^ https://$host/$uri; } location / { return 302 https://$host$uri; } What can go wrong? CRLF (%0d%0a) comes to play
  • 70. rewrite with $uri • Request GET /test%0d%0aSet-Cookie:%20malicious%3d1 HTTP/1.0 Host: yourserver.com • Respond HTTP/1.1 302 Moved Temporarily Server: nginx Date: Mon, 02 Jun 2014 13:08:09 GMT Content-Type: text/html Content-Length: 154 Connection: close Location: https://yourserver.com/test Set-Cookie: malicious=1
  • 72. Tip #14. Pay attention to try_files
  • 73. try_files • try_files checks the existence of files in the specified order and uses the first found file for request processing • if none of the files were found, an internal redirect to the URI specified in the last parameter is made
  • 74. try_files There is a Django project $ tree /your/django/project/root +-- media +---- some_static.css +-- djangoproject +---- __init__.py +---- settings.py +---- urls.py +---- wsgi.py +-- manage.py
  • 75. try_files Administrators decide to serve static files with nginx and use this configuration root /your/django/project/root; location / { try_files $uri @django; } location @django { proxy_pass http://django_backend; }
  • 76. try_files: what’s wrong? • NGINX will first try to serve static file from root, and only if it does not exists pass the request to @django location • Therefore, anyone can access manage.py and all of the project sources (including djangoproject/ settings.py)
  • 77. Tip #15. Use disable_symlinks if_not_owner
  • 78. Hosters usually do this location /static/ { root /home/someuser/www_root/static; }
  • 79. What’s the problem? User can create symlink to any file available to nginx worker (including files of another users)! [root@server4 www]# ls -alh total 144K drwxr-x--- 6 usertest nobody 4.0K Apr 10 20:09 . drwx--x--x 13 usertest usertest 4.0K Apr 7 02:16 .. -rw-r--r-- 1 usertest usertest 184 Apr 6 21:29 .htaccess lrwxrwxrwx 1 usertest usertest 38 Apr 6 22:48 im1.txt -> /home/ another_user/public_html/config.php -rw-r--r-- 1 usertest usertest 3 May 3 2011 index.html
  • 80. What you can do 1. Turn off symlinks (and users will suffer) 2. Use option disable_symlinks if_not_owner (best choice)