Category Archives: Security

Add an SPF DNS record if you don’t want emails sent by your system defined as spam

The problem is, 

  1. Your web application’s domain name is www.foo.com

  2. Your server IP is 123.123.123.123, and it sends emails to users from  support@foo.com 

  3. When a user  danni@gmail.com gets an email from it,  GMAIL may consider it is spam because it doesn’t know whether 123.123.123.123 really represents support@foo.com . 

 What you need to do is to setup a SPF DNS record for your domain, to tell people that 123.123.123.123 can send emails from xxx@foo.com. On Godaddy, you can do this according to, 

https://ph.godaddy.com/help/add-an-spf-record-19218

What are the HTTPS Certificates in a C/S Communication and How are they verified?

An Https Certificate (a.k.a X509 certificate) is used to show others that you are really who you says you are.

In a https-based c/s communication, including b/s communication, in most of the cases only the server side has to show a certificate. The client doesn’t need one, otherwise it will be very inconvenient for clients.

When communicating, the client-side application such as a web browser will download the server-side certificate, verify its domain name against what is recorded in the certificate, then they can start transferring data.

But a server-side certificate itself can be fake. The client-side program needs to inquire a CA (Certificate Authority) to verify the server-side certificate’s authenticity that it is issued by a CA. This is done by using CA’s certificates(a.k.a Root Certificate).  

So how to get the CA’s certificate?  Web browsers have contained mainstream CAs’ certificates, such as VeriSign’s. So, everything is fine with Browsers and sites with CA-issued certificates.

However, it is not free to let a CA issue a certificate. Some websites may choose one of the 2 ways to avoid the cost by using an “invalid certificate”:

1. Use a self-signed server-side certificate

2. Be a CA myself and then issue server-side certificate, such as https://www.12306.cn/

In both of the cases the client will get a warning on browser.  To avoid the warnings, you can “import” these “invalid certificates” to your browser. After importation the browser thinks you will always trust them.

We’ve talked about the case of browsers.  What about other clients such as a Java desktop program or an Android APP which talks to https-based servers?  They are about the same as browsers.  Take Java for example. A JDK has been shipped with mainstream CA’s certificates. And you can import “invalid” certificates files to JDK, or do it at runtime with java security APIs. By the way, the importing is mandatory for Java programs. You will not get an warning but an Exception.

Finally, there are a few cases the client needs a certificate to prove himself, for example, when you are visiting an online bank system.  Another example is RESTFul API calling between two companies who know each other. In this case, the server side program must explicitly point out it needs client-side authentication.

Will there be security issues of self-made https certificates ?

By self-made https certificates, I mean one of the two kinds:

1. A self-signed certificate

2. A certificate issued by an unknown CA, for example, the certificate of https://www.12306.cn is by the CA of China’s Railway Department.

Will there be security issues?  Yes, there is a big issue, but you can work around it in some cases.

The major security issue is privacy problem when there is a DNS trick. Take 12306.cn as an example,

1. You visit 12306 with a browser. Due to the DNS trick, you are actually visiting the attacker’s https-based website which looks like 12306.

2. The browser then warns that the certificate is not valid. At the same time, the fake 12306 tells you to download the self-made certificate and import it to your browser, just as the real one does.

3. If you choose to ignore warnings and go on without importing any certificate, you are now talking to the attacker with sensitive information. You are in danger.

4. You may also choose to download the self-made certificate, do the importing since you the real 12306 does that. After the importation the warning disappears.  What you don’t know is, you just download a fake certificate made by the attacker.  If you go on with this site your information get leaked.

If 12306 doesn’t uses an unknown CA, when you are under DNS trick and visiting the fake 12306 site, you will see a security warning which you don’t expect.  You are safe.

How to work around this problem if the server company cannot afford to pay a mainstream CA?  If you have got 12306’s authentic CA certificate before hand, for example, you have a friend working at that site and he gives you the real certificate with a USB stick, and then you import it before you visit the site, you will expect to see no warnings. When you visit the fake 12306 in this case, the browser will show warnings because the server-side certificate used by the fake 12306 will not pass the test of the authentic CA, which you have imported in the first place.

The same rules apply to a site which uses a self-signed server-side certificate instead of a self-made CA certificate.

Also, if the 12306 were inside the intranet that you totally trust, you wouldn’t worry about this problem at all. That’s why intranet sites often use self-made certificates. 

In the case of Internet site, you can see that “a friend working at the website’s company” is the key factor to work around this problem. That is, if you can get the real certificate before hand, then you are safe.  This is how C/S interactions work with self-made certificates.  Take an Android program for example.  The server uses a self-signed certificate, and the Android app packages this certificate file before it is being run. Things will match during runtime.

