Closed seansan closed 2 years ago
My understanding of this situation regarding PCI-DSS compliance and Magento 1.9 EOL is that as long as you don't handle credit card details yourself by outsourcing to a fully compliant PCI-DSS vendor you don't need the full compliance.
In Stripe's documentation it says for example that by using Stripe Elements you automatically qualify to the most basic level of PCI-DSS compliance SAQ A (which does not contain Requirement 6).
For users that have developed their own integration and are using either Checkout or Stripe.js and Elements to collect card details from customers, you are eligible for the simplest method of PCI validation: SAQ A. Stripe automatically creates a combined SAQ A and Attestation of Compliance (AoC) for you, available for you to download in your account’s compliance settings, and no action is required on your part to submit further proof of your PCI compliance.
This is possible because Checkout and Elements host all form inputs containing card data within an iframe served from Stripe’s domain—not yours—so your customers’ card information never touches your servers.
Regarding Paypal the default Magento integration redirects to Paypal's own website which means that the website never actually sees the payment details just the final payment token which should also make it SAQ A compliant.
I only investigated the two specific payment methods that affect our business so I am not aware of how other payment integrations work.
adding some more Links
as of https://twitter.com/mbalparda/status/1262742228696395779 : https://www.pcisecuritystandards.org/documents/FAQs-for-PCI-Software-Security-Framework-v1_0.pdf https://www.pcisecuritystandards.org/documents/PCI-Secure-SLC-Standard-v1_0.pdf
also we should list Vendors, who post about it in a supportive way
As this is a dynamic topic, we should add a dedicated Page to our Website for PCI, we can additionally publish a Blogpost when we reached enough content, to have it forward to News Websites
we should add a dedicated Page to our Website for PCI
I agree lets do this fast
On Tue, May 19, 2020 at 3:56 PM Daniel Fahlke notifications@github.com wrote:
adding some more Links
as of https://twitter.com/mbalparda/status/1262742228696395779 :
https://www.pcisecuritystandards.org/documents/FAQs-for-PCI-Software-Security-Framework-v1_0.pdf
https://www.pcisecuritystandards.org/documents/PCI-Secure-SLC-Standard-v1_0.pdf
also we should list Vendors, who post about it in a supportive way
- https://blog.onestepcheckout.com/2020/05/magento-1-store-payments-30th-june-2020-pci-compliance/
As this is a dynamic topic, we should add a dedicated Page to our Website for PCI, we can additionally publish a Blogpost when we reached enough content, to have it forward to News Websites
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/OpenMage/magento-lts/issues/975#issuecomment-630835344, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE7I22G45AGDOU2NBCD7A3RSKFXNANCNFSM4NANNIPQ .
Adding a link: Self-Assessment Questionnaires That's IMHO a nice, condensed, overview.
Most merchants offering CC payments should be able to easily fulfill the SAQ-A requirements (no audits required). Anyway, a merchant should never store CC data or even get in touch with it (= SAQ-A). Thats in it's own interest. So it's really a non-issue issue for most merchants and pretty much any e-commerce platform.
Things like recurring CC payments with tokenization are AFAIK not even a PCI compliance subject. That's up to the merchant to provide good enough security.
I wasn't aware of fear mongering on that topic. So it would be nice to clearify that for merchants, and maybe also publish it via admin-notifications...
https://www.paypal.com/us/smarthelp/article/faq4241
Paypal says:
Q: If PayPal processes my card data, do I still need to comply? A: Yes, even if you outsource part of your PCI DSS compliance to PayPal, you are still required to install security patches within one month of release, which will no longer be possible after June 30, 2020. In addition to these patches, merchants are responsible for meeting all requirements of their PCI DSS compliance.
Do we have to worry? Could it be that the use of "Paypal Express" is blocked?
It seems unlikely that PayPal will do anything active against existing Magento 1 installations, they just won't officially support it. They already accept PayPal payments through many other EOL applications or those that do not have vendor support. In addition, they don't specifically state something to the effect of "you will no longer be able to receive payments using PayPal", but rather they say "your integration will be out of compliance" and are vague enough to make it sound scary.
As long as a store is still taking active measures to remain secure, such as continuing to apply OpenMage patches and all the security measures they should have already been taking, it would remain in compliance with PCI. In the worst case you may have to contact PayPal and explain to them that the site is still being maintained in line with PCI requirements, but I personally see even that as unlikely.
PayPal and Adobe have entered into an agreement for PayPal to offer loans to companies to upgrade to Magento 2 and it does seem like this messaging is designed to scare people into upgrading.
As a side note, PayPal's own Magento 1 EOL announcement links to the Magento Association's EOL resources, which in turn links to the OpenMage project.
Thanks @rossbearman, very clear for me now! It's our same thinking ;-) We need to pass this info to our customers!
If the OpenMage maintainers haven't already, it may be worth reaching out to Mage One about this, as they are also trying to get some clarification from both PayPal and VISA on this matter.
(cc: @Schrank)
I think we need to open a section on open mage and clarify dat we DO provide patches. Almost every two days. And that the code IS maintained.
On Thu, 21 May 2020 at 12:03, Ross Bearman notifications@github.com wrote:
If the OpenMage maintainers haven't already, it may be worth reaching out to Mage One about this, as they are also trying to get some clarification https://mage-one.com/2020/05/15/open-letter-to-paypal-and-visa-about-the-end-of-life-of-the-magento-1-x-platform/ from both PayPal and VISA on this matter.
(cc: @Schrank https://github.com/Schrank)
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/OpenMage/magento-lts/issues/975#issuecomment-631999847, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE7I23IWOJU3CI3LGJYWL3RST4AXANCNFSM4NANNIPQ .
Hey @rossbearman thanks for the mention. PCI is unfortunately a highly discussable field and the outcome is: A shop/merchant can be PCI compliant a software can not (that might be simplified until wrong, but I think you get the main point). We talked to a couple of experts, QSAs, etc. and the outcome is, only a QSA can tell you based on your single Magento website, whether you are compliant or not - and of course all of them are humans, this means, one QSA might accept OpenMage or MageOne but another doesn't. One accepts us, but not you and the other way around. So just stating that you are providing patches and therefore the shop is compliant is wrong. But I think one can argue, that you provide patches, therefore the Shop comply with 6.2 of PCI DSS. The big questions is: Is it enough for the QSA? Without having people actively searching for security vulnerabilities.
MageOne (avoiding "we" here to not confuse with us here :-)) discussed in the beginning whether we partner up and share forces with OpenMage, but there are two reasons against:
PCI is an annoying topic. The Specifications of PCI DSS don't know about OSS and is unspecific with the definition of 'vendor', no one is able to tell you what to do on a generic software level to be compliant (read as: if you want to know whether you are compliant, you need an assessment for your store). We and you are giving our best to be part of the solution, hopefully this is enough.
I think it'd be great to add a list of payment processors/gateways that have quality M1 extensions which allow for SAQ A compliance (not SAQ A-EP). That is, form fields are fully hosted (redirect or iframe), multi-use tokens (saved card), refunds supported, etc. It's a lot easier to switch payment processors than it is to re-platform!
@ioweb-gr could you please move this question somewhere else? It does not belong into the topic of this issue, which is already big enough in context.
One customer of ours received this email from Adyen yesterday:
Dear Sir/Madam,
This email is regarding the account(s) you have on the Adyen payment platform (your payment service provider).
We thank you for your business to date, and are contacting you in light of the upcoming Magento 1 End of Life in combination with statements by payment industry parties ( such as Visa) about PCI compliance of Magento 1 merchants.
Making sure that you and your customer’s data is secure is of utmost importance to us. Unfortunately, since we cannot guarantee that this will be the case on Magento 1 moving forward, we require urgent action by you.
Our records indicate that you are currently on Magento 1, which means you need to take one of the following actions before 30 June 2020:
- Migrate to a different eCommerce platform (Magento 2 or another supplier) in order to remain PCI-DSS compliant and secure. After your migration is completed, please inform us by sending an email to our support team.
- If you are not using Magento 1 as your eCommerce platform, please inform us of this by sending an email to our support team.
Unless we receive an email confirming one of the above actions by 30 June 2020, we hereby give you formal notice of our decision to terminate the Merchant Agreement with your company in accordance with article 10.1 of the Terms & Conditions applicable to your Merchant Agreement.
The termination will come into effect after due observation of a 2 (two) month termination period after this letter. Therefore, unless we receive your confirmation as set out above by 30 June 2020, your account will be terminated per 30 July 2020. If you wish to continue processing payments after this date while using Magento 1, you will need to do so via a different payment provider.
As per the terms of the Merchant Agreement, you will still be responsible for any chargebacks and fraud related to the transactions we are processing for your company. After the chargeback period has ended, we will settle the final amount into your account. Please note that we reserve all rights in this respect.
Hopefully we have informed you sufficiently, we would like to thank you for doing business with Adyen. In case of inquiries, please do not hesitate to contact us.
Sincerely,
Adyen N.V.
We'll reply that we're switching to OpenMage. If this is enough for them fine, otherwise we'll switch to another payment provider.
@mmenozzi Do you have reply from Adyen?
Hi, sorry guys for the delay. Yes they replied... Here their response:
Hi Manuele,
I have read through your message and we completely understand your frustration. Unfortunately, due to recent statements by card schemes such as Visa in relation to Magento 1, only security patches released by Magento will allow you to be PCI DSS compliant. Since there will be no security patches released by Magento for Magento 1 after June 30 this means that you will no longer be PCI DSS compliant.
PCI DSS (Payment Card Industry Data Security Standard) are global standards set by the card schemes (such as Visa and Mastercard) and apply to all merchants that processes card payments. We would love to have given you a longer notice period however this was not possible due to the timing of statements released.
Due to the scale of the fines involved with breaches for merchants who are not PCI DSS compliant I'm afraid that we can no longer process for your business after July 30th if you remain on Magento 1.
I am sorry that I can not bring you better news and I hope we can find a way to continue working together in the future.
For more information please visit our pages: Magento 1 End Of Life Magento 1 FAQ
Kind regards, Adyen Support
Note that in my message I also asked what about Magento 2.0, 2.1 and 2.2 which are already in EOL. They didn't reply to this question. And I cannot find any answer to this question elsewhere.
We maintain system PCI compliance in the UK via nginx config. Our site undergoes regular penetration tests for this compliance. Maybe we can all agree a best practice Nginx config for LTS.
@ollyboy I think a simple, secure, production-ready config would be great to provide, perhaps as an article on the webpage so that the user can customize it as they follow along? Docker-based of course. :)
@ollyboy Can you share the config you have so far, please? Maybe the community can review it and work towards publishing it as an officially recommended best practice.
@ollyboy yes interested in the setup. Also checkout magenx Magento nginx setup which is quite advanced and with security built in. We added some additions on top. Main item I’ve been watching out for is to create some honeypot for admin uris that are known for invulnerabilities and if they are requested then we know it’s a bad request - and send it to ban.
Hi all. Here is nginx config. I have text replaced my clients name with [client]. You need to review any of the [...] strings and replace for your own use. This config is passing a UK penetration/PCI scan.
# xpractical nginx config, adapted from www.hypernode.com
user www-data;
# hypernode use 4 here, we have quad core
worker_processes 8;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
# This uses Nginx’s Map module to set a variable $fastcgi_https.
# The variable is set to “off” by default, and “on” for HTTPS connections. We then use the variable to set a FastCGI parameter.
map $scheme $fastcgi_https {
default off;
https on;
}
# extra logging
log_format timed_combined '$remote_addr - $remote_user [$time_local] '
'"$http_x_forwarded_for" '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe $host $request_uri';
access_log /var/log/nginx/access.log timed_combined;
error_log /var/log/nginx/error.log notice;
# basic settings
disable_symlinks off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
# allows big media uploads
client_max_body_size 120m;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# SSL global Settings
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_protocols TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE , dropping TLSv1 for PCI compliance
ssl_prefer_server_ciphers on;
# pre trustwave PCI check
#ssl_ciphers HIGH:!aNULL:!MD5;
# post trustwave PCI check
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS;
# GeoIP support is included in the Ubuntu 12.04 Nginx.
# This enables logging, and the following:
# if ($geoip_country_code ~ (CN|ZW) ) {
# return 403;
# }
# geoip_country /usr/share/GeoIP/GeoIP.dat;
# CloudFlare GeoIP Mapping 07-10-2016
map $http_cf_ipcountry $country {
default us;
AU au; NZ au;
CA ca;
DE uk; GB uk; FR uk; AT uk; BE uk; HR uk; CY uk; CZ uk; DK uk; EE uk; FI uk; GR uk; HU uk; IS uk; IE uk; IT uk; LU uk; MD uk; MC uk; NL uk; NO uk; PL uk; PT uk; RO uk; RU uk; SK uk; SI uk; ES uk; SE uk; CH uk; UA uk; VA uk;
}
#gzip settings
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 1100;
gzip_types
text/plain
text/css
text/js
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/xml+rss ;
# Determine whether a request comes from a human, a search crawler or another bot.
# [client] SOE bot is Screaming Frog SEO Spider/7.2
map $http_user_agent $is_non_search_bot {
default '';
~*(Screaming|Frog|dotMailer) '';
~*(google|pingdom|monitis.com|Zend_Http_Client) '';
~*(http|bing|crawler|spider|bot|search|ForusP|Wget/|Python-urllib|PHPCrawl|bGenius|LieBaoFast) 'bot';
~*(Mb2345Browser|zh-CN|MicroMessenger|zh_CN|HUAWEIFRD) 'bot';
}
# Rate limit bots (that are not search spiders) to one PHP request per second.
# An empty '$limit_bots' would disable rate limiting for this requests
# limit_req_zone $is_non_search_bot zone=bots:1m rate=1r/s;
limit_req_zone $is_non_search_bot zone=bots:1m rate=6r/m;
# need to use x_forward so we dont limit CDN
limit_req_zone $http_x_forwarded_for zone=allusers:16m rate=5r/s;
limit_req_log_level error;
# As this is the first server definition it will be used if there is a good match to server_name OR
# if there is no match to any server name
server {
server_name [client].com, [client]one.org;
# if no server name all requests get here
#server_name [client].com www.[client].com
# single server that listens on both http and https
listen 80;
listen 443 default ssl;
include /var/www/keyconfigfiles/cloudflare.whitelist;
#deny all;
# go daddy crts, not complete need to generate bundle
#ssl_certificate /home/[mag_user]/xp-demo.com/e7a321f0b88a7e89.crt;
#ssl_certificate_key /home/[mag_user]/xp-demo.com/xp-demo.key;
# may be able to use these SSL should be linked to domain and web server not the hardware or IP
#ssl_certificate /var/www/ssl/[client].com.crt;
#ssl_certificate_key /var/www/ssl/[client].com.key;
ssl_certificate /var/www/ssl2018/[client].com.crt;
ssl_certificate_key /var/www/ssl2018/[client].com.key;
# openssl req -new -newkey rsa:2048 -nodes -keyout example.key -out example.csr
# use the csr request to get the crt files
# cat all crt's into one bundle file, make sure the main one is top of list
#ssl_certificate /home/[mag_user]/[client]one_org-ssl-bundle.crt;
#ssl_certificate_key /home/[mag_user]/[client]one_org.key;
# If the site is accessed via mydomain.com
# automatically redirect to www.mydomain.com.
#if ($host = 'mydomain.com' ) {
# rewrite ^/(.*)$ http://www.mydomain.com/$1permanent;
#}
# if you are using a load balancer uncomment these lines
# header from the hardware load balancers
#real_ip_header X-Forwarded-For;
# trust this header from anything inside the subnet
#set_real_ip_from X.X.X.1/24;
# the header is a comma-separated list; the left-most IP is the end user
#real_ip_recursive on;
#listen 10.10.10.11:80;
#set_real_ip_from 103.248.190.60;
# use this to test pre-production magento folder, danger new code will update database
set $my_path var/www/magento;
if ($remote_addr ~ "^(110\.175\.187\.117)$" ) {
# set $my_path var/www/temp-magento;
set $my_path var/www/magento;
}
root /$my_path;
error_page 500 502 503 504 /custom_50x.html;
location = /custom_50x.html {
root /usr/share/nginx/html;
internal;
}
# magento specific
set $storecode "default";
index index.html index.php;
autoindex off; # we don’t want users to see files in directories
# security
if ($http_user_agent = "") { return 444;}
# sitemap files
location ~ /sitemap.xml|/([a-z][a-z]|[a-z][a-z]-[a-z][a-z])/(.*)sitemap.xml {
try_files /sitemaps/$1/sitemap.xml /sitemaps/sitemap.xml =404;
}
# allow view of sub folders and files here
location /downloads/ { autoindex on; }
# Denied locations require a "^~" to prevent regexes (such as the PHP handler below) from matching
# http://nginx.org/en/docs/http/ngx_http_core_module.html#location
location ^~ /app/ { return 403; }
location ^~ /shell/ { return 403; }
location ^~ /vendor/ { return 403; }
location ^~ /includes/ { return 403; }
location ^~ /media/downloadable/ { return 403; }
location ^~ /pkginfo/ { return 403; }
location ^~ /report/config.xml { return 403; }
location ^~ /var/ { return 403; }
location ^~ /lib/ { return 403; }
location ^~ /dev/ { return 403; }
location ^~ /RELEASE_NOTES.txt { return 403; }
location ^~ /downloader/pearlib { return 403; }
location ^~ /downloader/template { return 403; }
location ^~ /downloader/Maged { return 403; }
location ~* ^/errors/.+\.xml { return 403; }
# Extra protection
location ~* ^/rss/(order|catalog)/ { return 444; }
location ~ /(dev/tests/|errors/local.xml|cron\.php) { deny all; }
# note this will stop zip download location ~ ^/.*\.(sh|pl|swp|phar|sql|conf|zip|tar|.+gz)$ { return 444; }
location ~ ^/.*\.(sh|pl|swp|phar|sql|conf|tar|.+gz)$ { return 444; }
location ~ /\.(svn|git|hg|htpasswd|bash|ssh) { return 444; }
location ~* /(lib|media|shell|skin)/.*\.php$ { deny all; }
# CVE-2015-3428 / AW_Blog vulnerability
# Note the .+ at the start: We want to allow url's like
# order=create_date, which would otherwise match.
if ($arg_order ~* .+(select|create|insert|update|drop|delete|concat|alter|load)) {
return 403;
}
# Don't skip .thumbs, this is a default directory where Magento places thumbnails
# Nginx cannot "not" match something, instead the target is matched with an empty block
# http://stackoverflow.com/a/16304073
location ~ /\.thumbs {
}
# Skip .git, .htpasswd etc
location ~ /\. {
return 404;
}
# Disable all methods besides HEAD, GET and POST.
if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; }
# Try static files first, then pass to Magento handler
location / {
# stop specific IPs until fixed in CDN - added in to CF 24032020
#deny 77.246.157.20;
# enable limits
limit_req zone=allusers burst=5 nodelay;
limit_req zone=bots;
#
try_files $uri $uri/ @handler;
access_log off; # do not log access to static files
expires max; # cache static files aggressively
}
# Pass paths to Magento entry point
location @handler {
rewrite / /index.php?$args;
}
# Forward paths like /js/index.php/x.js to relevant handler
location ~ \.php/ {
rewrite ^(.*\.php)/ $1 last;
}
# Run PHP files using FastCGI
location ~ \.php$ {
try_files $uri $uri/ =404;
expires off; # no need to cache php executable files
#try_files $uri $uri/ @handler;
#fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/hhvm/hhvm.sock;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_keep_conn on; # use persistent connects to backend
fastcgi_param HTTPS $fastcgi_https; # needed for https
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param MAGE_RUN_CODE $storecode;
fastcgi_param MAGE_RUN_TYPE store; ## or website;
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
include fastcgi_params; ## See /etc/nginx/fastcgi_params
}
# [client]store Banner 30m browser expiry
location = /media/bannerslider/s/w/[client]store_au_banner.jpg {
expires 30m;
}
location = /media/bannerslider/s/w/[client]store_us_banner.jpg {
expires 30m; # All other image expires
}
location ~* \.(?:csv|tsv|xml|txt)$ {
expires 1m; # dont cache data feeds
}
location ^~ /blog/ {
proxy_intercept_errors off;
proxy_pass https://blog.[client].com/;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 5d;
log_not_found off;
}
}
# add the other servers here, these only work if matched, they tell the browser to cache this redirect
# once a browser has one of these 301 redirects it will always use it until cache is cleared
server {
server_name www.[client]store.co.uk [client]store.co.uk;
return 301 $scheme://www.[client].com/uk$request_uri;
}
server {
server_name www.[client]store.com.au [client]store.com.au www.[client].com.au [client].com.au;
return 301 $scheme://www.[client].com/au$request_uri;
}
server {
server_name www.[client]store.com [client]store.com www.[client]security.com [client]security.com;
return 301 $scheme://www.[client].com/us$request_uri;
}
}
Some notes on this:
Regarding Stripe, using their latest module version - am I safe in PCI terms to use it with OpenMage, or do I need some asssessor checking my site? Reading their Magento end of life article :
... you’ll be required to provide additional certification of your Magento 1 compensating controls by a PCI Qualified Security Assessor (QSA).
* we have a hacked up index.php for more protection. Can publish a copy of that if people interested, but its a bit ugly
Yes please. The more info we have the better. :)
@ansgarbecker Ouch, if you're not already doing it, hiring a QSA will be a significant additional cost..
What Stripe extension are you using?
I would suggest you have a backup plan for moving to a new processor (that doesn't require a QSA) and then trying the approach of "I am migrating to OpenMage LTS, please support it with your Magento 1 extension" and see if that is accepted. If you're using a third-party extension you could contact the extension developer and ask them to support OpenMage (no changes required, just a pledge really) and then that would be another good argument for OpenMage acceptance by Stripe. If you have a contact at Stripe it would be great to convince them to add OpenMage to the list of supported options for M1 users.
@colinmollenhour we're using their official Stripe/Payment module latest version (v1.1.5 currently), from their download page. (Btw, we're also using your Redis module, thanks hereby!) I will go and ask the Stripe support for accepting OpenMage - nice idea.
It looks like they've scrubbed the M1 extension from their help doc.. Please keep me posted on how it goes with the Stripe conversation or feel free to include me in it directly (colin.mollenhour@openamge.org).
I see you're the author of HeidiSQL which I've used before, so thanks to you as well! :)
Good news from Stripe payments provider:
If you have opted in for OpenMage, then for the foreseeable future, there won't be any PCI compliance concerns as updates will be supplied by both Stripe (for the Stripe for Magento Plugin) and OpenMage (for your Magento website).
@ansgarbecker That's awesome! Unfortunately it looks like they removed the M1 plugin docs from their site, it would be great if they'd restore the old docs and update references to Magento with OpenMage. Can you ask them about that?
EDIT: I see now there is a separate "tab" for Magento 1..
It would be great if there was an official mention of OpenMage on their EOL page or the Magento 1 tab, or if they added a new tab specifically for OpenMage since we are considering removing the Connect manager.. Or maybe this is a strong case for keeping it? (#903)
Hi all. Here is nginx config. I have text replaced my clients name with [client]. You need to review any of the [...] strings and replace for your own use. This config is passing a UK penetration/PCI scan.
# xpractical nginx config, adapted from www.hypernode.com user www-data; # hypernode use 4 here, we have quad core worker_processes 8; pid /var/run/nginx.pid; events { worker_connections 1024; } http { # This uses Nginx’s Map module to set a variable $fastcgi_https. # The variable is set to “off” by default, and “on” for HTTPS connections. We then use the variable to set a FastCGI parameter. map $scheme $fastcgi_https { default off; https on; } # extra logging log_format timed_combined '$remote_addr - $remote_user [$time_local] ' '"$http_x_forwarded_for" ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time $pipe $host $request_uri'; access_log /var/log/nginx/access.log timed_combined; error_log /var/log/nginx/error.log notice; # basic settings disable_symlinks off; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off; server_names_hash_bucket_size 64; # allows big media uploads client_max_body_size 120m; include /etc/nginx/mime.types; default_type application/octet-stream; # SSL global Settings #ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_protocols TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE , dropping TLSv1 for PCI compliance ssl_prefer_server_ciphers on; # pre trustwave PCI check #ssl_ciphers HIGH:!aNULL:!MD5; # post trustwave PCI check ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS; # GeoIP support is included in the Ubuntu 12.04 Nginx. # This enables logging, and the following: # if ($geoip_country_code ~ (CN|ZW) ) { # return 403; # } # geoip_country /usr/share/GeoIP/GeoIP.dat; # CloudFlare GeoIP Mapping 07-10-2016 map $http_cf_ipcountry $country { default us; AU au; NZ au; CA ca; DE uk; GB uk; FR uk; AT uk; BE uk; HR uk; CY uk; CZ uk; DK uk; EE uk; FI uk; GR uk; HU uk; IS uk; IE uk; IT uk; LU uk; MD uk; MC uk; NL uk; NO uk; PL uk; PT uk; RO uk; RU uk; SK uk; SI uk; ES uk; SE uk; CH uk; UA uk; VA uk; } #gzip settings gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_min_length 1100; gzip_types text/plain text/css text/js text/xml text/javascript application/javascript application/x-javascript application/json application/xml application/xml+rss ; # Determine whether a request comes from a human, a search crawler or another bot. # [client] SOE bot is Screaming Frog SEO Spider/7.2 map $http_user_agent $is_non_search_bot { default ''; ~*(Screaming|Frog|dotMailer) ''; ~*(google|pingdom|monitis.com|Zend_Http_Client) ''; ~*(http|bing|crawler|spider|bot|search|ForusP|Wget/|Python-urllib|PHPCrawl|bGenius|LieBaoFast) 'bot'; ~*(Mb2345Browser|zh-CN|MicroMessenger|zh_CN|HUAWEIFRD) 'bot'; } # Rate limit bots (that are not search spiders) to one PHP request per second. # An empty '$limit_bots' would disable rate limiting for this requests # limit_req_zone $is_non_search_bot zone=bots:1m rate=1r/s; limit_req_zone $is_non_search_bot zone=bots:1m rate=6r/m; # need to use x_forward so we dont limit CDN limit_req_zone $http_x_forwarded_for zone=allusers:16m rate=5r/s; limit_req_log_level error; # As this is the first server definition it will be used if there is a good match to server_name OR # if there is no match to any server name server { server_name [client].com, [client]one.org; # if no server name all requests get here #server_name [client].com www.[client].com # single server that listens on both http and https listen 80; listen 443 default ssl; include /var/www/keyconfigfiles/cloudflare.whitelist; #deny all; # go daddy crts, not complete need to generate bundle #ssl_certificate /home/[mag_user]/xp-demo.com/e7a321f0b88a7e89.crt; #ssl_certificate_key /home/[mag_user]/xp-demo.com/xp-demo.key; # may be able to use these SSL should be linked to domain and web server not the hardware or IP #ssl_certificate /var/www/ssl/[client].com.crt; #ssl_certificate_key /var/www/ssl/[client].com.key; ssl_certificate /var/www/ssl2018/[client].com.crt; ssl_certificate_key /var/www/ssl2018/[client].com.key; # openssl req -new -newkey rsa:2048 -nodes -keyout example.key -out example.csr # use the csr request to get the crt files # cat all crt's into one bundle file, make sure the main one is top of list #ssl_certificate /home/[mag_user]/[client]one_org-ssl-bundle.crt; #ssl_certificate_key /home/[mag_user]/[client]one_org.key; # If the site is accessed via mydomain.com # automatically redirect to www.mydomain.com. #if ($host = 'mydomain.com' ) { # rewrite ^/(.*)$ http://www.mydomain.com/$1permanent; #} # if you are using a load balancer uncomment these lines # header from the hardware load balancers #real_ip_header X-Forwarded-For; # trust this header from anything inside the subnet #set_real_ip_from X.X.X.1/24; # the header is a comma-separated list; the left-most IP is the end user #real_ip_recursive on; #listen 10.10.10.11:80; #set_real_ip_from 103.248.190.60; # use this to test pre-production magento folder, danger new code will update database set $my_path var/www/magento; if ($remote_addr ~ "^(110\.175\.187\.117)$" ) { # set $my_path var/www/temp-magento; set $my_path var/www/magento; } root /$my_path; error_page 500 502 503 504 /custom_50x.html; location = /custom_50x.html { root /usr/share/nginx/html; internal; } # magento specific set $storecode "default"; index index.html index.php; autoindex off; # we don’t want users to see files in directories # security if ($http_user_agent = "") { return 444;} # sitemap files location ~ /sitemap.xml|/([a-z][a-z]|[a-z][a-z]-[a-z][a-z])/(.*)sitemap.xml { try_files /sitemaps/$1/sitemap.xml /sitemaps/sitemap.xml =404; } # allow view of sub folders and files here location /downloads/ { autoindex on; } # Denied locations require a "^~" to prevent regexes (such as the PHP handler below) from matching # http://nginx.org/en/docs/http/ngx_http_core_module.html#location location ^~ /app/ { return 403; } location ^~ /shell/ { return 403; } location ^~ /vendor/ { return 403; } location ^~ /includes/ { return 403; } location ^~ /media/downloadable/ { return 403; } location ^~ /pkginfo/ { return 403; } location ^~ /report/config.xml { return 403; } location ^~ /var/ { return 403; } location ^~ /lib/ { return 403; } location ^~ /dev/ { return 403; } location ^~ /RELEASE_NOTES.txt { return 403; } location ^~ /downloader/pearlib { return 403; } location ^~ /downloader/template { return 403; } location ^~ /downloader/Maged { return 403; } location ~* ^/errors/.+\.xml { return 403; } # Extra protection location ~* ^/rss/(order|catalog)/ { return 444; } location ~ /(dev/tests/|errors/local.xml|cron\.php) { deny all; } # note this will stop zip download location ~ ^/.*\.(sh|pl|swp|phar|sql|conf|zip|tar|.+gz)$ { return 444; } location ~ ^/.*\.(sh|pl|swp|phar|sql|conf|tar|.+gz)$ { return 444; } location ~ /\.(svn|git|hg|htpasswd|bash|ssh) { return 444; } location ~* /(lib|media|shell|skin)/.*\.php$ { deny all; } # CVE-2015-3428 / AW_Blog vulnerability # Note the .+ at the start: We want to allow url's like # order=create_date, which would otherwise match. if ($arg_order ~* .+(select|create|insert|update|drop|delete|concat|alter|load)) { return 403; } # Don't skip .thumbs, this is a default directory where Magento places thumbnails # Nginx cannot "not" match something, instead the target is matched with an empty block # http://stackoverflow.com/a/16304073 location ~ /\.thumbs { } # Skip .git, .htpasswd etc location ~ /\. { return 404; } # Disable all methods besides HEAD, GET and POST. if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } # Try static files first, then pass to Magento handler location / { # stop specific IPs until fixed in CDN - added in to CF 24032020 #deny 77.246.157.20; # enable limits limit_req zone=allusers burst=5 nodelay; limit_req zone=bots; # try_files $uri $uri/ @handler; access_log off; # do not log access to static files expires max; # cache static files aggressively } # Pass paths to Magento entry point location @handler { rewrite / /index.php?$args; } # Forward paths like /js/index.php/x.js to relevant handler location ~ \.php/ { rewrite ^(.*\.php)/ $1 last; } # Run PHP files using FastCGI location ~ \.php$ { try_files $uri $uri/ =404; expires off; # no need to cache php executable files #try_files $uri $uri/ @handler; #fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/hhvm/hhvm.sock; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; fastcgi_keep_conn on; # use persistent connects to backend fastcgi_param HTTPS $fastcgi_https; # needed for https fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param MAGE_RUN_CODE $storecode; fastcgi_param MAGE_RUN_TYPE store; ## or website; fastcgi_buffer_size 128k; fastcgi_buffers 256 16k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; include fastcgi_params; ## See /etc/nginx/fastcgi_params } # [client]store Banner 30m browser expiry location = /media/bannerslider/s/w/[client]store_au_banner.jpg { expires 30m; } location = /media/bannerslider/s/w/[client]store_us_banner.jpg { expires 30m; # All other image expires } location ~* \.(?:csv|tsv|xml|txt)$ { expires 1m; # dont cache data feeds } location ^~ /blog/ { proxy_intercept_errors off; proxy_pass https://blog.[client].com/; } location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 5d; log_not_found off; } } # add the other servers here, these only work if matched, they tell the browser to cache this redirect # once a browser has one of these 301 redirects it will always use it until cache is cleared server { server_name www.[client]store.co.uk [client]store.co.uk; return 301 $scheme://www.[client].com/uk$request_uri; } server { server_name www.[client]store.com.au [client]store.com.au www.[client].com.au [client].com.au; return 301 $scheme://www.[client].com/au$request_uri; } server { server_name www.[client]store.com [client]store.com www.[client]security.com [client]security.com; return 301 $scheme://www.[client].com/us$request_uri; } }
I will be review this config and get back to you in the next few days.
Some notes on this:
- the PCI work was trial and error, we did set up, the external audit did penetration/probe testing, we adjusted settings until given a pass
- we used to use hhvm until php 7 turned up. Boy was that a speed advantage back in the php 5 days
- Note that we dont service any traffic unless it comes from CDN, protecting magneto php code from noise can really reduce load on you systems
- we use plenty of rate limiting as this is a well known global site and we get attacks once to twice a month
- you may think its crazy but we use no DB server or load balancers or multiple nginx servers, its just not needed if you setup magneto well, magento is very talkative to the database, see the use of sockets instead of IP. DB and php using sokets on one server is faster that seperate DB and the web server.
- pages have got slower over the years as marketing add more and more stuff
- the rate limiting by x_forward_for is a good trick when using CDN. Be careful to not limit you CDN via the primary IP passed in requests
- we use no varnish and we gave up on magento cache modules, you dont need them. Just use CDN, GC or AWS firewall and a 4-8 core 32gig mem ubuntu server with 100gig SSD hard disk, all image assets are on the SSD
- we have a hacked up index.php for more protection. Can publish a copy of that if people interested, but its a bit ugly
- Here we take care to not allow magneto folders to be visible, we rename the admin path something crazy hard that no one will guess, although I do think there may be some ways to display this path and should put in IP restriction to any admin
- all config is in this file, we probably should break into bits and use site_enabled but if we get an attack late at night tired brains work better on one file
Can you please post your index.php?
Index php interest too ;)
Addition to nginx conf
################# ADMIN AREA PROTECTION NEXT TO OTHER #################
## Best admin area protection
set $ADMIN_URI "mysecretbackend";
## Main Magento @location
## You can also add some rate limiting on backend ... to prevent ddos/brute force
location ~ ^/(index.php/)?$ADMIN_URI {
auth_basic "Private Area";
auth_basic_user_file /var/www/html/$ROOT/.htpasswd;
try_files $uri $uri/ @rewrite;
expires max;
}
################# COMMONS STOPS #################
location ~ rss/(order|catalog) {deny all;}
location ~ /(dev/tests/|errors/local.xml|cron\.php|install\.php) { deny all; }
location ~ ^/([^/])+\.(sh|pl|swp|phar|sql|zip|conf|tar|gz)$ { return 403; }
location ~ /\.(svn|git|hg|htpasswd|bash|ssh) { return 410; }
location ~* /(lib|media|shell|skin)/.*\.php$ { deny all; }
location ~ ^/(app)/ { deny all; }
location ~ ^/.*(modman|myadmin).*$ { return 410; }
location ~ magenotification { return 410; }
################# BLOCK SEO TOOLS #################
# BLOCK SEO TOOLS
# BLock aggresive crawlers
if ($http_user_agent ~* "LieBaoFast|Mb2345Browser|UCBrowser|megaindex|MQQBrowser|mj12bot|mj12|GarlikCrawler") { return 403; }
if ($http_user_agent ~* "ShoppimonAgent|MauiBot|DomainCrawler|MJ12bot|SemrushBot|OpenLinkProfiler|rogerbot|exabot|dotbot|gigabot|sitebot|spbot|prijsbest|seokicks") { return 403; }
# BLOCK BOTS AND CRAWLERS THAT MAKE NO SENSE
# IF ITS NOT A HUMAN AND NOT GOOGLE OR BING THEN BLOCK THEM
if ($http_user_agent ~* "SpiderLing|360Spider|VelenPublicWebCrawler|Baiduspider|MegaIndex|Yahoo|YandexBot|Barkrowler|ZoominfoBot|MJ12bot|Cliqzbot|DotBot|YandexBot|SearchAtlas") { return 403; }
if ($http_user_agent ~* "Go-http-client|GuzzleHttp|Slackbot|SeznamBot|coccocbot|SemrushBot|Sogou|MojeekBot|DomainStatsBot|prijsbest|GrapeshotCrawler") { return 403; }
if ($http_user_agent ~* "Vagabondo|Bilbo|MegaIndex|GrapeshotCrawler|BLEXBot|rc-crawler|SearchAtlas|linkfluence|Internet-structure-research") { return 403; }
if ($http_user_agent ~* "RU_Bot|MojeekBot|SE Ranking Gentle|MixnodeCache|bidswitchbot|niocBot|SeznamBot|YandexImages| oBot/|Konturbot|ZoomBot|YandexMetrika|Cincraw") { return 403; }
if ($http_user_agent ~* "Linkbot|YandexMobileBot|CCBot|Sidetrade|TweetmemeBot") { return 403; }
# if ($http_user_agent ~* "AhrefsBot|AhrefsSiteAudit") { return 403; }
################# RATE LIMIT DYNAMIC URLS #################
location ~ ^/(hsapi|wishlist|customer|catalogsearch|newsletter|sales/guest/view|contacts/index/post|review/product/post|(fire|one.+)?checkout)/ {
limit_req zone=goeasy burst=6;
limit_req_status 429;
# if ($http_user_agent ~* "Baiduspider|AdsBot|Google|DotBot|bingbot|Yahoo|YandexBot") { return 410; }
try_files $uri $uri/ @rewrite;
}
################# STOP HACKERS LOOKING FOR LOOP HOLES #################
# HALT TO HACKERS https://gwillem.gitlab.io/2018/10/23/magecart-extension-0days/
location ~* ^/index.php/(quickshop|giftcards|quickview|catalog/product_frontend_action|madecache|freegift|qquoteadv|ajaxproducts|minifilterproducts|advancedreports|bssreorderproduct|rewards|gwishlist|aheadmetrics|customgrid|tabshome|vendors|multidealpro|layaway|simplebundle|netgocust|prescription|ajax/Showroom)/.*$ {
deny all;
}
## Block some common admin url searchers
## Would rather send this to fw ban fail2ban; you kind of know they are wrong clients
location ~* ^(/en|/fr|/nl|/de)?/(BackgroundTask|M2ePro|bannerpopup|admin|beheer|memberadmin|superadmin|admin2016|admin2014|admin_area|administratorlogin|admin1|ctrl_page|admin111|admin123|admin3|admin2|adminlogin|admin2010|admin2012|admin2013|admin2015|panel-administracion|moderator|myadmin|admin5|admin4|adminsecret|adminarea)/?.*$ {
return 444;
}
## Would rather send this to fw ban fail2ban; you kind of know they are wrong clients
location ~* ^(/en|/fr|/nl|/de)?/(advradmin|forum_admin|blog_admin|rewardsadmin|rma_admin|banner/admin|amflags/admin|amshopby/admin|affiliateplusa|amacart/adminh|searchindex/adm|wp_usersbackup|wp_users_backu|site_database|marketsuite/adm|affiliatepluss|amnotfound/adm|customerprices|amogrid/admi|amoaction/admi|amfile/admi|ammethods/admi|searchsphinx/adm|orderattach/adm|megamenuadmin|exporter/admin|imagegallery/adm|igallery/admin|attributemanag|amcustomerattr|vendor/phpunit|presets-admin|slocator/adm|profitlossrepo|mageworx/downl|ecfplus/admi) {
return 444;
}
################# HALT TO OLD ADMIN URLS FROM THE PAST #################
location ~* ^/(oldadmin1|oldadmin2) { deny all; }
###### OPTIONAL: START Blocks good bots that just crawl too much ######
# Step 1 identify the good bots
# CCBOt is open source bot
if ($http_user_agent ~* "Googlebot|bingbot|MegaIndex|Yahoo|YandexBot") { set $is_goodbot O; }
# Step 2 identify the actions we need to block for these bots
# All Magento attributes that can be filtered paste them here
if ($args ~ ^(bowtie_type|color|cost|country_of_manufacture|custom_comment|custom_design|custom_design_from|custom_design_to|custom_gender|custom_layout_update|delivery_period|description|discount_option|discount_selector|ebizmarts_mark_visited|gallery|gift_message_available|google_product_category|group_price|gr_ean|gr_valid_through|image|is_recurring|manufacturer|materiaal_type|media_gallery|meta_description|meta_keyword|meta_title|msrp|msrp_display_actual_price_type|msrp_enabled|naam_merchandiser|name|news_from_date|news_to_date|occasion|options_container|pack_multiplier|pack_size|page_layout|postnl_allow_delivery_days|postnl_allow_delivery_options|postnl_allow_pakje_gemak|postnl_allow_pakketautomaat|postnl_allow_timeframes|postnl_max_qty_for_buspakje|postnl_product_parcel_count|postnl_product_type|postnl_product_volume|postnl_shipping_duration|preorder_cart_label|preorder_note|price|price_view|products_in_pack|product_collection|product_discount|product_mainmaterial|product_minqty|product_modelname|product_noslosseas|product_overlay|product_popup|product_season|product_sluiting|product_taxonomy|product_width|recurring_profile|rw_google_base_12_digit_sku|rw_google_base_product_categ|rw_google_base_product_type|rw_google_base_skip_submi|searchindex_weight|shirt_boord|shirt_boordkleur|shirt_colours|shirt_coupenaad|shirt_cuff|shirt_dessin|shirt_fit|shirt_generalfit|shirt_iron|shirt_length|shirt_mill|shirt_neck|shirt_pocket|shirt_size|shirt_sleevelength|shirt_stof|shirt_stretch|shirt_subtype|shirt_tapekleur|shirt_threadcount|shirt_twoply|shirt_weving|short_description|sku|small_image|soort_shirt|special_from_date|special_price|special_to_date|status|strikmethode|tax_class_id|thumbnail|tier_price|tradetracker_exclude|type_shirt|underwear_length|url_key|visibility|washing_instructions|weight)=.+) { set $bot_layered_nav "${is_goodbot}N"; }
# Sorting listing ordering
if ($args ~ ^(dir|order|limit|sort)=.+) { set $bot_layered_nav "${is_goodbot}N"; }
# Block google searching all the time
if ($args ~ ^(q)=.+) { set $bot_layered_nav "${is_goodbot}N"; }
# No need to index the checkout checkout/login/account and such
if ($request_uri ~ 'checkout|account|login|cart|onepage|success') { set $bot_layered_nav "${is_goodbot}N"; }
# Step 3 if both step 1 and 2 are true then block the bot and send 410
if ($bot_layered_nav = ON) { return 410; }
###### END Blocks good bots that just crawl too much ######
################# NOPE WE ARE NOT WORDPRESS #################
## Wordpress files and locations protection
location ~ /wp-config\.php { deny all; }
location ~ /wp-includes/(.*)\.php { deny all; }
location ~ /wp-admin/includes(.*)$ { deny all; }
location ~ /xmlrpc\.php { deny all; }
location ~ /wp-content/uploads/(.*)\.php(.?) { deny all; }
################# BLOCK MYSQL #################
## Block MYSQL
if ($request_uri ~ '.*select.*from.*where.*') { return 444; }
if ($request_uri ~ '.*update.*set.*where.*') { return 444; }
if ($request_uri ~ '.*select.*sleep.*') { return 444; }
if ($request_uri ~ '.*insert into.*values.*') { return 444; }
@Adel-Magebinary and @seansan please see the PR #1209 which proposes a simple nginx config as the default dev environment. It is not meant to be production-ready per-se but I would like to create a simple "reference" config that users can use as a starting point for replacing Apache.
This config uses a very simple and secure technique for controlling what static files are made public using a separate "/pub" directory rather than using the Magento root for static files. It also restricts all PHP requests to just index.php rather than allowing arbitrary fastcgi script filenames (avoids using $fastcgi_script_name
). If your deployment's source code is write-protected from the web server user it should make it near impossible to ever run unauthorized PHP code without the entire server first getting hacked.
Your additional WAF-like rules are a great reference, perhaps these could be added to "WAF rules cookbook" wiki page so users can pick and choose and customize easily?
https://github.com/OpenMage/magento-lts/pull/1209/files#diff-9e3923f9fdb3de5d1849d1eca7869eb6R10
Looks good
I would add at least commented out section for htaccess protection of admin (entrypoint for most if not all hackers)
And advise to review this: https://github.com/magenx/Magento-nginx-config
On Mon, Sep 28, 2020 at 8:44 PM Colin Mollenhour notifications@github.com wrote:
@Adel-Magebinary https://github.com/Adel-Magebinary and @seansan https://github.com/seansan please see the PR #1209 https://github.com/OpenMage/magento-lts/pull/1209 which proposes a simple nginx config as the default dev environment. It is not meant to be production-ready per-se but I would like to create a simple "reference" config that users can use as a starting point for replacing Apache.
This config uses a very simple and secure technique for controlling what static files are made public using a separate "/pub" directory rather than using the Magento root for static files. It also restricts all PHP requests to just index.php rather than allowing arbitrary fastcgi script filenames (avoids using $fastcgi_script_name). If your deployment's source code is write-protected from the web server user it should make it near impossible to ever run unauthorized PHP code without the entire server first getting hacked.
Your additional WAF-like rules are a great reference, perhaps these could be added to "WAF rules cookbook" wiki page so users can pick and choose and customize easily?
https://github.com/OpenMage/magento-lts/pull/1209/files#diff-9e3923f9fdb3de5d1849d1eca7869eb6R10
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/OpenMage/magento-lts/issues/975#issuecomment-700213614, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE7I25OUONHI2EUNK6SLJ3SIDKQXANCNFSM4NANNIPQ .
Thanks @seansan I'll check that out and consider adding htpasswd to the default.
Looked at the index.php again as requested, can't really send as it's too client-specific and Cloudflare specific, you can switch between 15+ store views on this site, but we try to send new users to the most logical store. Most of the protection is done in Nginx, especially the include white CDN white list and then deny all other. The protection in index.php is about the final check of all _SERVER variables and avoiding any rubbish calls to Mage::run
What it does:
looks for a cookie we set using Cloudflare
if (isset ($_SERVER["HTTP_CF_IPCOUNTRY"])) $country_code = $_SERVER["HTTP_CF_IPCOUNTRY"];
sets cookie based on this or some other URL rules ( like a specific store path call )
exits if we cant work out rule or there is blanks / junk / !isset for $_SERVER['REQUEST_URI'] or $_SERVER['HTTP_HOST'] etc
finally does very strict and specific store call stuff ( including some admin rules ) like:
if ($country_code == "US") {
if ( !$store_call ) {
$_SERVER['REQUEST_URI'] = '/us' . $_SERVER['REQUEST_URI'];
}
Mage::run('us','store');
}
elseif (in_array($country_code,$auArray)){
if ( !$store_call ) {
$_SERVER['REQUEST_URI'] = '/au' . $_SERVER['REQUEST_URI'];
}
Mage::run('au','store');
}
... etc ...
PCI and the future
LTS is a great product, super stable and there are 10’s of thousands of businesses that don’t have the funds, time or focus to convert to magento2 in these troubled times. My view is 2021/22 is going to be very tough for small/medium businesses. My idea is to put together a project and offer that will “destroy” the arguments that magento1 is dead or non PCI compliant.
Rough ideas for discussion to agree an “LTS 2030” plan
Some background info….
PCI DSS ( Data Security Standard ) considers merchants to be:
Level 1
* more than 6 million Visa, Mastercard, or Discover transactions annually via any channel
* more than 2.5 million American Express transactions annually
* more than 1 million JCB transactions annually
* have suffered a data breach or cyberattack that resulted in cardholder data being compromised
* have been identified by another card issuer as Level 1
Validation Requirements:
Level 2
* between 1 million and 6 million Visa, Mastercard, or Discover transactions per year via any channel
* between 50,000 to 2.5 million American Express transactions annually
* less than 1 million JCB transactions annually
Validation Requirements:
Level 3
* between 20,000 and 1 million Visa e-commerce transactions annually
* processing 20,000 Mastercard e-commerce transactions annually, but less than or equal to 1 million total Mastercard transactions annually
* process 20,000 to 1 million Discover card-not-present only transactions annually
* Less than 50,000 American Express transactions
Validation Requirements:
Level 4
* Merchants processing less than 20,000 Visa or Mastercard e-commerce transactions annually
* All other merchants processing up to 1 million Visa or Mastercard transactions annually
Validation Requirements:
What does PayPal say:
Requirement 6 of the PCI DSS requires merchants to "develop and maintain secure systems and applications by installing applicable vendor-supplied security patches." Without future security patches, Magento 1 merchants will no longer be able to meet this requirement, which could result in costly and time-consuming remediation.
This is not a PayPal-specific requirement. PCI DSS requirements apply to your integrations with card payment brands, such as Visa, MasterCard, American Express, Discover, JCB, and any other payment processor on the Magento 1 platform. Visa has stressed that urgent action is required for merchants to migrate from Magento 1 and advised merchants to be aware of their responsibilities in securing their environment to help prevent the loss of payment card data.
Although PCI Compliancy can be acquired by self assessment
and it is not "really" required in Europe (where I am from) becuase of GDPR regulations, and mainly only for CreditCard processing (if it happens on your site and not the PSPs site)
Howvever it would be good to make a statement on this and publically communicate LTS supports PCI Compliancy ...
https://docs.magento.com/m1/ee/user_guide/store-operations/compliance-pci.html