Mail hacked | Are you keeping a database of each Install / Update with IP/ Domain?

Hi !
Last week I installed a new v5, and generated an app password for my email.

I didn’t noticed it but the very next day on my sent email folder was an email sent with the IP of my instance and my email details.

Again same thing happened few days after.
And last night I had to deal with more than 857 phishing emails sent from my email.

Fortunately I noticed it by bounced emails.

So, I now secured my install (thank you nginx for regenerating a default where the http point to my IP :face_with_symbols_over_mouth:) and generated a new app password.

After investigation, it appears that laravel have a major security flaw. But I secured it.

My Invoice Ninja v5 is not indexed by any search engine, but they hacked into the very next day after the installation.

So now, my question is very simple :

ARE YOU KEEPING ANY RECORD WITH IP / DOMAIN OF EACH INSTALL OR UPDATE ???

IF SO, DISCLOSE THAT YOUR DATABASE CAN BE READ OR HAVE BEEN HACKED ! IT IS IMPOSSIBLE FOR THEM TO KNOW I MADE AN INSTALL SO FAST !

@Charles.k

The short answer is no. We don’t store that kind of data.

The longer answer is on the internet there are bad actors swarming every IP address known with scripts looking for vulnerabilities like this where the .env has been inadvertently exposed.

This is a new IP generated for a new instance by Google cloud, so it’s not a “known IP with script”.

So, well, my best advice is to protect the .env by doing the following.

IF USING APACHE2 :
Add the following on the .access

<Files .env>
order allow,deny
Deny from all
</Files>

IF USING NGINX

Remove the file “default” with the following command

sudo rm /etc/nginx/sites-available/default

And link your conf file

sudo ln -s /etc/nginx/sites-available/your_ninja_domain.com.conf /etc/nginx/sites-enabled/your_ninja_domain.com.conf

The best method to protect the .env file is by never exposing the document root where the .env lives.
You should always use the doc root of /public

listen 80;
server_name invoiceninja.test;
root /var/www/invoiceninja/public;
index index.php index.html index.htm;
client_max_body_size 20M;

There are many reasons for this; the .env is one, but you are also exposing the vendor/ directory which is another attack vector that could be used against you.

Of course, it actually is already set like that, and I used certbot to use port 443 with ssl certs instead of port 80.

But the pesky default of NGINX point to the root instead of the public, I deleted it at first but for some unknown reasons, it got regenerated which exposed my .env

I also redirected the http to https, but because of the default file of NGINX , if they pinged my domain, then they got the IP and therfore could get the .env by simply going to

http://[my-ip-address]/.env

You can also consider Cloudflare DNS. I know with certbot, you will install a certbot cloudflare ddns extension, and edit your certbot scripts for it, but it is worth it. Cloudflare for free proxies all the 443 traffic to your server, and intercepts and blocks anyone attempting to connect to your server https with direct IP. Even running wget https://((ip address))/.env would return an SSL error.

Hi Charles.k, Do you remember how you fixed this? I have been trying to fix for a few days without resolve.

I was testing with my self-hosted InvoiceNinja instance a bit and I was a bit confused that I got a HTTP200 when trying https://domain.tld/.env. It was an empty Zero Byte document, but I still got a HTTP200 and I do not know why this was not a HTTP4xx.

Well, I modified my DOCKER Ngnix vHost config as described below:

server {
    listen 80 default_server;
    server_name _;
    
    server_tokens off;
    
    client_max_body_size 100M;

    root /var/www/app/public/;
    index index.php;

    ### DENY DOTFILES
    location ~ ^/\.(.*) {
        deny all;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass invoiceninja:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
    }
}

For the time being, I’ll keep this config as long as it has no side effects to IN at all.

1 Like