Hello. Under the cut - translation of the article by Jeff Atwood, in which he lists the 25 most dangerous mistakes in programming from Common Weakness Enumeration with his comments.
Just want to say. Most of the mistakes listed there are well known and filled with many. Despite this, we continue again and again to attack the same rake. And me as well. If you are developing in any capacity, at least read this list diagonally. If something is unfamiliar to you or is of interest, I recommend to follow the link for a more detailed description (English)
Insufficient input validation Make sure your input is correct. If you expect a number, there should be no letters. As well as the price of a new car can not be equal to the dollar. Incorrect input validation can lead to vulnerabilities where an attacker can change the input in an unexpected way. Many of the most common vulnerabilities known today can be avoided or at least reduced by using strict input validation.
Insufficient output encoding or shielding Insufficient output encoding is the root of most injection-based attacks. The attacker can change commands that you have to send to other components, which can lead to a complete compromise of your application - I'm not talking about the execution of exploits on other components that the attacker can not run directly. When your program generates output for other components in the form of structured messages, such as queries, make sure that the control information and metadata are separated from the data itself. ')
Violation of the SQL query structure (aka "SQL injection") If attackers can affect the SQL that you send to the database, they can change your queries to steal, damage, or change the data in it. If you use SQL queries to manage security, such as authentication, attackers can change the logic of these queries and bypass the security.
Violation of the webpage structure (aka "Cross-site scripting", "XSS") Cross-site scripting (XSS) is the result of HTTP combining, which by its nature does not save state, mixtures of data and scripts in HTML, large amounts of data transferred between websites, diverse coding schemes, and rich web browsers. If you are not attentive enough, attackers can inject Javascript or other browser-executable code into the page that your application generates. Then your page is visited by other users whose browsers run this fraudulent script as if it came from you - because, after all, it did come from you! Unexpectedly, your website provides a code that you did not write. Attackers can use various techniques to inject such code onto your server directly or using an unsuspecting victim as an intermediary.
Violation of the OS command structure (aka "OS Command Injection") Your program works as a bridge between a stranger on the network and the insides of your operating system. If you run another program in the operating system, allowing you to transfer questionable parameters to the command line, you invite intruders into your operating system.
Transmission of important information in clear text Information transmitted over the network passes many different nodes along the path to the final goal. If your program sends important, personal information or authentication data, beware: attackers can intercept it along the way. All they need is to gain control over one of the nodes on the way to the final goal, any node on the same subnet of transit nodes, or connect to an available interface. Obfuscating traffic using Base64 or URL coding provides no protection.
Cross-site request forgery (XSRF) Cross-site request forgery is how to take a package from anyone - with the difference that the attacker forces the user to activate the HTTP request that goes to your site. The user may not even guess that the request has been sent, however, when he gets to the server, he looks as if he came about a user, not an attacker. The attacker disguised as a legitimate user and gets all the possible rights that the user has. This is especially effective when the user has administrator privileges, completely compromising the functionality of your application.
Race condition A race condition involves multiple processes in which an attacker has full control over one of them; The attacker uses the process to create chaos, collisions, or errors. An impact can be local or global, depending on what affects the state of the race (for example, the state of variables or the security logic), and also occurs between multiple threads, processes or systems.
Information leakage through error messages Excessively "talkative" error messages can reveal secrets to any attacker who misuses your program. These secrets can cover a wide range of relevant data, including personal information, authentication data and server configuration. This data may look like innocent secrets, convenient for users and admins, for example, the complete installation path of your program - but even these little secrets can simplify a more planned attack.
Violations of control over operations at the boundaries of the memory buffer The scourge of C applications for decades, buffer overflows are extremely resilient to destruction. Attack and detection methods continue to improve, and today's buffer overflow methods are not obvious at first or even at second glance. You can assume that you are completely protected from buffer overflow, because you write your code in higher-level languages than C. But what is the interpreter of your favorite "safe" language written on? What about the native code you are calling? What languages is the operating system API written in? What about programs that provide the infrastructure of the Internet?
External control of critical state data If you save user state data where an attacker can change it, it makes it easier to compromise. Data can be stored in configuration files, .files, cookies, hidden form fields, environment variables, registry keys, or other places where they can be modified by an attacker. In stateless protocols such as HTTP, some forms of user state information can be intercepted in each request, that is, they are open to the attacker unnecessarily. If you, based on this data, perform any security-critical operations, you can bet that someone will change this data to trick your application.
External control over the file name or path When you use the input to build a file name, the resulting path may not point to the intended folder. An attacker can combine several ".." or similar sequences to get out of a restricted directory. Other file-related attacks are simplified when externally controlling a file name, for example, following symbolic links, which causes your application to read or change files to which an attacker does not have direct access. The same applies when your application is running with elevated privileges and accepts a file name as input. Similar rules are true for URLs and allowing outsiders to specify arbitrary addresses.
Unreliable search path Your application depends on you, or on your environment, in terms of providing a search path (or working path) for critical resources, such as code libraries or configuration files. If the search path is controlled by an attacker, it can change it to point to resources selected by the attacker.
Uncontrolled code generation (aka "Code injection") Undoubtedly, it is difficult to deny the sexuality of a dynamically generated code, but attackers find it equally attractive. A serious vulnerability occurs when your code can be directly caused by unauthorized participants, if external input data affects the code to be executed or the data is inserted directly into the code itself.
Code download without integrity check If you download the code and execute it, you believe that the source of this code is not fraudulent. But attackers can change this code before it reaches you. They can hack the site from which you are downloading, imitate it with DNS spoofing or cache “poisoning”, convince the system to redirect to another site or even change the code on the way through the network. This scenario applies even to cases where your own product downloads and installs updates.
Incorrect closure or release of resources When your system resources reach the “end of their life”, you get rid of them: memory, files, cookies, data structures, sessions, communication channels, and so on. Attackers can use the wrong closure to keep control of these resources when you already think you have gotten rid of them. Attackers can sift them in search of important data. They can also theoretically reuse this resource.
Incorrect initialization If you do not initialize your data and variables correctly, an attacker may be able to initialize them for you or obtain important information left over from previous sessions. If these variables are used in security-critical operations, such as deciding whether to authenticate, they can be modified to bypass your protection. This is the most likely reason why your code suddenly initializes with strange errors and conditions.
Wrong calculations When intruders control the input to numerical calculations, mathematical errors can have security implications. They can make you allocate significantly more resources than you need - or significantly less. They can disrupt business logic (calculations that return a negative price) or cause a denial of service (division by zero, resulting in a program crash).
Insufficient access control (Authorization) If you do not verify that application users are doing only what they are allowed to do, attackers will try to use incorrect authorization and play with unauthorized functionality.
Using a cracked or risky cryptographic algorithm Self-made cryptography - an invitation for intruders. Cryptography is complicated. If ingenious mathematicians and computer specialists cannot give it a tune - and they periodically recognize their own methods as obsolete - and you will fail.
Hard coded password Prescribing a secret account and password in the code of your application is very convenient - for expert analysts. If the password is the same in all of your applications, each client of yours becomes vulnerable when this password inevitably becomes known. And since it is hardcoded in the code, fix it is a big headache.
Unsafe assignment of permissions to a critical resource Watch out for critical programs, data warehouses and configuration data with readable default permissions. Although this problem may not be addressed during implementation or development, it should. Do not require your customers to make your application safe for you! Try to provide security by default, out of the box.
Using insufficient random values You can depend on randomness, even when you are unaware of this, for example, when generating session identifiers or temporary file names. Pseudo-random number generator (PRNG) is used everywhere, but a lot of things can go wrong. Once an attacker can determine which algorithm is being used, he can guess the next random number often enough to make a successful attack after a relatively small number of attempts.
Run with unnecessary privileges Your program may require special privileges to perform certain operations; having these privileges longer than necessary is risky. When working with extra privileges, your application has access to resources that users of the application cannot directly use. Each time you launch a separate program with elevated privileges, attackers can theoretically use these privileges.
Client-side server security Do not trust the client to perform security checks on behalf of the server. Attackers can analyze your application and write their own clients. The implications depend on what your security checks protect, but the main goals are authentication, authorization, and input validation.
Of course, there is nothing truly new here; I seriously went through the same basic list in the book “Sins of Software Security” almost two years ago. The difference is only in relative priorities, as web applications begin to dominate in the main thread.
The list of application security bugs serves the same purpose as the classic McConnell design bugs list: raise awareness. A surprisingly large part of success is recognizing the most common errors and failure states. So you can - at least in theory - realize when your project moves to one of them. Ignorance is the worst killer of software projects.
In the translation and design of the text I was helped: