Security guidelines for building modern Web applications

Source: Internet
Author: User
Tags html comment session id scrypt amazon cloudfront ruby on rails

Original: Security for building modern web Apps
Translator: Jay Micro Magazine-Zhang Di

This article is inspired by another article about "What to know before building a web app today." It's not long, but I've omitted some recommendations on security, so I'm writing to share some of this knowledge.

This article focuses on developers who come from startups and want to develop a Web application from scratch, who don't know much about information security and don't want to spend too much time thinking about the security of their applications. Some important content is not discussed here, such as threat modeling (threat modeling), continuous delivery of security (continuous delivery), and so on. The goal of this article is not to replace the existing code security checklist (for example, Owasp,sans), but to supplement it from today's perspective. After all, the concept of security is very old, (for example, the security design principle was defined in the 70 's), it will continue to exist today and even in the future, so security needs to evolve with the times and adapt to reality.


Note: While articles such as this are useful, security is a process that must be closely related to the development process from the outset. Always consider finding an application security specialist to help you.


Client Clients


Output filtering: A well-known cross-site script (Cross-site Scripting), also known as "XSS" or "HTML injection," can cause problems when there is no output filtering and execution of some code. The defense method relies on the context, such as the dynamic value (onclick, onload, etc.) on the HTML tag attribute, or the inside of the label (for example, $ ("P:first"). innerhtml=dangerousvariable). This danger code will only take effect if the dynamic variable is stored in the attributes of the HTML tag. Filtering input is helpful for security, but remember that XSS depends on context, so not all filters are valid. Here's a detailed explanation of my XSS (PT-BR).


working with static pages (use static pages): The advantages of a single-page application (SPA) in addition to the reduced traffic congestion due to Ajax requests, there is a static front end. This means fewer attack surfaces and lower costs, so you can store all of your content on Amazon S3 and keep Amazon safe, without a security technology team or your security technology team that is not as good as Amazon's expertise in this area. It's great to have Amazon provide security assurances. The disadvantage of spa is that there is a lack of certificate support for custom HTTPS (custom HTTPS certificate supports). You need to move to Amazon CloudFront (CDN), which is easy to implement, and it will improve the usability of your web app. The disadvantage is that you need to handle folder invalidation (assets invalidations), but not too much. They use some version management techniques that use filenames, though they are bad, but there is always better than nothing.


Avoid JSONP reaction instructions and multiple JS files (even ad networks) on third-party websites: If you allow third-party websites to inject JavaScript code into your site and trust them without reservation, the result is an increased likelihood of your site being attacked. Be careful with the APIs that respond to data, and don't let them be executed easily. Look at the case of Troy Hunt.


do not leave HTML annotations: Some security tools can be used to search for HTML comments and present them to an attacker to see if there is any use, such as owasp WebScarab. Delete the HTML comment. If you need comments, add comments using dynamic language when the page is generated, and the comments will not appear in the response.


client-side validation (server side of course also executes): The server checksum can not be replaced, there are two advantages: 1) Better user experience, because the feedback quickly, 2) block the background of useless requests, thereby improving the effectiveness.


exit (logout) should be visible on every page: Please do not forget this. Preferably in the desired place, such as clicking on the user's avatar after the top right corner.


If you store data on the client, be careful: the same threat applies to mobile, and to other customer-stored devices, which can cause data loss and theft. If you store the data on the client, assume that someone will see it, so don't store important information. The store is encrypted, and the key is stored in a cookie (no httponly tag that can be read by JavaScript), at least until the end of the current session. Delete all information when the user logs off. Depending on the data, you may want to use techniques such as HMAC to prevent integrity violations (integrity violations). Anyway, remember to use it like this. Of course, the server must also save the key. When used with the session storage mechanism, rails ' cookies are used in conjunction with the server's app secret. To reinforce this concept, you can use the JSON Web Tokens (JWT), which is currently doing this (data + signature + algorithm used + expiration + base64 encoding + JSON format) The standard.


