I am tasked with converting a PHP application into a progressive web app. This entails converting the existing PHP logic into JavaScript that runs client-side.
However, the PHP application contains sensitive information, including SQL credentials, which must never be leaked. This complicates the conversion because one of the biggest requirements of a progressive web app is Offline First, or the ability to operate without an Internet connection and/or not slow down even if an Internet connection is available.
Encrypting the JavaScript code is not an option because, no matter how strong the encryption, the decryption code must be shipped alongside it, and thus, determined hackers will always be able to crack the encryption. HTTPS cannot prevent hackers from jailbreaking their phones.
On the other hand, sending an Ajax request to a proxy server that holds the sensitive credentials will slow down the application, defeating the whole point of progressive web applications.
I have spent hours looking up solutions online, yet nothing I found is relevant enough. So how should developers go about ensuring that SQL credentials and other sensitive information are never exposed in the progressive web app?
EDIT: I should clarify that, while I understand that synchronizing local data with server data is the preferred behavior of progressive web apps, I am explicitly forbidden from doing so in this particular case. The data must be kept confidential.
To answer your original question on how to store your DB passwords safely in client side, "you can't". Anything at client side is not for sensitive information like server side DB password.
PWA is a web application end of the day with new features. But those doesn't gives you any added security to perform server side like operations which you can hide from users. Even if you use HTTPS, it will only encrypt data over network.
What if you use: If you store "DB password" in a PWA app or any web app for that matter, user can get the password using Chrome Dev tools for example and use that to connect to DB directly to get all the data in it, not just his.
Solution: PHP is a server side scripting language. When you convert that to HTML/JS, server side code from it will be remaining for your to put it again in server side itself and expose the data using web services to PWA.
On Downloading data: Caching is not plainly equivalent to downloading. Read more on here and if you still don't want caching, you "Network only" mode as explained in the same link and make use of other PWA aspects..like notifications, install to home screen.
Related
This is kind of a weird question I think to ask, but I have browsing about for the past some time and cannot find a clear definite answer.
I understand that a client connects to its own server and communicates with the web-server through sockets and I kind of see how that works in php (I have never used php but have used sockets before so I understand the concept).
The issue is I'm trying to get a real view of this.
The question is, do websites generally use sockets and contact a web-server to fetch data or the actual html? Or is it a rare choice made in some areas?
If it is generally used, then is the "real" js usually in the server? or is it client-side (for performance sake)?
Context:
Let me explain a bit where I'm coming from, I'm not a web expert, but I am a computer engineering student so most concepts are easy to understand. A "real"-er view of this would be very helpful.
Now, onto why I'm asking this. I'm developing a web-app as part of a project and have done a fair bit of progress on it but everything was done on a local dev server (so basically a client?)
I've started wondering about this because I wanted to use a database for my website and since I want to connect to something, I will need to connect to a web-server first (for security sake).
My question's intent is to guide me on how and most importantly, where, to setup this server.
I don't think showing any code would be of help here, but assume I have my client running on localhost:1234, my database on localhost:3306, I think I should have a web-server on another port so I can establish this communication, but I want to do it in a clean and legitimate way so all of my current solutions can be ported online with little to no changes (except the obvious)
There's a bunch to unpack here.
First of all, servers can be distant or local. Usually they are distant, local server are mostly used for development purposes.
Even if your server is on your local machine, it still isn't the client. The client is the part that is connecting to your server. For web development it is usually the user browser.
Javascript is a language that can be used server-side, with a NodeJS server, but more often client-side, in your user browser.
Your website, or web application, communicate with your server through various means. Most common one is the HTTP protocol, used to make server requests such as data request to populate your page (in case of an API server, REST or otherwise), or simply request the actual page to display in the browser. The HTTP protocol works by resolving URLs, and making requests to your server registered to this url using special methods such as GET, POST, DELETE, etc...
Sockets are used to create a persistent connection with your server that works both ways. It is mostly used for realtime updates, such as a live chat, as it allows you to push updates from the server instead of having the client request everything.
In most cases the database can be found on the same server as the one serving the website or application, as it is a lot easier to handle, and often faster without the extra networks requests to get the data. However it can be placed on another server, with it's own API to get the data (not necessarily web related)
Ports such as 1234 or 3306 are often used for local development, however once your move your project to a host service, this is usually replace by urls. And the host service will provide you with a config to access the associated database. Or if you are building your own server you might still use ports. It is heavily dependent on your server config.
Hope this clear some things up.
In addition to #Morphyish answer, in the simplest case, a web browser (the client) requests an URL from a server. The URL contains the domain name of the server and some parameters. The server responds with HTML code. The browser interprets the code and renders the webpage.
The browser and the server communicates using HTTP protocol. HTTP is stateless and closes the connection after each request.
The server can respond with static HTML, e.g. by serving a static HTML file. Or, by serving dynamic HTML. Serving dynamic HTML requires some kind of server language (e.g. nodejs, PHP, python) that essentially concatenates strings to build the HTML code. Usually, the HTML is created by filling templates with data from the database (e.g. MySQL, Postgres).
There are countless languages, frameworks, libraries that help to achieve this.
In addition to HTML, the server can also serve javascript that is interpreted in the browser and adds dynamics to the webpage. However, there could be 2 types of javascript that should not be mixed. NodeJS runs on the server and formats the server response, client javascript runs on the browser. Remember, client and server are completely isolated and can communicate only through an HTTP connection.
That said, there ways to make persistent connections between client and server with WebSockets, and add all kinds of exotic solutions. The core principle remains the same.
It does not matter if server software (e.g apache, nginx) is running on your local machine or anywhere else. The browser makes a request to an address, the DNS and network stack figures out how to reach the server and makes it work.
I need to send a particular header parameter in all ajax calls which is a very confidential information. I don't want from the end user to see any of the requests made in network tab of any browser. Is there any way to prevent it? or is it possible to make ajax calls directly from node server which doesn't go through browser?
Any call made on the client side cannot be hidden, as it's "client" side of the website. Even if you'd success to hide it in browser, any software could monitor it with tools such as network sniffers / monitors, WireShark for instance.
So the answer is no
When you go to a restaurent and order something, can the waiter subsequently make you forget your last instruction/order? The answer is NO, same as the answer to this question.
It all starts with client making a request to the server, hence client is the driving force of the whole interaction. Server just serves as per the instructions from client (and maliciously does some extra work on its own, say auditing, database update, cookie addition etc.).
Hence there is no way a 'server' can restrict client to see its own instructions.
Just simply don't send sensitive information directly via headers. Encrypt them via your client side code and add them within cookies or any other HTTP header(s).
Quoting from internet:
Client/server architecture is a producer/consumer computing
architecture where the server acts as the producer and the client as a
consumer. The server houses and provides high-end, computing-intensive
services to the client on demand. These services can include
application access, storage, file sharing, printer access and/or
direct access to the server’s raw computing power.
Client/server architecture works when the client computer sends a
resource or process request to the server over the network connection,
which is then processed and delivered to the client. A server computer
can manage several clients simultaneously, whereas one client can be
connected to several servers at a time, each providing a different set
of services. In its simplest form, the internet is also based on
client/server architecture where web servers serve many simultaneous
users with website data.
Never trust to client. Ever. Never ever. Doesn't matter what you do assume its been cracked. Hackers have all the tools and complete control of the client and all software running on it. Assume they've written their own network stack, their own TLS implementation, their own browser, their own operating system...
If you need to keep it secure, keep it on your servers. If you need to communicate 'privileged' information (assuming you remember that once you've sent it to a client they can access it) don't, tokenise it on your server and send them the token. And if you're generating tokens make sure they're very random and utterly opaque - don't encrypt anything in the token because you should assume they can crack that too, regardless how secure you think the library you are using is (assume it'll one day be cracked).
Never expose the confidential data on the client-side.
The best practice is to encrypt your confidential data on the server-side, send it to the client, and decrypt on the server end when the client sends you back.
If you don't want encryption or this confidential information is result of user actions itself then make a key-value pair in a database, where the key is something which can be exposed to the client (let's say username) and value is the confidential information. Hence now we have 1-1 mapping, so fetch this confidential information on server-side from database using the key we are getting from the frontend.
I hope this will help.
Good Luck!!
im trying to create a simple website with HTML/CSS and Javascript. Basically the user should be able to input a number into a textfield and "send it" with a button. When the button got pressed i want to run a Javascript function that searches the number in a sql database.
Creating all that stuff shouldnt be a big problem for me, but i have no clue how to create a safe connection between JS and SQL. I have read that a direct connection with javascript is very insecure.
Some people recommend to use java or c# to built an sql connection. How would that work? Basically just an Javascript code, that runs an java/c# application(which builds an sql connection) and returns the needed sql data?
Also heard that its possible to create a sql connection with node.js, is this safe? Or is another method more suitable?
Greetings
I have read that a direct connection with javascript is very insecure
The danger is in giving direct access to your database to the client. JavaScript is most commonly run client-side in web browsers, so for it to access the database you would have to give the browser (and thus the visitor) a username and password on your database server and let them run raw SQL.
There are many possible security risks with this and it just isn't worth it.
(Aside: You can't make arbitrary socket connections with browser-side JavaScript, so it's impossible to connect to most database servers from it anyway).
If you want to expose data to JavaScript running in the web browser, then the standard approach is to write a webservice.
You can write the webservice in any programming language you like (including JavaScript). It listens for HTTP requests, reads data out of them, possibly performs authn/authz, the queries the database (applying the well-documented defences against SQL Injection attacks) and returns the result (often formatted as JSON).
The client-side JavaScript, therefore, just has to make an HTTP request (e.g. with XMLHttpRequest or fetch) with parameters passed in the query string or request body, and process the data it gets back from it.
Connecting to a database using client side javascript is very insecure as the javascript will need to know the login details. And since the client side javascript is on the client side, any user will be able to see the login details in plain text.
The best way to do this is to make a webservice on a server. When the button is clicked it will make a GET/POST request to the webservice with the entered number as a parameter. The webservice, which can be made using any language pretty much, will create the connection with the database and insert the row itself.
Although I would advise going the webservice route since it will be much easier to make secure. Playing with javascript to database is extremely dangerous unless you have a really good system and understand exactly what you are doing; but if you really want to do it and have an application that requires it, then can use PouchDB connected with CouchDB.
PouchDB is run locally and can sync with CouchDB over HTTP.
https://pouchdb.com/
https://couchdb.apache.org/
There is an answer here discussing basic security with pouchDb synchronizing with couchDb. Basically, each person needs separate login credentials and credentials should never be stored in the page code.
PouchDB security
There are some neat uses for pouchDB: https://pouchdb.com/users.html
I'm curious if there's any way that a server can validate a client without knowing that the client is entirely "friendly" code that isn't monitoring 1) the user's input or 2) network requests.
The only way I could conceive of this is if browsers have a built-in, secure, isolated shell / scope that can hash and send data (which can be verified with a complimenting server unhashing / lookup script).
Is there any browser-supported (non-DOM) input/hashing method that can also be installed on the server to identify the authenticity or user input? I want to avoid Chrome Extensions and potential keylogging in general, but I'm not sure any browser supports this feature.
Thanks
EDIT
I think some form of 2-step auth in a separate window would be the closest, but I don't have SSL, and I don't like the presentation of random "popup" windows
If I understand your question correctly you are asking for a proof that the data entered into a form are neither manipulated nor generated by malicious software. But you (as operator of the server) don't have control of the client.
This is impossible as long as you don't have control of the client because it is impossible to distinguish user generated data from software generated data on the network level, and that's all you get at the server. Even the output generated by a browser extension can be faked.
I think some form of 2-step auth would be the closest
2FA is relevant for authentication of the client only and provides no way of making user generated data tamper resistant.
SSL alternative for secure handshake?
SSL only protects the transport and does not prevent modification of the user input within a malicious browser extension or similar. It also does not protect against malicious man in the middle on the clients machine (i.e. Superfish or similar).
Is there a norm for AJAX security?
When making an XMLHttpRequest, if querying an HTTPS url, will the browser handle all the certificate business and properly encrypt the request (or use an already existing authenticated tunnel)? Are there any security flaws in this model?
Then there's also user authentication issues with AJAX. This made me think that using the user's password to encrypt part or all of an AJAX request could solve some authentication issues. I've seen some impressive javascript based encryption tools. It seems like there'd be lots of potential there to build a single system that takes care of both encryption and authentication(host level and application user level). I have however not seen anything that seems 'tried an true'.
My question can be summed up as:
Is there a norm for secure AJAX either
using browser technologies or client
side javascript? What
is it? And if not, what's preventing
us from building one using javascript?
Thank you, as always.
SSL through HTTPS is sort of a cooperative venture with the destination server. The destination server will report its identity with its identity certificate (sent back to the client). This is part of the protocol that will encrypt the data stream between the client and the server.
However, this just encrypts the stream, it does nothing about several other security issues. Identification and authentication of the user entity making a request is handled through other means. If you're encrypting the stream with SSL, it should be safe to use HTTP basic auth. After that, the response to authentication should be a session id sent back to the client that will pass it back on all subsequent requests. Application servers typically manage the creation of those session ids.
Ajax does not inherently introduce new
security vulnerabilities in the realm
of web applications. Instead, the
applications face the same security
issues as classic web applications.
Unfortunately, common Ajax best
practices have not been developed,
which leaves plenty of room to get
things wrong.
from: http://www.securityfocus.com/infocus/1868
Basic authentication makes sense. I found this article explaining how to do it.
I somehow still have this desire to not use all the browser technologies and encrypt/authenticate things myself. Not sure if that would make any sense. Key caching would be hard to accomplish.
I'm still looking to find out if this (SSL + using basic auth in ajax calls) is the norm.