In the previous article, I discussed a number of common attacks, including credential theft, SQL injection, cross-site scripting, and many others, as well as some tips for preventing those attacks. This article discusses the remainder of the common security attacks covered in the web security course I recently completed.
Be careful with what you store in cookies. While browser cookies may seem like private data, they are not quite as private as you might think. Not only can users inspect their own cookies, but their data can be visible to attackers while in transit. Cookie data is sent in the header of requests to the server, and if an attacker can see network traffic (which could easily happen on an unsecured network), they can see the cookie data. XSS attacks can also be used to get cookie data.
"Stealing" a cookie refers to a situation where an attack takes the information from a user's cookie and inserts those values into their own browser's cookie. It can also refer to a situation where the attacker sends a forged request with the user's cookie data. Alternatively, an attacker could modify the user's existing cookie to serve their own purposes.
While cookie theft can be serious, there are some methods that the course suggests to protect against damage from cookie theft:
- The best prevention is to not put anything of value in the cookie data. Storing harmless information in a cookie, such as a user's language preference, is perfectly safe. Storing an access token in the cookie that allows the user to access privileged data is not so safe. Session data should also not be stored in the cookie (although a session ID can be stored there to be sent to the server when you need to confirm that a session is valid).
- Websites should be set up using SSL certificates so that HTTPS can be used. This encrypts all communication between the browser and the server and prevents attackers from seeing the cookie data in transit. Secure cookies, which are only sent over HTTPS (and would not be sent if the user manually typed in HTTP), should be used together with SSL for extra security.
- Cookies should be given expiration dates, set either using
Max-Age(if both are set, Max-Age has precedence over Expires). When the cookie reaches its expiration date, it will be deleted by the browser, which helps in cleaning up old cookies.
- By default, a cookie is available throughout a domain, including on all subdomains and all pages. If a cookie will only be needed in a certain subdomain or within one directory, then it should be restricted to that directory using the
Pathattributes. This may not be appropriate for all situations, but it is always worth considering whether the principle of least privilege should apply to cookies.
- If sensitive data is being stored in the cookie, then it should be encrypted. Encrypted cookies are never in plain text, whether in transit or in storage.
- Cookies can be digitally signed (which means running it through an algorithm to get a checksum that is added to the end of the cookie data) to prevent modification. When the cookie data is received by the app, the value will be run through the same algorithm, and it will only be accepted if the checksums match.
Session hijacking is when an attacker steals ("hijacks") a user's active session to gain unauthorized access to restricted parts of a website. While sessions should store user data in a file or database on the server, a session identifier is often stored in the browser cookie and is vulnerable to theft. If an attacker gains access to the user's session, they can access all of the data stored in that session, or worse, they can impersonate a logged-in user. Once the attacker gains access to a logged-in user's session, the server treats the attacker as that logged in user. The attacker can do anything that the user can do - transfer money, view personal information, edit account credentials, send messages as the user, etc.
Several defenses can be employed to protect against session hijacking:
- Keep cookie data (and the session IDs stored in cookies) secure (see above for some examples of that). Cookies can be stolen through XSS attacks, so it's important to also have protections against cross-site scripting. Using HTTPS is an easy way to add security to your website, and is essential for login pages or any pages that should have restricted access.
- Expire and remove old session files. Fewer sessions stored means fewer sessions that can be hijacked.
- Regenerate session identifiers periodically and at key access points in the app. Regenerating a session ID invalidates any previous session IDs, which means that a stolen session is only valid until the next time the session ID is regenerated. One instance in which it is key to regenerate the session ID is after a successful login - we do not want to give a user with access to a logged out session access to the session once the user logs back in.
Session fixation is essentially the reverse of session hijacking - rather than hijacking a user's session, in a session fixation attack, the attacker gives the user a valid session ID that is controlled by the attacker. In both scenarios, the end result is the attacker and the user using the same session. However, in a session fixation attack, the session provided by the attacker is not yet authenticated, and the attacker has to wait for the user to log in to gain access to restricted pages.
Early session fixation attacks relied on websites which accepted session ID's sent in the URL or form data, but this is no longer common practice. However, session fixation is still a concern, as an attacker can set the user's browser cookie to their session ID through an XSS attack or a "person-in-the-middle" attack. In a person-in-the-middle attack, an attacker positions themselves in the line of communication between the browser and the web server, using malware or a hacked router (or some other technique). The attacker relays information from the browser to the server (and vice versa) but can manipulate that data without either party knowing.
How can we prevent session fixation?
- Only accept session IDs from cookies - never accept them as GET or POST variables. This is generally the default setting but is worth checking to be sure.
- Use XSS defenses (as listed above) to prevent an attacker from setting a user's session ID through an XSS attack.
- Automatically regenerate the session identifier after the user logs in - discard the old session ID and assign a new one. This renders the attacker's session ID useless, as it will never be attached to an authenticated session.
Remote code execution (RCE) is one of the worst types of attacks. RCE is when an attacker can remotely execute internal operating system commands on a server. To put it simply, an attacker can run commands on your server as if they were sitting at the keyboard acting as a logged-in user. Once an attacker has access to your server, they can read, add, modify or delete files, change access privileges or passwords, edit configurations, or communicate to other servers.
RCE is one of the worst attacks, but thankfully, it's also one of the hardest to pull off. Operating systems keep a wall between the operating system and the software running the web server, which is difficult to get through. Most programming languages have functions which allow them to communicate directly with the underlying OS (for example,
console.log() in NodeJS), and hackers can use these function to send their own data to the OS. It's best to not use these functions at all (often there's another solution using less risky code) or to disable them entirely (if your programming language of choice allows it). If you have no other option but to use one of these functions, avoid pairing it with user-submitted or dynamic data, and if that is not possible, ensure that you validate all data and use allow-lists to limit the range of data that can be entered.
Remote code execution attacks are very bad, but fortunately are not very common, and most occur because of developer carelessness.
File upload abuse is when an attacker abuses a website's upload feature in some way. The most common forms of abuse are uploading too many files, uploading files that are too large, or uploading files too frequently. Too many files or files that are too large can use up all of a server's storage space. Files uploaded too frequently can slow down server processing or monopolize server connections. File upload abuse can also take the form of uploading the wrong content type.
The most serious type of file upload abuse involves malware. Malware can pretend to be a different file type or can be embedded in files that otherwise seem legitimate. An attacker may upload malware and then use other techniques to move it to a different location or launch it. Malware can be used for many different goals, and ransomware (such as the attack on Garmin a few months ago which affected flight systems, as well as my ability to sync my runs) has become a major threat in recent years. Most ransomware encrypts all files and then demands a ransom to obtain the key needed to decrypt the files.
The instructor in this course recommended a few measures to protect against file upload abuse:
- The best way is to require users to log in before they can upload files - don't allow anonymous uploads. This won't prevent a determined attacker, but at least you'll have account information for the attacker and can revoke their access to prevent future attacks from that user.
- Don't make user-uploaded files available for public download (so that if malware is uploaded, you don't spread it). Store uploaded files in directories that are not publicly readable, and if they do need to become public, scan them for viruses and have a human review them for extra protection.
- Validate that the file has the correct content type or MIME type, and validate the file extension against a list of allowed extensions. You can also validate that the file size is below a set maximum file size.
- Using large hard drives or cloud servers can help ensure that there's always adequate drive space available, rendering some file upload abuse attacks (particularly ones that are intended to use up your server space) useless.
- Frequent file uploads can be limited or throttled by the server, the web application, or a firewall.
- Scan servers with antivirus software to look for malware that you may have missed through your other defenses.
Denial of service (DoS) attacks deny authorized users access to a server, service, or resource to which they would normally expect to have access. In a DoS attack, the underlying resource is generally not impacted, but the user's ability to access that resource is impacted. This attack is intended to impact the availability of data, not the data itself. Denial of service attacks usually use flooding or crashing to make data unavailable. Flooding is when a system is overwhelmed with too many requests, and crashing is when software or hardware stops operating
Denial of service attacks are rarely performed by a single computer, as most computers cannot muster up the amount of traffic necessary to shut down a well-designed server or router. More commonly, a distributed denial of service (DDoS) attack, which involves hundreds or even thousands of computers, will be used to bring down a resource. DDoS attacks can be controlled by humans, but are more often executed by zombie botnets, collections of internet-enabled devices with malware installed on them. An attacker sends commands to the botnet and can use all of the connected devices to launch simultaneous attacks. The biggest DDoS attack to date took place in February 2020 and was unsuccessful, as AWS was able to successfully mitigate the 2.3 Tbps attack.
Preventing DDoS attacks is challenging. The first question to ask is whether a DDoS attack is in your threat model. In most cases, the answer is no.
If your website is likely to be the target of retaliation, hacktivism, or extortion attempts (for example, a government agency website), the instructor of this course suggests outsourcing the problem and hiring a company that offers DDoS mitigation services. These companies will route all incoming traffic to your website through their servers, which are better equipped to handle the traffic.
If you see a spike in your website traffic, it may be legitimate traffic based on recent good press or changes in the need for your service. Increasing available RAM and deploying additional servers behind your load balancer are two ways to handle this increased load.
If you do discover an increase in malicious traffic, the instructor of this course recommends a few methods to deal with that traffic:
- Throttling your traffic, also known as rate limiting, regulates the flow of input to keep it below a maximum level, which slows down the attack.
- Filtering traffic applies a set of rules to that traffic, and only allows requests of a certain type or with certain characteristics.
- Sinkholing redirects traffic to a new destination.
- Blackholing is a more extreme version of sinkholing, where the traffic is rerouted to nowhere (also known as the null resource). Blackholing, along with sinkholing, filtering, and throttling, can all be done with the user of a firewall.
- Contact your ISP, who may be able to start blackholing traffic on their end immediately.
Knowing what attacks are commonly executed helps in developing a threat model and deciding on security defenses. Most websites will not be subject to all of the attacks listed in this article, but knowing which ones may impact your website is a great first step in deciding what security to employ.