consider replacing the session with a JSON Web Tokens (JWT): You can make a stateless server dependent on JWT, not a session and a database. The disadvantage is that the confidentiality of poor, see a piece on the know. This method can improve the effectiveness of the application and, if stored in localstorage instead of cookies, can also prevent csrf attacks. CSRF occurs when the browser is unresponsive (dumbness), even if cross-domain requests, the cookie also has the risk of being transmitted to the server.


Remember , Localstorage will be affected by XSS, and the cookies identified by HttpOnly will not: Although this facilitates storing session identifiers (cookie w/httponly identification), there is still a risk of csrf. This is a trade-off, remember this one.


server-side server


Choose a web framework, at least MVC: away from the script that builds the Web application. The most commonly used frameworks have given you some protection (for example, csrf protection, security header), and if you are writing PHP, use them directly. However, be careful that you may fall down on the following line:


avoid being too whimsical: I think this is the most common flaw in developers. They are very satisfied with certain useful functions or frameworks and blindly believe in them. This leaves room for many security vulnerabilities and bugs to occur. The most common example is the OAuth library. Before using SSO, be sure to understand the details of its work. Otherwise you will fail authentication. There is no free lunch during the development process. Before developing, insert some unknown code into your application, do some code review, static analysis, check for known bugs (CVE), and read the RfC if possible, but don't do it blindly, especially in key parts of the Web application, such as authentication, authorization, Liability and payment processing/stored value cards.


Verify Cors Source (cors origin): unless you intend to open the API to the entire world, you should only allow the source address of a single page app to be called to avoid in-browser (In-browser) calls to other sites.


The default setting cookie identifies HttpOnly: HttpOnly identifies that more cookies are required, which prevents JavaScript from accessing cookie values (such as session cookies), which protects the information in cookies, even if XSS occurs. In fact, with all due respect, HttpOnly should be the default property, Non-httponly only used in exceptions. Cookies that do not have this identity can only be used for client access, such as an identifier that shows or hides a menu based on user preferences. Localstorage's support for it is also good, so we should no longer use cookies without httponly.


The default is to set the secure flag for cookies:The secure flag allows cookies to be transmitted only over HTTPS connections, which is great, but you need to have an HTTPS port monitoring tool. Today, it should be a must-have setting, not only for security, but also to increase your Google search query rankings. As far as I know, you can not use a custom certificate on Amazon S3. You need to deploy your custom certificates to Amazon CloudFront (CDN), which is harmful to your keys, but there is no choice for small teams. CloudFlare thought of this, developed a no-key SSL, but you need to build a server that can handle all the SSL handshake, at least the use of this key part of the header, which also means more servers and higher costs.


Avoid business logic bypass: One of the most common pitfalls is authorizing bypass, and even on Facebook you can see this happening. For example, when editing the details of a user account, can you ensure that your app can block this update if the user enters user_id that is embedded in another user? You need to be careful on all controllers. This is usually a validation that some developers have to implement themselves, so it is often overlooked or difficult to see. Test it yourself and invite someone with a background in the security program to test it and even do some unit tests to verify your controller. The mass distribution Vulnerability (MASS Assignment vulnerability) is also noteworthy, and Homakov exploited it to attack GitHub. You'll need to whitelist your model parameters, or the attackers will use the "framework Magic" to build out the model objects by guessing their names.


Place CSRF protection in your API: The web framework generally recommends that you use CSRF protection, and when you build the API, you see a message that "CSRF token is missing in the request" and you generally disable it after you continue coding. Don't do that. CSRF is really dangerous, remind yourself to make sure to add a CSRF token, even when the API is being invoked. You can do this in the following 3 ways:


① stateful session: Add CSRF random tokens to each session to check if they match in each request.


② stateless Dual Cookie Submission technology: Attackers can manipulate the request body, but cannot manipulate cookies because they come from another domain, send the same random values to the server in a cookie and request, and check if they match If your users (or third-party scripts, such as ads) can control any subdomain, there are some techniques you can bypass. Get more information from Blackhat's articles.


