Product Development February 27, 2020

My web app was hacked today :( . How to prevent this in the future?

Nicolas Granja @ngranja19

Today my web app ViralQuotes was hacked. My DB was erased, instead, there was a new table called Warning with a message 0.08 BTC to recover my DB.

After 5 hours I was able to rebuild my DB, but unluckily I lost all my historical data within my 400+ users data among them.

Of course, there are some lessons learned about it:

  1. Don't forget to set up regular backups.
    I know, I was really silly for not doing it, but I never thought that someone would hack my insignificant website. So, stop what you are doing, and go and set up some way to back up your DBs and significant files at least once a day. Some providers offer it for a few extra bucks a month.
    Don't be like me, maybe your product is not generating thousands of dollars and you think that no one will waste his time hacking your site, but remember that is important for you and that's is enough.

  2. After looking into how that could happen, I realized that I pushed to my server my .env file with all the database credentials in it, which Is pretty simple access to it especially if you use Laravel.
    I found out that is a pretty common mistake, If you google DB_USERNAME filetype:env you will find thousands of Laravel env files exposed
    Therefore, remember to actually set your variables from the .env file as environmental variables in your server and destroy any .env file that is around there.

For sure there are more lessons to learn about this, and maybe is a good opportunity for everyone to share some bad experience they had, and how to prevent them in the future.

Cheers,

  1. 28

    I would:
    1.) Setup a cron/bash script that every 5 minutes simply loops through and deletes any non-web server files. If you're not accepting file uploads then there should never be anything except .php, .css. .js, etc files.
    2.) You could actually maintain a list of "acceptable files" and delete any file not on the list. That way if someone finds a way to get a malicious file onto your server its deleted shortly after.
    3.) You could also create a checksum of your current production app, and every 5 minutes check the current checksum against the approved. That way you would almost immediately know that a file has been changed on your server.
    3.) Never store credentials in git/repo/backup.
    4.) When you do setup backups set encryption of the backup automatically, before it leaves the server. Imagine if someone got one of your backups and it was unencrypted, you might have a data breach and never know it.
    5.) Use different DB servers and accounts for dev and production so even if the dev credentials do get exposed then the production DB is not exposed.
    6.) Setup a bash script that sends an email upon every successful SSH/FTP/admin login. That is the first (other than direct DB access) step a hacker takes so getting an email notification it becomes very easy to get an email and think to yourself "that's not me, therefore I've been hacked" and you can shut your server down.
    7.) Disable remote DB access unless its necessary. On most DBs you can allow local access only and if the DB and web server are running on the same server then there should be no need to login remotely.
    8.) Create separate DB permissions for "read operations" and "write operations" to separate lower risk and higher risk operations. You can even go further and create permissions for lower risk operations (write the event log) and higher risk operations (update user account).
    9.) Of course your passwords are all hashed right? Never store plain text user passwords anywhere.
    10.) In fact, I've started encrypting high-risk user data such as email and home address and birthdate since they are rarely assessed and do not require bulk access.

    I can probably think of more, that's just off the top of my head.

    1. 2

      Great measures. Should I worry too if I use firebase ? As long as my credentials are safe a cloud provider takes care of everything right ?

      1. 3

        Yes and no...
        Cloud storage has its own risks: https://www.google.com/amp/s/www.wired.com/story/capital-one-paige-thompson-case-hacking-spree/amp

        They, generally handle the physical server security. It's still up to you to segment permissions and such. Firebase is a unique case because user authentication can be handled in Firebase and it seems like it's possible to have client devices connecting directly to the DB. I don't know it well enough to comment.
        I can however speak to MySQL, MariaDB, PostgreSQL, Microsoft, Mongo, etc. In all of those, traditionally self hosted, databases you can associate the app user with a specific IP. So, for example, write_user@localhost means that not only does the username/pass have to be correct but connections can only originate from localhost.
        Certainly an added measure of security.

      2. 2

        Yes they take care. But in case of Firebase you should focus on the proper rules for both firestore and file store. There are a lot of app with write privilege for the whole database out there. Also application level security is your responsibility always and backup is the part of it.

      3. 1

        Second this — would very much like to know about Firebase. Does Google take good care of their cloud servers' security?

        1. 1

          @stnkvcs / @aekiro

          do you back up your Firebase database?
          is it Firestore or Realtime db?
          How often do you backup?

          (Apologies for all the questions but I'm thinking of building a Firestore database backup utility and trying to validate the idea here)

          1. 2

            Yeah, me neither, just trying to find out the pros and cons

          2. 1

            I don't use Firebase yet.

    2. 2

      I also generally run a "forbidden dir" that is not web accessible and that's where all settings file, classes, etc are stored. For simple math you can do $_SERVER['DOCUMENT_ROOT']/../forb_dir. That too reduces risk since the only files in the webroot are only ever files that are supposed to be accessible.

      1. 1

        Yeap something like this is what I need to do. I have all my Laravel files in a directory that could be accessed by the web and that's my main issue. The thing is that it will take me a lo of time to change all the files to a safe directory and keep everything working, but for sure it'll worth it.

    3. 1

      Super insightful, thank you!

    4. 1

      Wow thanks! There are really good ideas here. I'm taking note to implement some of them.
      An yes the password are hashed so no worries about that.

      1. 2

        Genuinely happy to help. That's why I joined this community.

        1. 1

          Thank you for posting it. This was really valuable.

      2. 1

        Well depending on the hash it is a worry since it might be the primary target of the attacker to get a list of password hash and than crack it. Your users also should get notified since if the use the same password elsewhere that they are at risk.

        1. 1

          I like to hash passwords with a unique salt(s). Using something like the date the user created their account and/or the user ID and/or the users email results in a different salt for every password. Not perfect but going to significantly slow down a brute force attack.

          1. 2

            Just use something like bcrypt, which hashes each password a bunch of times with a totally random salt.

            1. 2

              Underrated post. Every indie hacker should read https://codahale.com/how-to-safely-store-a-password/

  2. 5

    the google search blew my mind!

    1. 2

      Then this will blow your mind even more → https://www.exploit-db.com/google-hacking-database

      I wrote a simple article many years ago on the topic → https://medium.com/@deadcoder0904/google-hacking-database-4eda32dc2a6a

    2. 1

      Yup - I just found and ENV file for a company website and it has their PayPal username and password on it.

  3. 4

    This is very unfortunate. Drills down on the point that hackers aren't essentially looking out for hugely prosperous online businesses. Startups and small businesses are equally at risk. It's very important to keep regular backups and test your web apps every once in a while.

  4. 3

    My condolences, this sucks!

    Please note that you are very likely required by law to notify your users about this data breach (depending on what data was leaked).
    The following page gives a bit additional information: https://www.ncsl.org/research/telecommunications-and-information-technology/security-breach-notification-laws.aspx

    1. 2

      thanks. Oh i didn't kno that, but how I should notice my users if I don't have their contact info?

      1. 1

        Probably the best you can do is put up something obvious on your homepage so the next time they try to use it they'll see it.

  5. 3

    Recently, this happens quite often! My condolence and thank you for sharing such a useful info.

    1. 1

      your welcome, I hope this help other people to not commit the same mistakes I did.

  6. 2

    Piggybacking on the thread somewhat: does anyone know of any good services/tools/people/etc. who could look at an app (the whole thing- framework/code configuration, server configuration, database configuration, etc.) and point-out holes security? It seems like a productized consulting service in this space could be a huge opportunity and provide a truly valuable service.

    1. 1

      One example: https://fugue.co I saw a demo by them today. Scans for various AWS misconfigurations. Useful free tier available.

  7. 2

    Hi, I think you should focus on three things:

    1- Don't make your app files accessible! this is the main mistake I see in PHP apps, you should only allow access to the main router (index.php or something) and static files in a certain folder, nothing more than that, normally the index.php is in a "public" folder or something like that, so check your nginx/apache config to make sure that only "public" is publicly accessible :P and have in mind that any file in that folder will be publicly accessible, you can also disable access to files starting with dot (.) (like .git, .env, .bash_profile, etc) with one line of nginx config:

    location ~ /\. { access_log denied; log_not_found off; deny all; }

    The .env file is not an issue, people could also access other files and gain access to confidential information, the typical issue is exposing your git repo (.git folder), so people can directly read all your source code (!). This is just another example of why you should NOT expose any app file, deleting your .env file is not the solution.

    2- Your database should not be accessible from everywhere, even if I don't know the password if you expose your database server to the internet it's a time bomb, people will be trying passwords and zero-day exploits all the time while you sleep. If you are using a serious database as postgresql, even having access to the database port is not enough, because every client IP (your app servers) need to be specified explicitly for connecting, for example:

    # TYPE DATABASE USER ADDRESS METHOD
    host my_database. my_user 192.168.93.0/24 (your app server ip) md5

    Most VPS providers as DO, Linode, Vultr, etc, support firewalls and it's super easy to block access to public ports or grant access to only a subset of ips.

    3- As you have said, do backups regularly, in some providers as DigitalOcean or Linode is just clicking a checkbox, and you have a daily/weekly snapshot of everything.

  8. 1
    1. In the Laravel you can add exclusions for push for .env file ;) and probably you know it.
    2. You can add double authentication which is a bit of a pain if app is in a developer mode, but once it's tested and hit production mode, then it's quite acceptable. You can use Google Authenticator, or others if you like.

    Same thing for Wordpress, this one out of the box is few times worst then Laravel ;) by the way.

  9. 1

    one way to avoid this is running your code in docker container. imo it's harder to break in and grab credentials.

    and instead of .env file i pass env variables to container

    1. 1

      When I deployed my last web app I used 3 docker containers to run it. Guess who's database got hacked because they never changed the default admin password since they thought it was running locally and not accessible over the net :)

      1. 1

        rookie mistakes like that will always give you headaches 😋

  10. 1

    I found out that is a pretty common mistake, If you google DB_USERNAME filetype:env you will find thousands of Laravel env files exposed

    I checked it. OMG

    1. 1

      yeap is crazy right?

      1. 1

        It IS.

  11. 1

    Dude, all your Laravel app is still accessible via web ´https://viralquotesonline.com/laravel/´ you need to change that right now, if you are using Laravel for your API move it to a subdomain and you should set the public folder as your website root, you are using it wrong.

    From the docs

    Public Directory
    After installing Laravel, you should configure your web server's document / web root to be the public directory. The index.php in this directory serves as the front controller for all HTTP requests entering your application.

    1. 1

      done fixed, thanks men!

  12. 1

    I got hacked so many times I became numb to it.
    I did learn from them and improve my security but it's never completely avoidable, the target is to make it more expensive for them.

    Of course having my main issue is I need to have a hot bitcoin wallet to offer my apps at kriptode.com but nonetheless any web app should be very cautious.

    money is digital and hackers galore.

  13. 1

    Any indie hacker doing anything with user passwords needs to read How To Safely Store a Password. Seriously, drop what you're doing right now and go read it! (It's short).

  14. 1

    Sorry bud - terrible thing to happen!

  15. 1

    Even though I have no useful piece of information to give you, I think you already receive some great advice already, I'm sorry that this happened to you. I wish you well!

  16. 1

    I'm sorry to hear that Nicolas, and thanks for being open and honest about your mistakes.

    I hope you are able to recover our business if not your data

    1. 1

      Thanks!

  17. 1

    This sucks and I’m sorry it happened to you.

    However I want defend Laravel somewhat and just say that this isn’t a Laravel issue - it’s human error and can happen with any programming language or framework.

    1. 1

      I agree, I'm not saying us Laravel fault. Is my fault for using it properly

  18. 1

    I'm curious, how did they get access to the env file in the first place? Did you had public access for them?

    1. 2

      Yeap :facepalm:. Is embarrassing but I didn't know that. Anyways, we should.not have .env files on the server.

      1. 1

        Are you saying .env was in your public folder (http://domain.com/.env)

        I would think if you store it outside of public html folder then it wouldn't be an issue

        1. 2

          Sounds to me more like it was in a public GitHub repo.

          1. 1

            nope, it was like blaso333 said. Yeap there are several mistakes here, and is embarrassing actually haha, but you know I was experimenting with Laravel for the first time with this project so I did a lot of mistakes. But if you did the google search that I mentioned you could see that I'm not the only one so a bunch of people has their product on risk.

            1. 1

              where was it hosted?

              1. 1

                Digital ocean.

  19. 0

    Honestly, the simplest way to avoid it is to use a firewall on the database machine, allowing only your server to have access to it.