Is this code vulnerable to Reflected XSS?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite
1












I'm doing a pentest and came by this code:



 (function() 
var subdomain = (function()
var query = /[?&]css=([^&#]*)/i.exec(window.location.search);
if(query)
return query[1];

var URL = window.location.host.split('.');
if (URL.length > 1)
return URL[0];

)();
if (subdomain)
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = "/" + subdomain + ".css";
document.getElementsByTagName('head')[0].appendChild(link);

)();


It adds a CSS file to the header for rebranding.

The target URL looks like this:
http://some.company.com/p1=test&css=custom

We have controlled the subdomain parameter here which equals to either query or URL[0].
query is the result of /[?&]css=([^&#]*)/i.exec(window.location.search); which equals to custom in this case.

if the query is not available in URL, then URL[0] equals to some here, I can't think of doing anything useful using URL[0] because, in order to control its value, I have to change some to something else which completely changes the URL and points to some other irrelevant page.

Anyway, The final CSS URL would be "/custom.css" or "/some.css" if the CSS parameter is not available.

I tried some payloads to exploit this but all failed.

Any ideas if this code is vulnerable and how can it be exploited?










share|improve this question



















  • 1




    //domain.tld/bad.css is a potentially valid url. no xss, but a css injection potential.
    – dandavis
    Sep 10 at 16:03

















up vote
4
down vote

favorite
1












I'm doing a pentest and came by this code:



 (function() 
var subdomain = (function()
var query = /[?&]css=([^&#]*)/i.exec(window.location.search);
if(query)
return query[1];

var URL = window.location.host.split('.');
if (URL.length > 1)
return URL[0];

)();
if (subdomain)
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = "/" + subdomain + ".css";
document.getElementsByTagName('head')[0].appendChild(link);

)();


It adds a CSS file to the header for rebranding.

The target URL looks like this:
http://some.company.com/p1=test&css=custom

We have controlled the subdomain parameter here which equals to either query or URL[0].
query is the result of /[?&]css=([^&#]*)/i.exec(window.location.search); which equals to custom in this case.

if the query is not available in URL, then URL[0] equals to some here, I can't think of doing anything useful using URL[0] because, in order to control its value, I have to change some to something else which completely changes the URL and points to some other irrelevant page.

Anyway, The final CSS URL would be "/custom.css" or "/some.css" if the CSS parameter is not available.

I tried some payloads to exploit this but all failed.

Any ideas if this code is vulnerable and how can it be exploited?










share|improve this question



















  • 1




    //domain.tld/bad.css is a potentially valid url. no xss, but a css injection potential.
    – dandavis
    Sep 10 at 16:03













up vote
4
down vote

favorite
1









up vote
4
down vote

favorite
1






1





I'm doing a pentest and came by this code:



 (function() 
var subdomain = (function()
var query = /[?&]css=([^&#]*)/i.exec(window.location.search);
if(query)
return query[1];

var URL = window.location.host.split('.');
if (URL.length > 1)
return URL[0];

)();
if (subdomain)
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = "/" + subdomain + ".css";
document.getElementsByTagName('head')[0].appendChild(link);

)();


It adds a CSS file to the header for rebranding.

The target URL looks like this:
http://some.company.com/p1=test&css=custom

We have controlled the subdomain parameter here which equals to either query or URL[0].
query is the result of /[?&]css=([^&#]*)/i.exec(window.location.search); which equals to custom in this case.

if the query is not available in URL, then URL[0] equals to some here, I can't think of doing anything useful using URL[0] because, in order to control its value, I have to change some to something else which completely changes the URL and points to some other irrelevant page.

Anyway, The final CSS URL would be "/custom.css" or "/some.css" if the CSS parameter is not available.

I tried some payloads to exploit this but all failed.

Any ideas if this code is vulnerable and how can it be exploited?










share|improve this question















I'm doing a pentest and came by this code:



 (function() 
var subdomain = (function()
var query = /[?&]css=([^&#]*)/i.exec(window.location.search);
if(query)
return query[1];

var URL = window.location.host.split('.');
if (URL.length > 1)
return URL[0];

)();
if (subdomain)
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = "/" + subdomain + ".css";
document.getElementsByTagName('head')[0].appendChild(link);

)();


It adds a CSS file to the header for rebranding.

The target URL looks like this:
http://some.company.com/p1=test&css=custom

We have controlled the subdomain parameter here which equals to either query or URL[0].
query is the result of /[?&]css=([^&#]*)/i.exec(window.location.search); which equals to custom in this case.

if the query is not available in URL, then URL[0] equals to some here, I can't think of doing anything useful using URL[0] because, in order to control its value, I have to change some to something else which completely changes the URL and points to some other irrelevant page.

Anyway, The final CSS URL would be "/custom.css" or "/some.css" if the CSS parameter is not available.

I tried some payloads to exploit this but all failed.

Any ideas if this code is vulnerable and how can it be exploited?







xss reflected-xss






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 11 at 19:30









R1-

1




1










asked Sep 10 at 15:22









Sam

327111




327111







  • 1




    //domain.tld/bad.css is a potentially valid url. no xss, but a css injection potential.
    – dandavis
    Sep 10 at 16:03













  • 1




    //domain.tld/bad.css is a potentially valid url. no xss, but a css injection potential.
    – dandavis
    Sep 10 at 16:03








1




1




//domain.tld/bad.css is a potentially valid url. no xss, but a css injection potential.
– dandavis
Sep 10 at 16:03





//domain.tld/bad.css is a potentially valid url. no xss, but a css injection potential.
– dandavis
Sep 10 at 16:03











3 Answers
3






active

oldest

votes

















up vote
10
down vote



accepted










Yes, this code is vulnerable, but not to XSS. The subdomain variable's value can indeed be controlled by an attacker, but that variable is only used to set the href parameter of a CSS stylesheet; which won't accept JavaScript code. However, controlling this value does still allow CSS injection.



The stylesheet's href is prefixed by /, but an attacker can still point it to an arbitrary page by adding another slash to form a protocol-relative URL pointing to the attacker's server. (E.g. //evilsite.com/payload.css.) This would allow the attacker to get complete control over the site's appearance, if not it's functionality, which could be used to trick users into taking actions they wouldn't otherwise take. (For example, add a banner telling users they need to reset their password, then style the user settings page to make their public profile description field look like the input box for "current password".)






share|improve this answer






















  • CSS might contain executable code - not for all browsers, but still.
    – Bergi
    Sep 10 at 21:46










  • @Bergi Interesting!
    – Sam
    Sep 16 at 12:10










  • So if the code was something like "/css/" + subdomain + ".css" was it still vulnerable to CSS injection?
    – Sam
    Sep 16 at 12:11

















up vote
5
down vote














Any ideas if this code is vulnerable and how can it be exploited?




As mentioned in the comments, this code could be vulnerable to CSS injection.



For example, if the URL looks like:



http://some.company.com/p1=test&css=/evil.com/more_evil


Then this javascript will create a new link in the header like:



link rel="stylesheet" href="//evil.com/more_evil.css"


Which is a valid URL (even without the scheme http/https), which can access the remote CSS file.






share|improve this answer




















  • You could avoid this specific issue by changing the regex to: /[?&]css=([a-zA-z]*)/
    – hft
    Sep 10 at 16:35

















up vote
1
down vote













It is vulnerable but you can solve that easily with whitelisting:



var allowedBrands = ['brand1', 'brand2', 'brand3'],
query = /[?&]css=([A-Za-z0-9]*)/i.exec(window.location.search);

if (query && allowedBrands.indexOf(query[1]))
return query[1];
else
return allowedBrands[0]; // this is the default value






share|improve this answer




















  • That's one way to do it, but I see two potential issues here, First, the list can get quite large, say for example 15000 or more "brands", and second, it is leaking information about all customers who are using this service. Your answer is technically correct, but I guess there are some considerations that must be taken into account.
    – Sam
    Sep 16 at 12:17










  • That's right, the best way I think is ok is to do the request directly (but with a secure Regex) into the server (that uses the same Regex) and let it validate whether the file exists to return a fallback if is needed, so the whitelist is the filesystem and no extra code is needed.
    – Matías Pizarro
    Sep 17 at 15:34











Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "162"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
noCode: true, onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsecurity.stackexchange.com%2fquestions%2f193397%2fis-this-code-vulnerable-to-reflected-xss%23new-answer', 'question_page');

);

Post as a guest






























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
10
down vote



accepted










Yes, this code is vulnerable, but not to XSS. The subdomain variable's value can indeed be controlled by an attacker, but that variable is only used to set the href parameter of a CSS stylesheet; which won't accept JavaScript code. However, controlling this value does still allow CSS injection.



The stylesheet's href is prefixed by /, but an attacker can still point it to an arbitrary page by adding another slash to form a protocol-relative URL pointing to the attacker's server. (E.g. //evilsite.com/payload.css.) This would allow the attacker to get complete control over the site's appearance, if not it's functionality, which could be used to trick users into taking actions they wouldn't otherwise take. (For example, add a banner telling users they need to reset their password, then style the user settings page to make their public profile description field look like the input box for "current password".)






share|improve this answer






















  • CSS might contain executable code - not for all browsers, but still.
    – Bergi
    Sep 10 at 21:46










  • @Bergi Interesting!
    – Sam
    Sep 16 at 12:10










  • So if the code was something like "/css/" + subdomain + ".css" was it still vulnerable to CSS injection?
    – Sam
    Sep 16 at 12:11














up vote
10
down vote



accepted










Yes, this code is vulnerable, but not to XSS. The subdomain variable's value can indeed be controlled by an attacker, but that variable is only used to set the href parameter of a CSS stylesheet; which won't accept JavaScript code. However, controlling this value does still allow CSS injection.



The stylesheet's href is prefixed by /, but an attacker can still point it to an arbitrary page by adding another slash to form a protocol-relative URL pointing to the attacker's server. (E.g. //evilsite.com/payload.css.) This would allow the attacker to get complete control over the site's appearance, if not it's functionality, which could be used to trick users into taking actions they wouldn't otherwise take. (For example, add a banner telling users they need to reset their password, then style the user settings page to make their public profile description field look like the input box for "current password".)






share|improve this answer






















  • CSS might contain executable code - not for all browsers, but still.
    – Bergi
    Sep 10 at 21:46










  • @Bergi Interesting!
    – Sam
    Sep 16 at 12:10










  • So if the code was something like "/css/" + subdomain + ".css" was it still vulnerable to CSS injection?
    – Sam
    Sep 16 at 12:11












up vote
10
down vote



accepted







up vote
10
down vote



accepted






Yes, this code is vulnerable, but not to XSS. The subdomain variable's value can indeed be controlled by an attacker, but that variable is only used to set the href parameter of a CSS stylesheet; which won't accept JavaScript code. However, controlling this value does still allow CSS injection.



The stylesheet's href is prefixed by /, but an attacker can still point it to an arbitrary page by adding another slash to form a protocol-relative URL pointing to the attacker's server. (E.g. //evilsite.com/payload.css.) This would allow the attacker to get complete control over the site's appearance, if not it's functionality, which could be used to trick users into taking actions they wouldn't otherwise take. (For example, add a banner telling users they need to reset their password, then style the user settings page to make their public profile description field look like the input box for "current password".)






share|improve this answer














Yes, this code is vulnerable, but not to XSS. The subdomain variable's value can indeed be controlled by an attacker, but that variable is only used to set the href parameter of a CSS stylesheet; which won't accept JavaScript code. However, controlling this value does still allow CSS injection.



The stylesheet's href is prefixed by /, but an attacker can still point it to an arbitrary page by adding another slash to form a protocol-relative URL pointing to the attacker's server. (E.g. //evilsite.com/payload.css.) This would allow the attacker to get complete control over the site's appearance, if not it's functionality, which could be used to trick users into taking actions they wouldn't otherwise take. (For example, add a banner telling users they need to reset their password, then style the user settings page to make their public profile description field look like the input box for "current password".)







share|improve this answer














share|improve this answer



share|improve this answer








edited Sep 10 at 16:31

























answered Sep 10 at 16:20









Ajedi32

2,70111347




2,70111347











  • CSS might contain executable code - not for all browsers, but still.
    – Bergi
    Sep 10 at 21:46










  • @Bergi Interesting!
    – Sam
    Sep 16 at 12:10










  • So if the code was something like "/css/" + subdomain + ".css" was it still vulnerable to CSS injection?
    – Sam
    Sep 16 at 12:11
















  • CSS might contain executable code - not for all browsers, but still.
    – Bergi
    Sep 10 at 21:46










  • @Bergi Interesting!
    – Sam
    Sep 16 at 12:10










  • So if the code was something like "/css/" + subdomain + ".css" was it still vulnerable to CSS injection?
    – Sam
    Sep 16 at 12:11















CSS might contain executable code - not for all browsers, but still.
– Bergi
Sep 10 at 21:46




CSS might contain executable code - not for all browsers, but still.
– Bergi
Sep 10 at 21:46












@Bergi Interesting!
– Sam
Sep 16 at 12:10




@Bergi Interesting!
– Sam
Sep 16 at 12:10












So if the code was something like "/css/" + subdomain + ".css" was it still vulnerable to CSS injection?
– Sam
Sep 16 at 12:11




So if the code was something like "/css/" + subdomain + ".css" was it still vulnerable to CSS injection?
– Sam
Sep 16 at 12:11












up vote
5
down vote














Any ideas if this code is vulnerable and how can it be exploited?




As mentioned in the comments, this code could be vulnerable to CSS injection.



For example, if the URL looks like:



http://some.company.com/p1=test&css=/evil.com/more_evil


Then this javascript will create a new link in the header like:



link rel="stylesheet" href="//evil.com/more_evil.css"


Which is a valid URL (even without the scheme http/https), which can access the remote CSS file.






share|improve this answer




















  • You could avoid this specific issue by changing the regex to: /[?&]css=([a-zA-z]*)/
    – hft
    Sep 10 at 16:35














up vote
5
down vote














Any ideas if this code is vulnerable and how can it be exploited?




As mentioned in the comments, this code could be vulnerable to CSS injection.



For example, if the URL looks like:



http://some.company.com/p1=test&css=/evil.com/more_evil


Then this javascript will create a new link in the header like:



link rel="stylesheet" href="//evil.com/more_evil.css"


Which is a valid URL (even without the scheme http/https), which can access the remote CSS file.






share|improve this answer




















  • You could avoid this specific issue by changing the regex to: /[?&]css=([a-zA-z]*)/
    – hft
    Sep 10 at 16:35












up vote
5
down vote










up vote
5
down vote










Any ideas if this code is vulnerable and how can it be exploited?




As mentioned in the comments, this code could be vulnerable to CSS injection.



For example, if the URL looks like:



http://some.company.com/p1=test&css=/evil.com/more_evil


Then this javascript will create a new link in the header like:



link rel="stylesheet" href="//evil.com/more_evil.css"


Which is a valid URL (even without the scheme http/https), which can access the remote CSS file.






share|improve this answer













Any ideas if this code is vulnerable and how can it be exploited?




As mentioned in the comments, this code could be vulnerable to CSS injection.



For example, if the URL looks like:



http://some.company.com/p1=test&css=/evil.com/more_evil


Then this javascript will create a new link in the header like:



link rel="stylesheet" href="//evil.com/more_evil.css"


Which is a valid URL (even without the scheme http/https), which can access the remote CSS file.







share|improve this answer












share|improve this answer



share|improve this answer










answered Sep 10 at 16:19









hft

1,174617




1,174617











  • You could avoid this specific issue by changing the regex to: /[?&]css=([a-zA-z]*)/
    – hft
    Sep 10 at 16:35
















  • You could avoid this specific issue by changing the regex to: /[?&]css=([a-zA-z]*)/
    – hft
    Sep 10 at 16:35















You could avoid this specific issue by changing the regex to: /[?&]css=([a-zA-z]*)/
– hft
Sep 10 at 16:35




You could avoid this specific issue by changing the regex to: /[?&]css=([a-zA-z]*)/
– hft
Sep 10 at 16:35










up vote
1
down vote













It is vulnerable but you can solve that easily with whitelisting:



var allowedBrands = ['brand1', 'brand2', 'brand3'],
query = /[?&]css=([A-Za-z0-9]*)/i.exec(window.location.search);

if (query && allowedBrands.indexOf(query[1]))
return query[1];
else
return allowedBrands[0]; // this is the default value






share|improve this answer




















  • That's one way to do it, but I see two potential issues here, First, the list can get quite large, say for example 15000 or more "brands", and second, it is leaking information about all customers who are using this service. Your answer is technically correct, but I guess there are some considerations that must be taken into account.
    – Sam
    Sep 16 at 12:17










  • That's right, the best way I think is ok is to do the request directly (but with a secure Regex) into the server (that uses the same Regex) and let it validate whether the file exists to return a fallback if is needed, so the whitelist is the filesystem and no extra code is needed.
    – Matías Pizarro
    Sep 17 at 15:34















up vote
1
down vote













It is vulnerable but you can solve that easily with whitelisting:



var allowedBrands = ['brand1', 'brand2', 'brand3'],
query = /[?&]css=([A-Za-z0-9]*)/i.exec(window.location.search);

if (query && allowedBrands.indexOf(query[1]))
return query[1];
else
return allowedBrands[0]; // this is the default value






share|improve this answer




















  • That's one way to do it, but I see two potential issues here, First, the list can get quite large, say for example 15000 or more "brands", and second, it is leaking information about all customers who are using this service. Your answer is technically correct, but I guess there are some considerations that must be taken into account.
    – Sam
    Sep 16 at 12:17










  • That's right, the best way I think is ok is to do the request directly (but with a secure Regex) into the server (that uses the same Regex) and let it validate whether the file exists to return a fallback if is needed, so the whitelist is the filesystem and no extra code is needed.
    – Matías Pizarro
    Sep 17 at 15:34













up vote
1
down vote










up vote
1
down vote









It is vulnerable but you can solve that easily with whitelisting:



var allowedBrands = ['brand1', 'brand2', 'brand3'],
query = /[?&]css=([A-Za-z0-9]*)/i.exec(window.location.search);

if (query && allowedBrands.indexOf(query[1]))
return query[1];
else
return allowedBrands[0]; // this is the default value






share|improve this answer












It is vulnerable but you can solve that easily with whitelisting:



var allowedBrands = ['brand1', 'brand2', 'brand3'],
query = /[?&]css=([A-Za-z0-9]*)/i.exec(window.location.search);

if (query && allowedBrands.indexOf(query[1]))
return query[1];
else
return allowedBrands[0]; // this is the default value







share|improve this answer












share|improve this answer



share|improve this answer










answered Sep 11 at 15:59









Matías Pizarro

111




111











  • That's one way to do it, but I see two potential issues here, First, the list can get quite large, say for example 15000 or more "brands", and second, it is leaking information about all customers who are using this service. Your answer is technically correct, but I guess there are some considerations that must be taken into account.
    – Sam
    Sep 16 at 12:17










  • That's right, the best way I think is ok is to do the request directly (but with a secure Regex) into the server (that uses the same Regex) and let it validate whether the file exists to return a fallback if is needed, so the whitelist is the filesystem and no extra code is needed.
    – Matías Pizarro
    Sep 17 at 15:34

















  • That's one way to do it, but I see two potential issues here, First, the list can get quite large, say for example 15000 or more "brands", and second, it is leaking information about all customers who are using this service. Your answer is technically correct, but I guess there are some considerations that must be taken into account.
    – Sam
    Sep 16 at 12:17










  • That's right, the best way I think is ok is to do the request directly (but with a secure Regex) into the server (that uses the same Regex) and let it validate whether the file exists to return a fallback if is needed, so the whitelist is the filesystem and no extra code is needed.
    – Matías Pizarro
    Sep 17 at 15:34
















That's one way to do it, but I see two potential issues here, First, the list can get quite large, say for example 15000 or more "brands", and second, it is leaking information about all customers who are using this service. Your answer is technically correct, but I guess there are some considerations that must be taken into account.
– Sam
Sep 16 at 12:17




That's one way to do it, but I see two potential issues here, First, the list can get quite large, say for example 15000 or more "brands", and second, it is leaking information about all customers who are using this service. Your answer is technically correct, but I guess there are some considerations that must be taken into account.
– Sam
Sep 16 at 12:17












That's right, the best way I think is ok is to do the request directly (but with a secure Regex) into the server (that uses the same Regex) and let it validate whether the file exists to return a fallback if is needed, so the whitelist is the filesystem and no extra code is needed.
– Matías Pizarro
Sep 17 at 15:34





That's right, the best way I think is ok is to do the request directly (but with a secure Regex) into the server (that uses the same Regex) and let it validate whether the file exists to return a fallback if is needed, so the whitelist is the filesystem and no extra code is needed.
– Matías Pizarro
Sep 17 at 15:34


















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsecurity.stackexchange.com%2fquestions%2f193397%2fis-this-code-vulnerable-to-reflected-xss%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Peggy Mitchell

Palaiologos

The Forum (Inglewood, California)