skip to Main Content

I have a node.js environment deployed using AWS Elastic Beanstalk on an Apache server. I have run a PCI scan on the environment and I’m getting 2 failures:

  • Apache ServerTokens Information Disclosure
  • Web Server HTTP Header Information Disclosure

Naturally I’m thinking I need to update the httpd.conf file with the following:

ServerSignature Off
ServerTokens Prod

However, given the nature of Elastic Beanstalk and Elastic Load Balancers, as soon as the environment scales, adds new servers, reboots etc the instance config will be overwritten.

I have also tried putting the following into an .htaccess file:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

# Security hardening for PCI
Options -Indexes
ServerSignature Off

# Dissallow iFrame usage outside of loylap.com for PCI Security Scan
Header set X-Frame-Options SAMEORIGIN

On the node js side I use the “helmet” package to apply some security measures, I also use the “express-force-https” package to ensure the application is enforcing https. However, these only seem to be taking effect after the Express application is initiated and after the redirect.

I have Elastic Load Balancer listeners set up for both HTTP (port 80) and HTTPS (port 443), however the HTTP requests are immediately routed to HTTPS.

When I run the following curl command:

curl -I https://myenvironment.com --head

I get an acceptable response with the following line:

Server: Apache

However when I run the same request on the http endpoint (i.e. before redirects etc):

curl -I http://myenvironment.com --head

I get a response that discloses more information about my server than it should, and hence the PCI failure:

Server: Apache/2.4.34 (Amazon)

How can I force my environment to restrict the http header response on HTTP as well as HTTPS?

4

Answers


  1. Chosen as BEST ANSWER

    Credit to @stdunbar for leading me to the correct solution here using ebextensions.

    The solution worked for me as follows:

    1. Create a file in the project root called .ebextensions/01_server_hardening.config
    2. Add the following content to the file:
    files:
      "/etc/httpd/conf.d/03_server_hardening.conf":
        mode: "000644"
        owner: root
        group: root
        content: |
          ServerSignature Off
          ServerTokens Prod
    
    container_commands:
      01_reload_httpd:
        command: "sudo service httpd reload"

    (Note: the indentation is important in this YAML file - 2 spaces rather than tabs in the above code).

    During elastic beanstalk deployment, that will create a new conf file in /etc/httpd/conf.d folder which is set up to extend the httpd.conf settings in ELB by default.

    The content manually turns off the ServerSignature and sets the ServerTokens to Prod, achieving the PCI standard.

    Running the container command forces a httpd reboot (for this particular version of Amazon linux - ubuntu and other versions would require their own standard reload).

    After deploying the new commands to my EB environment, my curl commands run as expected on HTTP and HTTPS.


  2. You will ultimately need to implement some ebextensions to have this change applied to each of your Beanstalk instances. This is a mechanism that allows you to create one or more files that are run during the initialization of the beanstalk. I have an older one that I have not tested in your exact situation but it does the HTTP->HTTPS rewrite like you’re showing. It was used in the Tomcat Elastic Beanstalk type – different environments may use different configurations. Mine looks like:

    files:
        "/tmp/00_application.conf":
            mode: "000644"
            owner: root
            group: root
            content: |
                <VirtualHost *:80>    
                  RewriteEngine On
                  RewriteCond %{HTTP:X-Forwarded-Proto} !https
                  RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R,L]
                </VirtualHost>
    
    container_commands:
        01_enable_rewrite:
            command: "echo 'LoadModule rewrite_module modules/mod_rewrite.so' >> /etc/httpd/conf/httpd.conf"
    
        02_cp_application_conf:
            command: "cp /tmp/00_application.conf /etc/httpd/conf.d/elasticbeanstalk/00_application.conf"
    

    Again, this is a bit older and has not been tested for your exact use case but hopefully it can get you started.

    This will need to be packaged with your deployment – i.e. in Java a .jar or .war or a .zip in other environments. Take a look at the documentation link to learn more about deployments.

    Login or Signup to reply.
  3. An easier and better solution exists now.
    The folder /etc/httpd/conf.d/elasticbeanstalk is deleted when the built-in application server is restarted (e.g. when using EB with built-in Tomcat). Since .ebextensions are not re-run the above solution stop working.

    This is only the case when the application server is restarted (through e.g. Lambda or the Elastic Beanstalk web-console). If the EC2 instance is restarted this is not an issue.

    The solution is to place a .conf file in a sub-folder in the .ebextensions.

    • .ebextensions
      • httpd
        • conf.d
          • name_of_your_choosing.conf

    Content of the file is the same as the output of the .ebextensions above, e.g.

    ServerSignature Off
    ServerTokens Prod
    

    This solution will survive a restart of the application server and is much easier to create and manage.

    Login or Signup to reply.
  4. There is a little change in configuration file path as AWS has introduced Amazon Linux 2

    .ebextentions                                                                                                                                                                 
    .platform                            
       httpd
         conf.d
            whateverFilenameyouwant.conf
    

    in .platform/httpd/conf.d/whatever-File-NameYouWant.conf

    add below two line

    ServerSignature Off
    ServerTokens Prod
    

    Above is for Apache
    Since AWS by default uses nginx for reverse proxy
    replace httpd to nginx it should work

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search