I don't want to leave any chance for hackers to see what I put in URI apart form the domain. For example,
http://www.mynewwebsite.com/ (some text or webpage.html)
In the above, I want to make '(some text or webpage.html)' secure
Now I am confused between two approaches.
1) Should I add a custom http header whose value is "(some text or webpage.html)" and on the server, I read the header to address the request.
2) Should I simply switch to https?
What are the pros and cons of each? (Forget about additional money i need to pay to use https)
Thanks in advance.
Switching to https is simple solution if you don't want hackers to sniff your network and read request params
With HTTPS, the request and headers are encrypted, this should prevent prying eyes as per your requirements. Depending upon your setup, the SSL certificate may be free using Let's Encrypt.
If you simply add a custom header to an HTTP request, you may hide your intentions from a cursory glance but the data could still be accessible to a 3rd party.
1) Should I add a custom http header whose value is "(some text or
webpage.html)" and on the server, I read the header to address the
request.
I think you misunderstood how http works. The header content are sent before the body content. The hacker could simply read the entire stream and focuses on just the header to extract information.
2) Should I simply switch to https?
Switching to HTTPS is a must (to me) if you are going to do user authentication or wanting to keep something secret. It encrypts the information so unintended recipients cannot understand. The recipient have to decide that information with their private key.
There are a number of SSL options that you have.
lets encrypt
It's the biggest free ssl certificate provider. However their certs only have a 3 months life so you need to renew it every now and then. Perhaps you can look up cron job and use it to check with let's encrypt server and renew when expire date near.
Other paid ssl provider
Although both has no differ in encryption level. But features that standout between the two that lets encrypt yet to have is wildcard ssl on *.yoururl.com. This offers the entire sub domain not just a single url as well as in an event of breach, insurance will cover for the damage.
HTTPS encrypts your payload (including headers and URL via SSL/TLS) along the route from point A to point B, preventing hackers from seeing your data if they intercept it between these two points. It's the only way to achieve the security you're looking for.
However if the potential hacker legally sits at point B, HTTPS will not help you. Regardless if the information is tucked away in the header or part of the URL, it will be visible. Anyone can see the headers. If you want to hide specific information from the end-user, manually encrypt it.
Related
I am a newbie in Javascript and Vue.js. Try to learn more about it. Now I will be facing a problem when calling an API login that will display a password in the request payload.
I was wondering it does not secure, right? And if it was correct. How to hide it from the browser?
Anyone please help or suggest to me.
This is a pretty heavy topic and the question is not very specific, so I'll make some assumptions along the way.
calling an API login that will display a password in the request payload
I suspect you mean that if you're looking into the requests in the browser dev toolbar, the password is seen.
If this is the case, this is expected and can't be 100% mitigated. I've known people to assume that this means that this means that the data is not encrypted and develop custom solutions to obscure the sensitive data. The thing to keep in mind though is that the browser already does the encryption for you as long as you use https. The encryption happens after the request leaves your browser, so you're not seeing it as encrypted, but it travels to the designated server in a way that hides the content for anyone in the middle. If you add some additional encryption system, you're adding complexity and as long as you're passing the key as-well, the "man in the middle" has access to that too. The endpoints within the target server are also encrypted, so you could even use GET to pass sensitive information without anyone between your browser and server knowing what it is, but don't use GET, since POST has additional benefits like not storing the values in your url cache and the server is less likely to be storing the data in the logs.
When using https properly, your data will be encrypted between browser and server.
You should be using POST requests for sending sensitive data
Avoid adding custom encryption on top of https. It will add more complexity than security.
There's also some considerations around storing the token in LocalStorage vs cookies. The final decision on which is better is inconclusive, but as long as proper precautions are taken, they can both be secure (though I think cookies can be more secure, but only if you make them inaccessible by js, so it makes working with them in context of an SPA harder)
I am new and need directions so I can ask the correct questions. Here's the deal:
I have developed a REST API under HTTPS.
The user must provide a valid token to use the API.
The token expires after not being used for more than 5 minutes.
To obtain the token, the client must call the authentication API passing his private primary or secondary key, along with his user number.
Each key is unique, and on the database I save it's hash.
The user passes his primary or secondary key through the header with key "pk" or "sk" and "usernumber".
The server will get those keys and send to the database, which will apply the hash and check if they are valid.
Once the keys are valid, a token itself is generated on the database, and returned to the user.
My concern regards passing the primary key or secondary key on the headers. I am not sure if someone can obtain those data from outside and neither if it is the best practice. I am trying to get some directions, and I have came upon basic auth, oauth, and others. But they all seem to be on HTTP.
I have not found much about API HTTPS, so I also need some directions here. Can I make my API accept only https requests? If so, does the same security rules apply?
Thanks in advance.
There are 4 security aspects to consider. Most of the frameworks define the flow for Authentication and Authorization. Some frameworks define Integrity as well via Signatures.
But almost all heavily rely on encrypted data for for Confidentiality. i.e they recommend HTTPS if the communication is based on HTTP
Authentication:
Identifying who is talking to your API.
Authorisation:
Once you have identified who is talking to your API, ensuring they have the permission to talk to. If authentication is like checking someone's Id and allowing them into the building. Then authorisation is like allowing them to go into room for which they have access code.
Integrity:
One you know who are you talking to and what they are allowed to do, you still need to make sure that data you are receiving is from them and not tampered data.
Confidentiality
May be they are not tampering the data but reading all the data over the wire so later they can use that data and pretend to be the person you trust. So except for the sender and receiver no one else to see the data.
Note:
The above 4 aspects are for security on the flow.
You also have to consider security at rest. You seems to have strong design here on the server side for this aspect.
Have you considered what would you do when the token expires after 5 minutes. You user won't be happy entering user number and primary key/secondary key every 5 minutes. And if you plan to store it on client side so you can automate it every 5 minute, then you have to think about where would you store it in the client side and security at rest aspect for that
First of all: regarding HTTPS VS HTTP.
HTTPS is HTTP over TLS, where TLS is another layer of protection meant to secure the communication channel. All HTTP rules regarding headers apply to HTTPS too. TLS will protect your data confidentiality and integrity. It will protect the whole HTTP request including headers and body.
Regarding passing secrets as headers.
It's ok to pass secrets as headers or body. It's not ok, to pass secrets in URL. It's not ok to log out secrets on servers and proxies along the way. It's not ok to implement your own authentication mechanisms unless really needed.
If you want to read more about what is required to protect the communication channel (and the rest of the application), look into the OWASP Application Security Verification Standard.
Let's say I have access to an https weather API.
Let's say I query its health status on thursday 17/08/2017 23h30 and the API replies OK (simple OK http code).
As a client, I need to prove in the future that the service actually responded me this data.
I'm thinking to asking the API to add a crypto signature of the data sent + timestamp, in order to prove they actually responded OK at that specific time.
Is it overkill? Is there a more simple way of doing it?
A digital signature containing current date/time or even adding a time stamp issued by a third party time stamp authority is an appropriate way to ensure that the content was actually issued on a date
In general, implementing a digital signature system on HTTP requests is not so simple and you have to consider many elements:
What content will you sign: headers, payload, attachments?
Is it binary content or text? Because the algorithms and signature formats will be different
In case of text you must canonicalize the content to avoid encoding problems when you verify the signature on the client side. Also you need to define a signature algorithm to compute the content to sign
Do you also need to sign the attachments when they are sent via streams?. How are you going to handle big files?
How are you going to attach the signature to the https response: special header, additional attribute in the payload?
How is the server going to distribute the signing certificate? You should include it in a truststore on the client
But, if you only want to proof that a service response was OK/FAIL, then the server just need to add a digital signature over the payload (or computed on a concatenation of the headers) but if you want to implement something more complex I suggest you take a look at the Json Web Signature (JWS)
I am building a web application that provides an API as it's primary function. I have been looking into methods for authentication but have been struggling to make a decision on what to use.
Since this will be a paid service and the API is the service, I need to make it as easy to use as possible so as not to put people off but obviously I want it to be secure. I have considered using HTTP basic authentication over SSL but would like to avoid the costs/overheads/hassle of SSL if possible early on and maybe provide it as an option later.
I like the AWS style API authentication (see here) but the problem is I can't have users sending the query string as plain text along with a signature because the parameters may contain things like phone numbers which I think customers would rather not expose. I have thought about providing a secret key to encrypt the string which is sent along with an api key to identify the user.
What do you think the best option is to also encrypt the query string along with the request while maintaining simplicity?
Use HTTPS. It's simple, supported by almost all client libraries, trusted, secure, and it protects the URL and payload.
Some Web Browser have extension/Add-ons, eg. FireFox with Modify Header or Tamper Data, that can modify HTTP Header for GET/POST method before send it to Server.
So, How I can check Header is modified by user from server side?
Since all of the headers come from the client as part of the HTTP request, in essence they are all modified by the client. You cannot tell which headers were added/modified by plugins, at least not with any certainty. The best you could do is try to gather some heuristic data and try to identity known modifications from specific plugins (e.g. Plugin "Foo" always adds a "XYZ" header that looks like "Foo bar baz"), but even then you're bound to get plenty of false positives or negatives.
The question is, why do you want to know this? If you are relying on information in the header (cookies, etc), you can encrypt that data server-side. That will protect it from client-side modifications.
You can't unless the header values are invalid. If they are editing the header values during a session you could check the browser and other header fields and store them in a session, then check that these haven't changed. i.e. if during the course of a session the $_SERVER['HTTP_USER_AGENT'] which is gathered from the header changes then the header has been tampered with.
However if the header values are valid and not unexpected, i.e. if you are receiving requests for values that the page does not use looping through the $_GET[''] array will bring you back all the information that is sent via GET and if you are recieving too many or values that are not needed then you could call die or log it.
Please bear in mind I am aware these examples are all PHP but you have not mentioned what language you are wanting to check this in, all languages have equivalent methods.
You cannot reliably guess what happened to a request before it reached your server, it may even have been crafted manually.
If you are trying to make sure clients never send cookies that your application didn't set (or something like that) you musn't make any such assumptions. Always assume that data sent from a remote user is malicious and use it with caution. You could instead sign your cookies with an HMAC to make sure nobody can create a valid cookie without your secret key.