③ stateless JSON Web Token: stored in localstorage and sent in each request. An attacker could not access a cross-domain localstorage.


don't let all operations get access to all of your AWS account resources: You don't waste too much time finding the right license for the AWS access credentials you apply. Don't be foolish enough to allow access to everything. If you upload a key to a public GitHub library, you're done, you'll be attacked, and you'll have to set permissions to reduce the risk.


do not store the certificate in the source code: read the certificate from an environment or file other than the source code deployment. It's a bit of a hassle at first, but some libraries make it very easy, like Ruby's dotenv gem.

When making a service-to-server communication, verify the endpoint certificate (endpoint), consider the pin it or its public key: When you browse some HTTPS websites, the browser validates its trusted CA. But who does the verification when you are communicating from the server to the server? Usually no one, so you need to set your own logic to verify the endpoint certificate. Before verifying the pass, do not allow other operations, otherwise SSL/TLS is meaningless. In addition to encrypting data during transmission, another goal of HTTPS is to verify the authenticity of the endpoint, thus preventing man-in-the-middle attacks. Consider using certificate pinning (Certificate pinning), or a better public key pinning. Owasp has a very good article explaining this in detail, so I won't repeat it. The basic thing is that you can only talk to the person you expect, for example, generate a Digest (digest) from a given X509 certificate and compare it to a hard-coded digest (coded Digest). However, there is a problem, if the certificate is revoked or changed, the service will be rejected. A better choice is to use a public key lock, because the public key exists in the X509 certificate, and unless the certificate is regenerated with a different key pair, it can be successfully verified by the public key, whether it is revoked or changed. These are also necessary for mobile applications.


Set security Headers: Protect Web Apps against click Hijacking (Clickjacking), reflective XSS (reflected XSS), and IE content detection by setting a security header in the response (ie Content guessing) attack (note: If you send the configuration correctly, Ruby on rails can do most of the work for you). For more details, please see the owasp page.

①x-frame-options: Use "Deny" or "homologous" to prevent "click hijacking".


②x-xss-protection: "1;mode=block" forces XSS reflection protection, which is default in chrome and not supported in IE.


③x-content-type-options: "Nosniff" Unfortunately, ie tries to guess the content of Web pages, even if this content/type means other content types. If IE detects HTML code, it will allow the TXT file to execute the script. Disable it by using this header.


④strict-transport-security: "Max-age=16070400;includesubdomains" HTTP strict-transport-security (HSTS) guarantees security ( HTTP through SSL/TLS) connection to the server. The browser will force HTTPS, even if it is a user-types HTTP, which is great.


There are other ⑤, such as content Security Policy (CSP), which are not discussed here.


Use the verification code on the "Sign Up" and "Forget password" pages: thanks to Google's reCAPTCHA, today's verification code is not very annoying. Today, you can verify whether the user is based on his behavior rather than just the human challenge, thus preventing fake accounts and sending crazy emails.


store the API key as you would store the password (or as much as possible): If the impact of both leaks is the same, then why is it safer to store one than the other? There are actually some differences, but the key is not to store the API keys in clear text. The API keys should be system-generated random characters, so they are not subject to dictionary attacks (dictionary attack), just like passwords, but in the database/filesystem/OS, the API key will be available in unencrypted text or data. In other words, at least some hash is necessary. If you use a tool like Scrypt or bcrypt, you need to be careful. Scrypt or bcrypt is highly recommended for passwords because of its slow hash calculation. A slow hash calculation can also cause the service to be rejected. You enter the password once to get a session ID, but the API is different and the API verification is always called, so slow slows down the usability of the application. A summary of the storage API key is sufficient to meet your application using the SHA256 or SHA512 algorithm. Stay away from MD5 and SHA1. Be sure to stay away!


at least use the UUID as the primary key for the user, not the sequential ID: prevent user account guessing/brute force cracking and easy copying. There are more advantages and fewer disadvantages, but it is worthwhile. Note: The UUID does not make the application more secure than a sequential integer, and only increases the non-speculative and fuzzy degrees from the security dimension.


