Sablier

Sablier
DeFiFoundry
53,440 USDC
View results
Submission Details
Severity: medium
Valid

SVG Injection Risk in NFTSVG Library

Summary

The NFTSVG library generates SVG images for NFTs by concatenating strings based on input parameters. However, the library does not sanitize the input parameters before embedding them into the SVG output. This could potentially allow an attacker to inject malicious code into the SVG if user-supplied input is not properly handled.

Proof of Concept (PoC)

  1. A user provides the following malicious input for the status parameter:

<script>alert('XSS');</script>
  1. The generateSVG function is called with this input:

function generateSVG(SVGParams memory params) internal pure returns (string memory) {
// ... other code ...
// Generate the status card.
(vars.statusWidth, vars.statusCard) =
SVGElements.card({ cardType: SVGElements.CardType.STATUS, content: params.status });
// ... other code ...
return string.concat(
'<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 1000 1000">',
SVGElements.BACKGROUND,
generateDefs(params.accentColor, params.status, vars.cards),
generateFloatingText(params.sablierAddress, params.sablierModel, params.assetAddress, params.assetSymbol),
generateHrefs(vars.progressXPosition, vars.statusXPosition, vars.amountXPosition, vars.durationXPosition),
"</svg>"
);
}
  1. The resulting SVG contains the malicious script:

<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 1000 1000">
<!-- other SVG content -->
<script>alert('XSS');</script>
</svg>

When this SVG is rendered by a browser, the script executes, resulting in an XSS attack.

Impact

If an attacker can control the input parameters (such as accentColor, amount, assetAddress, assetSymbol, duration, progress, sablierAddress, sablierModel, and status), they could inject malicious SVG content. This content could include JavaScript, which might be executed by a client's browser when the SVG is rendered, leading to Cross-Site Scripting (XSS) attacks. Such attacks could result in the theft of cookies, session tokens, or other sensitive information from the client's browser.

Tools Used

Manual review

Recommendations

  1. Implement comprehensive input sanitization for all parameters that will be included in the SVG output. This can be done by encoding special characters or using a whitelist approach to allow only safe characters.

Sanitized Input Example:

function sanitizeInput(string memory input) internal pure returns (string memory) {
bytes memory inputBytes = bytes(input);
for (uint256 i = 0; i < inputBytes.length; i++) {
if (inputBytes[i] == '<' || inputBytes[i] == '>' || inputBytes[i] == '&' || inputBytes[i] == '"') {
inputBytes[i] = ' ';
}
}
return string(inputBytes);
}
function generateSVG(SVGParams memory params) internal pure returns (string memory) {
// Sanitize input strings
params.accentColor = sanitizeInput(params.accentColor);
params.amount = sanitizeInput(params.amount);
params.assetAddress = sanitizeInput(params.assetAddress);
params.assetSymbol = sanitizeInput(params.assetSymbol);
params.duration = sanitizeInput(params.duration);
params.progress = sanitizeInput(params.progress);
params.sablierAddress = sanitizeInput(params.sablierAddress);
params.sablierModel = sanitizeInput(params.sablierModel);
params.status = sanitizeInput(params.status);
SVGVars memory vars;
// Generate the status card.
(vars.statusWidth, vars.statusCard) =
SVGElements.card({ cardType: SVGElements.CardType.STATUS, content: params.status });
// Concatenate all cards.
vars.cards = string.concat(vars.progressCard, vars.statusCard, vars.amountCard, vars.durationCard);
return string.concat(
'<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" viewBox="0 0 1000 1000">',
SVGElements.BACKGROUND,
generateDefs(params.accentColor, params.status, vars.cards),
generateFloatingText(params.sablierAddress, params.sablierModel, params.assetAddress, params.assetSymbol),
generateHrefs(vars.progressXPosition, vars.statusXPosition, vars.amountXPosition, vars.durationXPosition),
"</svg>"
);
}

To mitigate SVG injection risks, it is crucial to sanitize user-supplied inputs before using them in SVG generation. The sanitizeInput function provided above replaces potentially harmful characters with spaces.

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

SVG Injection

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.