Shortcut to seniority
Home
Go to main page
Section level: Junior
A journey into the programming realm
Section level: Intermediate
The point of no return
Section level: Senior
Leaping into the unknown
                    Go to main page
A journey into the programming realm
The point of no return
Leaping into the unknown
A vulnerability is a defect in security due to errors in implementation or specification. All the major vulnerabilities need to be treated very seriously, as it can do a lot of damage to the company itself, from either costing it tons of money, to its reputation, and even destroying the business entirely and forcing it to eventually close.
A cyclic redundancy check (CRC) is an error-detection code to detect accidental changes to raw data. Blocks of data get a short value attached, based on the remainder of a polynomial division of their contents. On retrieval, the same calculation method is performed and in case the values do not match, it means that the data has been corrupted and correction actions can be taken.
Reverse engineering is the process by which an object is deconstructed to reveal its design or its flows.
The MD5 algorithm is a widely used hash function that produces a 128-bit hash value. It is used as a checksum to verify data integrity, but only against unintentional corruption.
A backdoor is a term used to define the path used to gain access over a system by bypassing the authorization procedure. This happens if the functions that are responsible for the authorization or functions that require non-user access are not properly secured.
C&R Authentication is a family of protocols in which one party presents a question (“the challenge”) while the other one must provide a valid answer (“the response”) in order to be authenticated.
The simplest example of C&R is authentication through password, where the challenge is simply asking for the password, while the valid response is inserting the correct one.
A compromise occurs when the level of security is affected by an action, such as leaking of the encryption keys.
Kernel mode or privilege mode is an operating mode of the CPU, and it allows code to have direct access to all hardware and memory in the system. In this mode, any program or command can be executed, and any memory location can be accessed.
Kernel mode is reserved for low-level functions of the operating system. If the code crashes while in kernel mode, the kernel will enter the panic state (kernel panic) and terminate.
User mode or non-privilege mode is the opposite of kernel mode – it’s a mode in which the capabilities to run commands, or access to the memory location is limited.
In User mode, the code that is being executed has no direct access to the hardware. In order to do so, it must use calls from the system API. Due to this protection, any crash that occurs in user mode is recoverable. Most of the code running on the computer is executed in user mode.
SQL injection is a code injection technique used to attack data-driven applications, in which the malicious user attempts to exploit a security vulnerability in which the user input is not validated or filtered properly before passing it as an SQL statement. This results in the potential manipulation of the statements performed on the database by the user.
A buffer overflow is a common mistake made by programmers that can be used by attackers to gain access to the software. In a buffer overflow, we provide to a fixed-length buffer more data than it can accomodate. The extra data overflows into an adjacent memory space, overwriting or corrupting the data that already exists there. A system crash is a typical result, but a buffer overflow also allows attackers to run arbitrary code or to use these coding errors to initiate malicious actions.
Uncontrolled format string is a software vulnerability that can be used in security exploits to crash a program or to execute harmful code. Such exploit uses a combination of these techniques to force an application to overwrite the address of a library function or the return address on the stack with a pointer to some malicious code.
Integer overflow is the result of setting a value of an integer to something that is too large to be stored in its size. Because the size is limited, there are only a number of bits that can be used, and the max value occurs when all those bits are set to 1. As example, if we use 1 byte as size, the maximum representable number is 28 – 1 (1111 1111 In binary, 0xFF in hex, or 255 as decimal). If the sum of two numbers is bigger than this value (255+1 for example), the number will overflow. Since the data is circular, an integer overflow will go negative (for signed types) or start from 0 (for unsigned values).
There’s no way we can predict what would happen if variables are not initialized, as it depends on where and how they are used in the software.
Uninitialized numerical variables are problematic when you use them as the divider in a calculation. In other cases, it could lead to errors in the program, such as integer overflows.
Uninitialized boolean variables can lead to unexpected behavior, due to the random nature of the initial value. This leads to inconsistency and may lead to loss of control over the application.
Pointer variables are usually set to an initial value of null, and if they are not set, will most likely contain a random address value. Once the program uses the pointer to access the memory and changes the value at the given memory address, this can crash the application or even the whole operating system.
You should never silently ignore errors. If you try to continue after an error, the application will continue based on invalid assumptions, and it will most likely further generate other errors. Applications like this are hard to debug, due to such false handling (bug inside a bug – a bug that occurs due to another bug, and that will no longer occur if the initial one is fixed).
Dangling / wild pointer bugs, similarly to buffer overflows, become security holes. If the pointer is used to make a virtual function call, a different address (pointing at exploit code) may be called due to the vtable pointer being overwritten. If the pointer is used for writing to memory, some other data structure may be corrupted. If the memory is only read from a dangling pointer, it can lead to information leak or to privilege escalation. When a pointer is used after it has been freed, this is known as a “use after free” vulnerability.
Computer hacking is the activity of gaining unauthorized access to computers and technology dependent systems. These activites involve modification or alteration of the software or hardware in order to perform activities that could have negative consequences, which were not originally intended by the creator of the software.
A brute force attack is a trial-and-error method usually used for authorization attempts. Brute force is time and resource consuming, in which success is usually based on computing power and the number of combinations tried.
An example of a type of brute force attack is a dictionay attack, in which an automated software will try all the words in a dictionary. Another form of brute force attack might be to try commonly-used passwords or combinations of letters and numbers.
There are a number of measures that can be taken to defend against a brute force attack, such as:
Social engineering is the art of manipulating people so they disclose confidential information. Social engineering tactics are easier to exploit than discovering ways of hacking a software. For example, it is much easier to trick someone into giving away their password instead of trying to hack it yourself.
Common social engineering attacks include:
Security exploit (vulnerability) is an unintended and unpatched flaw in a software that exposes it to potential exploitation by hackers or by using malicious software such as viruses, works, or other forms of malware. Security exploits result from a combination of software bugs, weak passwords, or software already infected by a computer virus or worm. In order to prevent the unauthorized access, these security exploits require software fixes (patches).
Trojans are malicious computer programs which usually spread through social engineering (e-mail attachments, fake ads etc.). They usually act as a backdoor, allowing unauthorized personnel to have access to the affected computer. Once it’s in, it can also infect other devices connected to the same network. Ransomware attacks are usually carried out through a trojan.
A rootkit is a collection of malicious software designed to allow computer / software access to unauthorized users.
A DDoS attack is the bombardment of simultaneous data requests to a central server. The attacker generates these requests from multiple compromised systems.
By doing so, the goal of the attacker is to crash the system by exhausting its bandwidth and RAM.
Input Validation should be done for any input that is supplied by anyone else. Input could come from multiple sources, such as the end user, another application, or from a malicious user. Since there’s no way to differentiate a normal user from a malicious one (that is there to attack your software), all input should be checked and validated. Testing all input could protect against a future potential security hole and vulnerability in the software.
There are multiple vulnerabilities that can be solved through input validation, such as Buffer overflows, Injection and DDoS attacks, memory leaks, and disclosure of information.
As a developer, you should always assume that you’ll receive something you don’t expect.
When validating the data, you should always do whitelists instead of blacklists: Check for the valid types and exclude all the others. If you were to check for invalid types, the list could be either incomplete, or complete but unsafe in the future.
The code should be compiled under the highest warning level available and all the warnings should be fixed by changing the code. Static and dynamic code analysers should be used when available in order to detect and eliminate security flaws.
The design should be kept as simple and small as possible. Complex designs increase the likelihood that errors will be made in implementation, configuration, or use.
Default deny implies that access decisions should be on permissions rather than on exclusions. This means that the access should be denied by default, and authorize only specific people.
In other words, instead of keeping a blacklist, which should be maintained with those who should not have access, we should have a whitelist, and the system should authorize only those within the whitelist.
Every process should execute with the least set of privileges necessary to complete its job. Any high permissions should be held for a minimum time. This approach reduces the opportunities an attacker has to execute arbitrary code with elevated privileges.
The concept refers to clear all the data before passing it to systems that would act on that data. Attackers will attempt to inject bad code through the use of SQL, for example, and it’s not the input validator’s problem because that subsystem does not understand entirely the context in which the call is made or how the data will further be used. The validation should be performed twice, once to assure that the input is valid (non empty, correct data type, etc), and another one before feeding that data to the subsystem which uses it.
Good Quality Assurance techniques can be effective in identifying and eliminating vulnerabilities. Source code audits, software penetration testing, and static analyzers should be incorporated in the process, to assure that the system is highly secured.
You should apply a secure coding standard for your target development language and platform.
Security requirements should be identified and documented early in the development life cycle. Subsequent development artifacts should be evaluated for compliance with these requirements as well, to assure that the system can be effectively evaluated.
You should anticipate the threats that may occur in the software. To do so, you should decompose the application and identify key components, and rate the possible threats based on a risk rating, along with a plan to mitigate such threats.
The only reason you should build something by yourself is when you need something that doesn’t exist, or exists but doesn’t fit the needs (missing features, low performance). Frameworks, features, code should be reused, as they are stable and well tested, which reduce the chance of bugs or security flaws in the application.
No code should be trusted, no matter if other people wrote it or even ourselves. In big projects, there are many people involved, and each of them can have different ways of writing and organizing their code.
Package diagram is a view displaying the coupled classes and their encapsulation into a group (similar to namespace).
Activity diagram is a view representing the flow from one activity to another, describing an operation within a system.
Reserve is a function that pre-allocates a specific memory size, to accommodate new data.
The act of exploiting a bug in order to get administrator access.
Composition refer to two classes (composite and component) in which one of them (composite) contain an instance of the other one (component), creating a ‘has a’ relationship. The composite object has ownership over the component, meaning that the lifetime of the component object starts and ends at the same time as the composite class. In simple terms: A class contains an instance of another class.