token of forgotten Password and email confirmation: When generating a token for a forgotten password or email confirmation, make sure to use a secure pseudo-random number generator (rpng), otherwise you might be guessed. Use a library/language API that you can trust. Also set the due date/time for this token. Imagine a scenario where the user doesn't want to change their password, but a week later someone intercepts the email, accesses the URL, and changes his password. This is an unnecessary risk.


notify old mailboxes when a mailbox is updated: the most common behavior after an account infringement is to change the account's email address to prevent its owner from recovering the password and logging in, so be sure to send an email to the past e-mail and add an option to the recovery process. That's what Facebook does. This trick also applies to sensitive data updates. Regardless of who is in action, the account owner must be notified.


Disable port 80 instead of redirecting to 443: doing so will increase the attack surface. If port 80 is not needed, disable it. Remember, your API should only be monitored in 443. If you want to redirect from 80 to 443, work in < Insert CDN name > This option.


always use the generic class error message: Remember to always use common error messages, for example, when trying to login, do not say "Invalid Username or invalid password", just say "Invalid certificate", so that brute force is more difficult, although you can enumerate e-mail at the time of registration, Because your system may (and should) make each account's email address unique. If your application produces an exception, just say "error", do not expose the exception stack. I also recommend that you use some methods to collect all the exceptions and send them to your mailbox or show up on the dashboard of Raygun, Sentry, Airbrake.


confirm the user's e-mail address or phone: before sending an e-mail or notification, confirm that the mailbox or phone belongs to the user. The recommended approach is non-blocking, which allows users to log in without confirmation, but it also affects the use of online users. Look at Facebook: You can use unconfirmed accounts for 1 days. After that, you must confirm the email or phone before you sign in. I used to think about 10 minutes after the mail failed. Such services as mentioned above, the benefits are not to send mail to users who do not need them, but to keep you from being labeled as spam by users.


other aspects (no exclusion of other security measures)


don't choose them because your suppliers have cool features or low prices: Your data is dangerous, and your reputation is dangerous. There is a principle called "Don't trust", which means you need to be careful before you trust. Reducing your trust is also a good thing. The more you believe, the more dangerous it is. In other words, I usually recommend safety first. At first BitBucket seems to be cheaper than GitHub, but it does not have two-factor authentication. How much is your source code worth? AWS has sparked competition in the public cloud market, and they seem to do a great job when they start to focus on the security of sensitive information. So just in the case of cheap price is not enough to let me change a service provider. All things have to be taken into account, but be aware that static pages accept anything, and often see the corporate homepage claiming that they have secured the site via APT and SSL (deprecated). Try not to believe easily, when you trust, first verify!


(REST) API-oriented development: If you look at AWS, you'll see that the API is first, then the Web UI, and finally the SDKs. The API is scary because it is language independent. But I personally think that this is the inevitable trend of future development. It is also worth careful observation of the HATEOAS. It makes visual isolation between parts easier. The client is a static page, and the server is the brain that receives input and produces output for the front end. It separates roles and records more explicitly, such as the Web server must validate the input. Otherwise, the Web application of the non API is more confusing.


entrusted credit card: It is a good idea to delegate risk to a trusted entity. If you do it yourself, store your credit card data from the start and think about how much responsibility you have to take. Will it be better if you entrust a trusted payment provider, such as Stripe or PayPal? I think it will, unless you can do it better. So, make sure your app doesn't touch credit card data. You can redirect to their website to complete the process.


where are we going now?


There is too much information to search for it. Owasp and Sans will help you a lot. They have a lot of projects, items, lists and tools. I also recommend that you follow your tools and vendor-related safety recommendations. In addition, often go to Reddit/r/netsec stroll.

Original address: Http://www.jointforce.com/jfperiodical/article/933?f=jf_tg_bky

Security guidelines for building modern Web applications

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.