Base · Medium

CWE-93: Improper Neutralization of CRLF Sequences ('CRLF Injection')

The product uses CRLF (carriage return line feeds) as a special element, e.g. to separate lines or records, but it does not neutralize or incorrectly neutralizes CRLF sequences from inputs.

CWE-93 · Base Level ·6 CVEs ·2 Mitigations

Description

The product uses CRLF (carriage return line feeds) as a special element, e.g. to separate lines or records, but it does not neutralize or incorrectly neutralizes CRLF sequences from inputs.

Potential Impact

Integrity

Modify Application Data

Demonstrative Examples

The following code segment reads the name of the author of a weblog entry, author, from an HTTP request and sets it in a cookie header of an HTTP response.
Bad
String author = request.getParameter(AUTHOR_PARAM);...Cookie cookie = new Cookie("author", author);cookie.setMaxAge(cookieExpiration);response.addCookie(cookie);
Assuming a string consisting of standard alpha-numeric characters, such as "Jane Smith", is submitted in the request the HTTP response including this cookie might take the following form:
Result
HTTP/1.1 200 OK...Set-Cookie: author=Jane Smith...
However, because the value of the cookie is composed of unvalidated user input, the response will only maintain this form if the value submitted for AUTHOR_PARAM does not contain any CR and LF characters. If an attacker submits a malicious string, such as
Attack
Wiley Hacker\r\nHTTP/1.1 200 OK\r\n
then the HTTP response would be split into two responses of the following form:
Result
HTTP/1.1 200 OK...Set-Cookie: author=Wiley HackerHTTP/1.1 200 OK...
The second response is completely controlled by the attacker and can be constructed with any header and body content desired. The ability to construct arbitrary HTTP responses permits a variety of resulting attacks, including:
The following code is a workflow job written using YAML. The code attempts to download pull request artifacts, unzip from the artifact called pr.zip and extract the value of the file NR into a variable "pr_number" that will be used later in another job. It attempts to create a github workflow environment variable, writing to $GITHUB_ENV. The environment variable value is retrieved from an external resource.
Bad
name: Deploy Preview
		jobs:
		
		  deploy:
		  
		    runs-on: ubuntu-latest
		    steps:
		    
		      - name: 'Download artifact'
		      uses: actions/github-script
		      with:
		      
			script: |
			
			  var artifacts = await github.actions.listWorkflowRunArtifacts({
			  
			    owner: context.repo.owner,
			    repo: context.repo.repo,
			    run_id: ${{ github.event.workflow_run.id }},
			  
			  });
			  var matchPrArtifact = artifacts.data.artifacts.filter((artifact) => {
			  
			    return artifact.name == "pr"
			  
			  })[0];
			  var downloadPr = await github.actions.downloadArtifact({
			  
			    owner: context.repo.owner,
			    repo: context.repo.repo,
			    artifact_id: matchPrArtifact.id,
			    archive_format: 'zip',
			  
			  });
			  var fs = require('fs');
			  fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(downloadPr.data));
			
		      
		      - run: |
		      
			unzip pr.zip
			echo "pr_number=$(cat NR)" >> $GITHUB_ENV
Attack
\nNODE_OPTIONS="--experimental-modules --experiments-loader=data:text/javascript,console.log('injected code');//"
Good
The code could be modified to validate that the NR
		file only contains a numeric value, or the code could
		retrieve the PR number from a more trusted source.
If user input data that eventually makes it to a log message isn't checked for CRLF characters, it may be possible for an attacker to forge entries in a log file.
Bad
logger.info("User's street address: " + request.getParameter("streetAddress"));

Mitigations & Prevention

Implementation

Avoid using CRLF as a special sequence.

Implementation

Appropriately filter or quote CRLF sequences in user-controlled input.

Detection Methods

  • Automated Static Analysis High — Automated static analysis, commonly referred to as Static Application Security Testing (SAST), can find some instances of this weakness by analyzing source code (or binary/compiled code) without having to execute it. Typically, this is done by building a model of data flow and control flow, then sea

Real-World CVE Examples

CVE IDDescription
CVE-2002-1771CRLF injection enables spam proxy (add mail headers) using email address or name.
CVE-2002-1783CRLF injection in API function arguments modify headers for outgoing requests.
CVE-2004-1513Spoofed entries in web server log file via carriage returns
CVE-2006-4624Chain: inject fake log entries with fake timestamps using CRLF injection
CVE-2005-1951Chain: Application accepts CRLF in an object ID, allowing HTTP response splitting.
CVE-2004-1687Chain: HTTP response splitting via CRLF in parameter related to URL.

Taxonomy Mappings

  • PLOVER: — CRLF Injection
  • OWASP Top Ten 2007: A2 — Injection Flaws
  • WASC: 24 — HTTP Request Splitting
  • Software Fault Patterns: SFP24 — Tainted input to command

Frequently Asked Questions

What is CWE-93?

CWE-93 (Improper Neutralization of CRLF Sequences ('CRLF Injection')) is a software weakness identified by MITRE's Common Weakness Enumeration. It is classified as a Base-level weakness. The product uses CRLF (carriage return line feeds) as a special element, e.g. to separate lines or records, but it does not neutralize or incorrectly neutralizes CRLF sequences from inputs.

How can CWE-93 be exploited?

Attackers can exploit CWE-93 (Improper Neutralization of CRLF Sequences ('CRLF Injection')) to modify application data. This weakness is typically introduced during the Implementation phase of software development.

How do I prevent CWE-93?

Key mitigations include: Avoid using CRLF as a special sequence.

What is the severity of CWE-93?

CWE-93 is classified as a Base-level weakness (Medium abstraction). It has been observed in 6 real-world CVEs.