HTTPS needed for an internal web app, which is accessible only when device is connected through corporate VPN?

Hello!

Hope I’m asking this at the right place / sub

For a bit of a context. I’m db sysadmin for 1.5 years, I work in an insurance. Out of interest, I started learning programming in C++ some 5 months ago. Quite recently I started learning JavaScript, Node, HTML, CSS, React… So, bare in mind I’m quite new, but very curious :slight_smile:

About 4 months ago, my company decided to incorporate hybrid work. However, you need to send an email to your manager for an approval, for each day you’d want to work from home. As you can imagine, it’s a hassle, especially for managers with bigger teams

Since I’m eyeing the dev position in my company, I decided to make a web app where you can send your WFH requests. Also, where manager can approve or disapprove requests over his dashboard. This is my first serious project I’m attempting

What I have so far is the fully working LDAP Auth. I’m using Express + Passport and I’ve also set up Passport sessions.

What works so far:

  • - User can use his existing Active Directory credentials to log in. If he logs in for the first time, I use data from LDAP reponse to register that user automatically in my database. I also set up manager - user relationship in another table.
  • - After registration, OR if user already exists in my database, passport session gets created, is saved in my db and user gets a cookie :slight_smile:

- Now, on to my question from the title: I’m concerned with security. I’m using LDAP auth, parameters in my db queries to prevent SQL injections… Now the http / https part:

  • - The thing is - both Node server and frontend would be hosted inside a VPN, not available to public. User could only access the frontend when connected to a company LAN (from a device trusted in AD) or if he’s connected to corporate VPN (over Cisco Anyconnect client, for instance). Otherwise, the IP address of the client would not be accessible.

Would you consider safe if I’d send session cookies over an http, but inside a trusted VPN network only? Out of sensitive data, in my database I store 1. user sAMAccountname, 2. email, 3. managers sAMAccountname. That’s all.

However, I’m mostly concerned with the following scenario - I’m in a caffe on a public wifi. I connect to VPN, open my React frontend, send AD username / password over my login form as http POST json. Is that username / password exposed to potential wifi sniffing, since VPN is already enrcypting all traffic?

Would a self-signed cert add additional layer of security so I can enable https? (I know about warnings though… Users could be educated to ignore). I 've also found a lot of tutorials for creating my own CA, but it might be a challenge for a newbie like me to do right.

EDIT/UPDATE:

Thanks everyone!

Alright, so I talked to my manager today and told him that I’m making an app. I showed him the work I did so far. He was quite pleased with what he saw, was positively surprised and encouraging :slight_smile:

He told me: Yes, do the app, it’s a great idea. Also, he said that https is mandatory. He will take care of the wildcard cert from digicert, no problems there!

I was also happy he is 100% pro node backend I’m working on, even though we use .NET for everything.

Latest update: I already sucessfully crated my own CA using openSSL in my root for development purposes! Https is working on frontend / backend. Browser says: connection is secure

This is working:

const https = require("https");
const fs = require("fs");
const path = require("path");
const sslOptions = {
  key: fs.readFileSync(path.join(__dirname, "./cert/localhost.key")), 
  cert: fs.readFileSync(path.join(__dirname, "/cert/backend.crt")),
};

...

let _ = {};


_.start = () => {
  try {
    https.createServer(sslOptions, app).listen(port, () => {
      console.log("HTTPS server listening on port: " + port);
    });
  } catch (err) {
    throw new Error(err);
  }
};
const corsOptions = {
  origin: "https://localhost:5173",
  credentials: true, 
};
app.use(cors(corsOptions));
app.use(passport.initialize());

...
}

front is working:

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    https: {
      key: fs.readFileSync(path.resolve(__dirname, "./src/cert/localhost.key")), 
      cert: fs.readFileSync(path.resolve(__dirname, "./src/cert/frontend.crt")),
    },
    proxy: {
      "/api": "https://localhost:8000",
    },
  },
});

Everything going good so far! I feel even more motivated now

