DEV Community

How do you use an SVG as background image without affecting security?

Drishit Mitra on November 10, 2018

I want to use an SVG as a backround image for one of my pages. For this, I have to make my CSP img-src rule as img-src 'self' data:
However, this will be an unsafe choice as explained here.

Has anyone faced this issue? If yes, how did you overcome it?

Collapse
 
antogarand profile image
Antony Garand

Don't use a base64'd version of the image, or anything using the data protocol.

You can use an url towards the image instead, which will make it safe.

Collapse
 
drishit96 profile image
Drishit Mitra

I had tried with a relative url previously and the request was going for the base64'd version. It works only if I use the full URL. I didn't want to hardcode the URL.
Anyways, thanks!

Collapse
 
nektro profile image
Meghan (she/her)

what was your CSS? you should be using a URL not data:

Thread Thread
 
drishit96 profile image
Drishit Mitra • Edited

This doesn't work:

.back-img {
    background-image: url("../img/bg.svg")
}

But this does:

.back-img {
    background-image: url("https://example.org/img/bg.svg")
}

I just don't want to hardcode the URL

Thread Thread
 
pmcgowan profile image
p-mcgowan • Edited

Try url('/img/bg.svg'), not sure if that will work though.

Thread Thread
 
drishit96 profile image
Drishit Mitra

I don't see the difference between your snippet and mine 😅.
I know my relative URL is right, because without CSP it works fine.

Thread Thread
 
nektro profile image
Meghan (she/her)

What’s your CSP?

Thread Thread
 
drishit96 profile image
Drishit Mitra
default-src 'none' ; script-src 'self'; style-src 'self' https://code.getmdl.io/1.3.0/material.teal-orange.min.css; img-src 'self' ; font-src https://fonts.gstatic.com/s/materialicons/; connect-src 'self' https://fonts.gstatic.com/s/materialicons/ https://fonts.googleapis.com/icon https://code.getmdl.io/1.3.0/material.teal-orange.min.css; media-src 'none' ; object-src 'none' ; child-src 'none' ; frame-src 'self'; worker-src 'self' ; frame-ancestors 'none' ; form-action 'none' ; upgrade-insecure-requests; block-all-mixed-content; base-uri 'self'; manifest-src 'self';
Thread Thread
 
tompearson profile image
Tom Pearson

the difference between url('/img/bg.svg') and url("../img/bg.svg") is that the former is an absolute path and will always refer to the same resource the latter is a relative path and the resource it refers to will change depending on the URL of the page that makes the request.

For example if the page making the request is example.com/page/content/index.html then '/img/bg.svg' will look for the SVG at example.com/img/bg.svg whereas '../img/bg.svg' will look for the SVG at example.com/page/img/bg.svg

Collapse
 
drishit96 profile image
Drishit Mitra • Edited

Thanks for all who helped 🙂.
I have found out the cause of my problem.
I had used vue-cli to build my project and it used a package called 'url-loader' which was inlining images as data urls whenever the size of the image was less than 1000 bytes. That's the reason why my relative URL was getting converted to data url. I have reduced that limit to 1 byte to avoid any conversion.