Speak of Android, or other client-side programs, it is important not to go for the “disable SSL validation” approach.  In Android or Java, this is normally done with a “trust-all” security manager. If you go this way and you get DNS tricked, you will leak information to the attacker’s fake server, because it is like “ignoring browsers’ warnings when visiting a website with self-made certificates”

Prevent user attacking in HTTP RESTFul API calls

This is an incomplete list of things you should consider when you want to prevent your users being attacked by others.

Note this is about protecting individual consumers with username/password pairs, rather than application clients such as third-party companies, who normally carry AppKey/AppSecret pairs. 


Authentication

There are several options.  

Sending username/password as http request parameters every time an API is called.  In this case you should, 

1. POST rather than GET. A password in URL can be more easily exposed

2. HTTPS has to be used to prevent eavesdropping. 

Basic Authentication: Sending username/password as http headers every time an API is called.  In this case,  make sure to use HTTPS to ensure privacy. 

 Authentication based on cookies or session tokens : The user "login" for once, then the client application receives a cookie or a session token, and send it along with the request every time an API is called.  In this case you should, 

1. POST rather than GET

2. Use HTTPS to protect password when calling Login API if possible.  However, you may be confident to think that this can rarely happen since the password is transferred in clear text for only once. 

3. Use HTTPS to secure the cookies or session tokens in requests after login

Attach a password-based signature with every API request.  This is useful if you can’t set up HTTPS.

1. Encrypt every http request with the consumer’s password as encryption key, get a signature,  and send the signature along with requests. 

2. The server side will do  the same encryption on receiving requests and see if the result matches the signature. 


Privacy of Sensitive Information in Request and Response

1. Always prefer POST to GET

2. Use HTTPS  if possible 


Data Integrity

If HTTPS has been used, data integrity won’t be breached. An attacker cannot modify encrypted text. 

If HTTPS has not been used, then you must use the password-based-signature authentication mentioned above.  It is also safe in terms of data integrity, since the modified request won’t match the original signature.


Replay Attack

If HTTPS has been used, a man-in-the-middle reply attack won’t work. The HTTPS protocol has some handshake and MAC trick to prevent this. 

However, you still need to choose POST over GET, to reduce the chance that a user mistakenly send the whole request URL to the attacker.  

If no HTTPS is used and you have the password-based-signature authentication mentioned above, a repay attack can be easily performed. In this case, you need to insert a timestamp in the request and use it to construct the signature, the server side should check if the timestamp is close to current time.  However, it won’t work very well if the replay happens very soon.  You will also need to provide a clock synchronization API. 

The other choice is to introduce a "One-Time Submission Token", just like the token used in websites to prevent duplicate form submission.  You request the token first by calling a special API and then use this token to call your biz api. 

系统交互时利用摘要机制来校验参数组合的正确性

一个系统在处理另一个系统发来的请求时,如果遇到 "种类 = 可乐 & 口味 = 苦味" 这样的无意义参数组合,应该如何甄别出这是一个无效的请求? 因为可乐不可能是苦味的,正常的系统不会发出这样的请求,这种请求只可能是别人伪造出来的。

最直接的甄别手段是在本系统里实现“可乐不可能是苦味”这种业务逻辑,但是本系统是一个基础应用,不应该让特殊的业务逻辑侵入。

另一种方案是让本系统通过RPC回调业务系统,校验是否“可乐,苦味”这种组合的有效性。但这会导致两个系统之间存在互调,对性能和发布都不利。

今天有个同事想出了一个简单的办法:发送端将参数组合起来加密,接收端解密文,如果解出来的东西不是一堆乱码,就可以认为这个组合是有效的。 即使中间人截获了报文,他也只能截获“可乐,甜味”,“可乐,酸甜味”这种有效的组合;如果中间人把这种组合发出来了,我们的基础系统也照样帮忙处理,没什么大不了的。

那为什么说中间人拼不出“可乐,苦味”这种无效组合的密文呢? 因为中间人不知道具体的加密办法。

所以,通过加解密就可以保证参数组合是有效的。 当然,更简单的办法是用摘要,摘要算法如MD5是不可逆的加密算法,它的执行可以快一些;不过,MD5算法很容易被人猜到,你在MD5之前应该先往明文里掺点噪音数据,并让发送方和接收方使用相同的噪音数据。

常用认证中心 (CA)

摘自《Java加密与解密的技术》

CA三巨头: VeriSign, GeoTrust, Thawte  –都很贵,但会提供一些Trial Version

一个免费组织: www.cacert.org

中国各省均设有CA机构,如北京市数字证书认证中心

KeyPairGenerator, KeyFactory, KeyStore

待完善….

KeyGenerator    — 用于生成Symmertric Key

KeyPairGenerator   –用于生成Public/Private Key对

SecretKeyFactory — 把代表对称密钥的byte[] 变回 Key对象

KeyFactory  — 把代表非对称密钥的byte[] 变回 Key对象

KeyStore  —  in-memory collection of keys and certificates