Thanks everyone for great advices and for pointing out that security is always no1 priority! Also, I’m working in insurance, so good security is mandatory.

Cheers :slight_smile:

If it’s at all feasible, enable HTTPS. In your case the security aspect is not super important, but you mentioned you’re eyeing the dev position at the company, and your manager / users seeing a big scary warning message from their browser and you telling them “oh just ignore that” is not a great look. Even if you’re 100% right that it’s safe, non-technical people are going to find it sketchy. Appearance and presentation is almost as important as whether or not the app actually works, if your company is anything like the many I’ve worked at. You’ve done a lot of work on this project so far, just go a little bit further and finish the job.

Always use encryption. Security is “job zero”.

Stop thinking “if” you should use it. Just work on implementing it. Once you do it for your first app, all other tools can use the same methodology.

Don’t forget to use encryption on all your other backend servers as well, like your database servers.

Are you sure you can trust every device that connects to your network? Can people bring in devices and connect them? A VPN would prevent a coffee shop’s devices from seeing credentials but not the devices on your office network (or nefarious but legitimate users on approved devices). Like maybe there’s another low level employee who wants to get higher level access. End to end encryption is worth it.

Letsencrypt usually requires your http server to be public for the challenge but you can use DNS challenge (and get a wildcard cert) instead Challenge Types - Let's Encrypt

Absolutely use HTTPS. You need defense in depth. You may not be worried about in-transit encryption (VPN does that), but what about:

  • the person possibly sitting in the office, approving the requests (they’re connected to some switch or AP, but maybe today there’s a new black box in some rack you rarely check? [1])
  • a “power user” who connects the VPN from his router, rather than configure it on his laptop (he uses Arch btw.)
  • a DNS attack that redirects traffic to a third-party host controlled by the attacker (no HSTS to prevent this!)

Use defense in depth. Use split horizon DNS if you have to, to obtain a real SSL cert. Enforce HSTS. For stuff like this, it is even more important because it could be a good gateway to attack the rest of the company.

And for the love of everything that’s sane and secure, do not educate users to ignore HTTPS errors.

[1] Now this is a fun one: last week, Bitcoin miners were found in ventilation ducts in the friggin’ Supreme Administrative Court of Poland. Some were also embedded under the floor. You never know!

I was working on a project with some security experts who consult with financial institutions in NYC. We were talking about security issues he’s seen in the wild, and one of them was using HTTPS (or more broadly, encryption) only at the network perimeter but passing everything in the clear within the network.

He called this the HTTPS mullet: business up front, party in the back.

A VPN mullet is also a bad look.

Https is just easier than http. More web features are getting put behind the s-flag it’s the way to go.

If you’re using LDAP you have enough admin control to add your own PKI root and sign a cert to prevent warnings. But it’s easier to just get a wildcard cert on the domain. Because you’re still using a real DNS name right?

You’ll need https at a minimum and also your maybe storing PII in the database in the users email.

You should write up an architecture and submit it to a security team for review otherwise it will get shut down.

Build solutions assuming they exist in a zero trust environment. Don’t assume you’ll always have a specific VPN in place because that can change.

Yes, you should be using TLS everywhere.

Why is it needed if you already are using a VPN?

You can check Traefik which is a reverse proxy that automates certificate creation and renewal using let’s encrypt, very simple to use especially with Docker, for an internal site you would use DNS challenge as mentioned earlier.

Also set up auto renewal from the start so the app doesn’t suddenly stop working.

Well, you may still get that message with a self-signed cert (assuming an internal domain). Of course I would still do it, warning or not.

true. users care more on aesthetics and bugs than how useful the app actually is

Thanks! Will update my question shortly to anwser everyone :slight_smile:

He’s already using encryption through the VPN.

Thanks! Will update my question shortly to anwser everyone :slight_smile:

Also, wow at that court vent btc mining operation

Yeah, that’s true. I am new to programming and web dev though, hence the original question. Anyways, I updated my question. :slight_smile: Thanks for help!