Ngày nay, sự đe dọa lớn nhất đối với an ninh của các mạng máy tính của các tổ chức lại đến từ chính các Website công cộng và các ứng dụng đặt ở trên các web của họ. Không giống như các dịch vụ dùng trong mạng cục bộ như là các cơ sở dữ liệu có thể ngăn cản sự truy cập từ bên ngoài thông qua firewalls, thì mọi người đều có thể truy cập vào một trang web công cộng, khiến cho các ứng dụng bảo mật gặp nhiều vấn đề.
Khi mà các hệ thống mạng đang trở nên kiên cố hơn, các file có khả năng bảo mật thấp trong các ứng dụng web càng thu hút được sự chú ý của các hacker, bao gồm cả những người chỉ muốn tiêu khiển và cả những tên trộm, những kẻ luôn có các công nghệ đủ để khai thác các lỗ hổng đó. Việc tấn công này có thể gây các nguy hại đến cho các hệ thống mạng.
Đã có một vài phần mềm và một số người phát triển được đào tạo để tạo ra các phần mềm bảo mật hay thiết kế các ứng dụng web có khả năng tự bảo vệ cao. Bằng cách “baking in” an ninh của các ứng dụng ngay từ đầu quá trình phát triển thay cho “brush it on” sau khi đã hoàn thành, bạn sẽ dễ dàng tạo ra các ứng dụng bảo mật có thể chống lại sự tấn công của hackers. Tuy nhiên, ngay cả những mã nguồn bảo mật được viết tỉ mỷ nhất trên C# hay VB.NET vẫn có thể bị nguy hại nếu bạn không quan tâm đến các file cấu hình trong Web.config của ứng dụng. Các ứng dụng mạng cơ bản được cấu hình không hợp lý có thể bị nguy hiểm giống như được code không chính xác. Các vấn đề còn tồi tệ hơn, khi mà nhiều thiết lập cấu hình hiện nay thường để default và khi đó các giá trị thường là không an toàn.
Ở đây chúng ta sẽ nói về những lỗi hay tồi tệ nhất trong file cấu hình có thể gây hại đến cho các ứng dụng của chúng ta.
1. Custom Errors Disabled
ASP.NET sẽ đưa ra một bản thông báo chi tiết các lỗi tới người dùng khi bạn vô hiệu các lỗi đã được mặc định như dưới đây:
Việc hiểu được nguồn gốc các lỗi thì tự nó không gây hại gì cho khả năng bảo mật của ứng dụng nhưng hãy chú ý là: một hacker càng có nhiều thông tin về một website thì chúng càng có nhiều khả năng tấn công nó. Một thông báo lỗi có thể trở thành một mỏ vàng các thông tin cho những kẻ tấn công. Một thông báo lỗi liệt kê các phiên bản đặc trưng của các framework ASP.NET và .NET có thể được sử dụng bởi các web server, cũng giống như việc bắt các exception vậy. Chỉ cần biết các ứng dụng web cơ bản nào được dùng(trường hợp dùng ASP.NET) sẽ cho kẻ tấn công biết rẳng server đang chạy một phiên bản Microsoft Windows nào cũng như sử dụng web server là Microsoft Internet Information Server(IIS) 6.0 hay cao hơn. Lỗi này cũng giúp cho các hacker biết được cấu hình của các ứng dụng web đó; chẳng hạn như, nếu một “SqlException” được bắt, thì kẻ tấn công sẽ biết được rằng ứng dụng đang sử dụng một trong phiên bản của Microsoft SQL Server.
Bạn có thể xây dựng các ứng dụng có khả năng bảo mật để ngăn cản sự rò rỉ thông tin bằng cách điều chỉnh các đặc tính của thành phần sang “On” hoặc là “RemoteOnly”. Cách thiết lập này sẽ báo cho ứng dụng chỉ hiển thị thông báo lỗi chung chung và khó nhận biết khi có lỗi nào đó được sinh ra. Một cách khác để tránh các vấn đề bảo mật ứng dụng là redirect người dùng đến một trang mới khi có lỗi xảy ra bằng cách thiết lập “defaultRedirect” trong . Cách này sẽ giúp cho các ứng dụng khả năng bảo mật cao hơn bởi vì các trang lỗi chung mặc định sẽ không để lộ nhiều thông tin về hệ thống(đây là trường hợp server sử dụng ASP.NET ).
2. Leaving Tracing Enabled in Web-Based Applications
Trace là một trong những tool hứuich nhất trong ASP.NET, nó giúp bạn có thể đảm bảo tính bảo mật cho các ứng dụng. Thật không may, nó cũng là một trong những tool mà các hacker lợi dụng nhiều nhất để tấn công vào ứng dụng của bạn nếu nó được cho phép trong sản phẩm(cho phép người dùng tác động vào).
Khi đặt ở chế độ cho phép người dùng điều khiển(localOnly=”false”), bất cứ người dùng nào cũng có thể xem chi tiết danh sách các yêu cầu gần đây đối với ứng dụng bằng cách rất đơn giản là vào trang “trace.axd”. Nếu một thông báo chi tiết lỗil là một mỏ vàng đối với các hacker thì việc truy cập được vào trace lại giống như Fort Knox! Truy cập vào trace cho biết rất nhiều thông tin: các phiên bản .NET và ASP.NET mà server đang chạy; một liệt kê đầy đủ các phương thức do các yêu cầu sinh ra, bao gồm cả thời gian thực hiệnl; trạng thái các phiên và các key trạng thái của ứng dụng; các cookies đáp ứng và yêu cầu; thiết lập đầy đủ các yêu cầu headers, các biến hình thức, và các biến QueryString; và cuối cùng là thiết lập đầy đủ các biến server.
Một hacker luôn tìm kiếm cách để biết được lịch sử cách sử dụng các biến hình thức bởi vì những điều này có thể bao gồm cả các địa chỉ email, điều đó sẽ giúp chúng có thể bán lại cho các kẻ gửi thư rác, ID và password có thể bị sử dụng để mạo nhận người dùng, hoặc các thông tin về tài khoản ngân hàng hay thẻ tín dụng có thể bị đánh cắp. Thậm chí là những dữ liệu có vẻ như vô hại nhất trong trace cũng có thể gây nguy hiểm nếu rơi vào tay kẻ xấu. Ví dụ, biến server “APPL_PHYSICAL_PATH”, bao gồm các đường dẫn vật lý của các ứng dụng web trên server, có thể giúp các hacker tìm được các đường dẫn tới các thư mục tấn công lại hệ thống.
Cách tốt nhất để ngăn cản 1 hacker đạt được các dữ liệu trong trace từ các ứng dụng web là không cho phép xem trace bẳng cách thiết lập đặc tính “enabled” của sang “false”. Nếu bạn bắt buộc phải để trace ở “enabled” thì hãy chắc chắn rằng để “localOnly” ở “true”. Điều đó khiến người dùng chỉ có thể xem trace ở trên web server và vô hiệu việc xem từ các máy từ xa, tăng khả năng bảo vệ cho ứng dụng của bạn.
3. Debugging Enabled
Triển khai các ứng dụng web ở chế độ debug là một sai lầm rất phổ biến. Hầu như các ứng dụng web đều đòi hỏi phải debug. Visual Studio 2005 thậm chí còn tự động điều chỉnh Web.config cho phép debug khi bạn bắt đầu debug ứng dụng của bạn. Và, khi triển khai ứng dụng ASP.NET đơn giản như copy các file từ các thư mục phát triển sang các thư mục triển khai, thì cũng rất dễ dàng nhận ra các thiết lập cấu hình có thể gặp sai lầm bao gồm cả các lỗi bảo mật .
Giống như 2 lỗi trên việc cho phép debug rất nguy hiểm bởi người dùng hoàn toàn có thể thu được các thông tin bên trong hệ thống của bạn qua đó tấn công ứng dụng của bạn. Thật không may là thiết lập này không phải là lỗi duy nhất, điều đó giải thích tại sao những người phát triển phần mềm không nên chú trọng vào một cấu hình duy nhất khi muốn bảo đảm tính bảo mật của hệ thống. Trong các phiên bản framework đầu tiên, một vài điều khiển trả về các thông báo tới người dùng khi có lỗi. Điều này xảy ra cho dù có thiết lập debug hay ko, vì thế cho dù bạn hoàn toàn có thể cấu hình ứng dụng của mình chỉ hiển thị các thông tin không quan trọng thì source code của bạn vẫn có thể rơi vào tay người dùng nếu bạn vẫn cho phép debug.
Để vô hiệu debug, đặt giá trị của “debug” trong bằng “false”. Đây là giá trị mặc định nhưng chúng ta nên tự cấu hình lại chứ không nên phụ thuộc vào cấu hình mặc định để bảo đảm tính bảo mật cho hệ thống.
4. Cookies Accessible through Client-Side Script
Trong trình duyệt IE 6.0, Microsoft đã giới thiệu đặc tính cookie mới gọi là “HttpOnly”. Trong khi bạn có thể thiết lập các đặc tính chương trình trên một nền tảng của mối cookie, bạn vẫn có thể thiết lập nó trên toàn cầu trong một trang cấu hình.
Bất kỳ cookie nào đặt ở đặc tính này đều chỉ có thể được truy nhập vào từ các code ở trên server.Điều này giúp nâng cao tính bảo mật cho hệ thống của bạn. Các hacker đều thuộc lòng cách tấn công CSS (Cross-Site Scripting, còn gọi là XSS) để thêm vào các mã nguồn riêng của mình. Khi đó thì tính bảo mật của hệ thống sẽ bị đe dọa nghiêm trọng. Các forum, wiki thường hay mắc phải các lỗi này. Trong những trang này, các người dùng hợp pháp post lên những suy nghĩ, ý tưởng của họ , những điều này là hoàn toàn public với tất cả mọi người xem trang web. Nhưng một kẻ tấn công thì sẽ post lên những bản tin như kiểu “alert(document.cookie);”. Thông tin này bao gồm các script của anh ta và sẽ được trình duyệt biên dịch và chạy. Những thông tin này thường nhằm mục đích lấy các thông tin truy cập của người dùng để sử dụng vào các mục đích xấu. Nếu đặt các cookie ở “HttpOnly” sẽ giúp các thông tin này không thể thấy được từ phía client và sẽ ngăn cản được việc bị tấn công. Vì thế hãy thiết lập “HttpOnly” của “HttpCookie” ở giá trị “true “. Tuy nhiên có một cách còn đơn giản và đáng tin cậy hơn là cấu hình cho hệ thống tự động cho phép “HttpOnly” cho tất cả các cookie. Chỉ cần đặt “HttpOnlyCookies ” của thành phần thành “true”.
5. Cookieless Session State Enabled
In the initial 1.0 release of ASP.NET, you had no choice about how to transmit the session token between requests when your Web application needed to maintain session state: it was always stored in a cookie. Unfortunately, this meant that users who would not accept cookies could not use your application. So, in ASP.NET 1.1, Microsoft added support for cookieless session tokens via use of the “cookieless” setting.
Web applications configured to use cookieless session state now stored the session token in the page URLs rather than a cookie. For example, the page URL might change from http://myserver/MyApplication/default.aspx to http://myserver/MyApplication/(12345…)/default.aspx. In this case, “123456789ABCDEFG” represents the current user’s session token. A different user browsing the site at the same time would receive a completely different session token, resulting in a different URL, such as http://myserver/MyApplication/(ZYXWV…)/default.aspx.
While adding support for cookieless session state did improve the usability of ASP.NET Web applications for users who would not accept cookies, it also had the side effect of making those applications much more vulnerable to session hijacking attacks. Session hijacking is basically a form of identity theft wherein a hacker impersonates a legitimate user by stealing his session token. When the session token is transmitted in a cookie, and the request is made on a secure channel (that is, it uses SSL), the token is secure. However, when the session token is included as part of the URL, it is much easier for a hacker to find and steal it. By using a network monitoring tool (also known as a “sniffer”) or by obtaining a recent request log, hijacking the user’s session becomes a simple matter of browsing to the URL containing the stolen unique session token. The Web application has no way of knowing that this new request with session token “123456789ABCDEFG” is not coming from the original, legitimate user. It happily loads the corresponding session state and returns the response back to the hacker, who has now effectively impersonated the user.
The most effective way to prevent these session hijacking attacks is to force your Web application to use cookies to store the session token. This is accomplished by setting the “cookieless” attribute of the element to “UseCookies” or “false.” But what about the users who do not accept cookies? Do you have to choose between making your application available to all users versus ensuring that it operates securely for all users? A compromise between the two is possible in ASP.NET 2.0. By setting the “cookieless” attribute to “AutoDetect,” the application will store the session token in a cookie for users who accept them and in the URL for those who won’t. This means that only the users who use cookieless tokens will still be vulnerable to session hijacking. That’s often acceptable, given the alternative-that users who deny cookies wouldn’t be able to use the application at all. It is ironic that many users disable cookies because of privacy concerns when doing so can actually make them more prone to attack.
6. Cookieless Authentication Enabled
Just as in the “Cookieless Session State Enabled” vulnerability discussed in part one, enabling cookieless authentication in your Web-based applications can lead to session hijacking and problems with application security.
When a session or authentication token appears in the request URL rather than in a secure cookie, an attacker with a network monitoring tool can get around application security, easily take over that session, and effectively impersonate a legitimate user. However, session hijacking has far more serious consequences for application security after a user has been authenticated. For example, online shopping sites generally utilize Web-based applications that allow users to browse without having to provide an ID and password. But when users are ready to make a purchase, or when they want to view their order status, they have to login and be authenticated by the system. After logging in, sites provide access to more sensitive data, such as a user’s order history, billing address, and lock nick number. Attackers hijacking this user’s session before authentication can’t usually obtain much useful information. But if the attacker hijacks the session after authentication, all that sensitive information could be compromised.
The best way to prevent session hijacking with Web-based applications is to disable cookieless authentication and force the use of cookies for storing authentication tokens. This application security measure is added by changing the cookieless attribute of the forms element to the value UseCookies.
7. Failure to Require SSL for Authentication Cookies
Web-based applications use the Secure Sockets Layer (SSL) protocol to encrypt data passed between the Web server and the client. Using SSL for application security means that attackers using network sniffers will not be able to interpret the exchanged data. Rather than seeing plaintext requests and responses, they will see only an indecipherable jumble of meaningless characters.
You can require the forms authentication cookie from your Web-based applications to use SSL by setting the requireSSL attribute of the forms element to true.
The previous section discussed the importance of transmitting the authentication token in a cookie, rather than embedding it in the request URL. However, disabling cookieless authentication is just the first step towards securing the authentication token. Unless requests made to the Web server are encrypted, a network sniffer will still be able to read the authentication token from the request cookie. An attacker would still be able to hijack the user’s session.
At this point, you might be wondering why it is necessary with application security to disable cookieless authentication, since it is very inconvenient for users who won’t accept cookies, and seeing as how the request still has to be sent over SSL. The answer is that the request URL is often persisted regardless of whether or not it was sent via SSL. Most major browsers save the complete URL in the browser history cache. If the history cache were to be compromised, the user’s login credentials would be as well. Therefore, to truly secure the authentication token, you must require the authentication token to be stored in a cookie, and use SSL to ensure that the cookie be transmitted securely.
By setting the requireSSL attribute of the forms element to true, ASP.NET Web-based applications will use a secure connection when transmitting the authentication cookie to the Web server. Note that IIS requires additional configuration steps to support SSL. You can find instructions to configure SSL for IIS on MSDN (http://www.microsoft.com/technet/pro….mspx?mfr=true).
8. Sliding Expiration Used
All authenticated ASP.NET sessions have a timeout interval to protect the application security. The default timeout value is 30 minutes. So, 30 minutes after a user first logs into any of these Web-based applications, he will automatically be logged out and forced to re-authenticate his credentials.
The slidingExpiration setting is an application security measure used to reduce risk to Web-based applications in case the authentication token is stolen. When set to false, the specified timeout interval becomes a fixed period of time from the initial login, rather than a period of inactivity. Attackers using a stolen authentication token have, at maximum, only the specified length of time to impersonate the user before the session times out. Because typical attackers of these Web-based applications have only the token, and don’t really know the user’s credentials, they can’t log back in as the legitimate user, so the stolen authentication token is now useless and the application security threat is mitigated. When sliding expiration is enabled, as long as an attacker makes at least one request to the system every 15 minutes (or half of the timeout interval), the session will remain open indefinitely. This gives attackers more opportunities to steal information and cause other mischief in Web-based applications.
To avoid this application security issue altogether, you can disable sliding expiration by setting the slidingExpiration attribute of the forms element to false.
9. Non-Unique Authentication Cookie Used
Over the last few sections, I hope I have successfully demonstrated the importance of application security and of storing your application’s authentication token in a secure cookie value. But a cookie is more than just a value; it is a name-value pair. As strange as it seems, an improperly chosen cookie name can create an application security vulnerability just as dangerous as an improperly chosen storage location.
The default value for the name of the authentication cookie is .ASPXAUTH. If you have only one Web-based application on your server, then .ASPXAUTH is a perfectly secure choice for the cookie name. In fact, any choice would be secure. But, when your server runs multiple ASP.NET Web-based applications, it becomes critical to assign a unique authentication cookie name to each application. If the names are not unique, then users logging into any of the Web-based applications might inadvertently gain access to all of them. For example, a user logging into the online shopping site to view his order history might find that he is now able to access the administration application on the same site and change the prices of the items in his shopping cart.
The best way to ensure that all Web-based applications on your server have their own set of authorized users is to change the authentication cookie name to a unique value. Globally Unique Identifiers (GUIDs) are excellent choices for application security since they are guaranteed to be unique. Microsoft Visual Studio helpfully includes a tool that will automatically generate a GUID for you. You can find this tool in the Tools menu with the command name “Create GUID”. Copy the generated GUID into the name attribute of the forms element in the configuration file.
10. Hardcoded Credentials Used
A fundamental difficulty of creating software is that the environment in which the application will be deployed is usually not the same environment in which it is created. In a production environment, the operating system may be different, the hardware on which the application runs may be more or less powerful, and test databases are replaced with live databases. This is an issue for creating Web-based applications that require authentication because developers and administrators often use test credentials to test the application security. This begs the question: Where do the test credentials come from?
For convenience, to avoid forcing developers from spending time on creating a credential store used solely for test purposes (and which would subsequently be discarded when the application went to production), Microsoft added a section to the Web.config file that you can use to quickly add test users to Web-based applications. For each test user, the developer adds an element to the configuration file with the desired user ID and password as shown below:
While undeniably convenient for development purposes, this was never intended for use in a production environment. Storing login credentials in plaintext in a configuration file is simply not secure. Anyone with read access to the Web.config file could access the authenticated Web application. It is possible to store the SHA-1 or MD5 hash of the password value, rather than storing the password in plaintext. This is somewhat better, but it is still not a secure solution. Using this method, the user name is still not encrypted. First, providing a known user name to a potential attacker makes it easier to perform a brute force attack against the system. Second, there are many reverse-lookup databases of SHA-1 and MD5 hash values available on the Internet. If the password is simple, such as a word found in a dictionary, then it is almost guaranteed to be found in one of these hash dictionaries.
The most secure way to store login credentials is to not store them in the configuration file. Remove the credentials element from your Web.config files in production applications.
You’re Not Out of the Woods Yet
Now that you’ve finished reading the top-ten list, and you’ve checked your configuration settings, your applications are secure forever, right? Not just yet. Web.config files operate in a hierarchical inheritance manner. Every Web.config file inherits values from any Web.config file in a parent directory. That Web.config file in turn inherits values from any Web.config file in its parent directory, and so on. All Web.config files on the system inherit from the global configuration file called Machine.config located in the .NET framework directory. The effect of this is that the runtime behavior of your application can be altered simply by modifying a configuration file in a higher directory.
This can sometimes have unexpected consequences. A system administrator might make a change in a configuration file in response to a problem with a completely separate application, but that change might create a security vulnerability in your application. For example, a user might report that he is not able to access the application without enabling cookies in his browser. The administrator, trying to be helpful, modifies the global configuration file to allow cookieless authentication for all applications.