3

Ok, for example, say you have settings stored in a database where the user selects the language of the site.

For example, say the language they chose was English and now has a setting of en.

Then within your scripting language such as PHP you generate the path to the file and include it as usual, such as:

<script type="text/javascript" src="<?=$home_url?>/languages/<?=$lang?>.js"></script>

I know this value should be safe and really if some malicious user has somehow gained access to the database then we likely have bigger problems to worry about, but I guess it's possible a security flaw somewhere made it possible to be able to corrupt the value of this field and insert some unexpected and malicious data.

Though I assume they couldn't do anything too nasty seeing as the inclusion of <?=$home_url?> should prevent anyone from including any files from a remote server?

1 Answer 1

4

Even though I only half agree with you on an attacker having access to the DB not being worth protecting against, I would still say that this is not a big issue for a couple of reasons:

  • Since the include is client side and not server side, you do not risk exposing any sensitive files that are not already exposed. Had it instead been a PHP include() you would have bigger risks, since it can reach files that can not be reached over HTTP.
  • Probably only files on your domain can be included (but using /../ could let an attacker traverse to other directories). But if you have an open redirect vulnerability on your side it could be used to include files from other domains. That would be dangerous.
  • As I understand it, the user can only set their own language. So even if this was exploitable it would be hard to "deliver" the exploit to other users.

But still, there is no reason to take unnecesary risks even if they are small. This can be easily defended against:

  • Validate the data in the application layer, so the user can not set a language that is not on your list of languages. So if they try setting ../evil_javascript.js it will fail.
  • Make sure only country codes can be stored in that database column, e.g. by using a foreign key to a languages table or perhaps a check constraint. This way, you know a user can not sneak in any strange values even if the validation in the application layer should somehow fail.
  • Then validate the data as it comes out of your DB. You could make a check like this (but perhaps with nicer error handling):

    if(!in_array($lang, $language_list)) die("Unknown language!");
    

    Or just doing this would take the teeth out of any attack:

    <script src="<?=$home_url?>/languages/<?=substr($lang, 0, 2)?>.js">
    

This might seem a bit execive for a low risk thing. But at least the first and second point is good practice anyway, even if you don't take security into consideration.

2
  • You have an excellent point, that an attacker could use this, along with an Open Redirect (if one is present), to execute an XSS attack. It's easy enough to use a regex to validate the input so that might be the best option. Commented Nov 21, 2016 at 20:55
  • 1
    Thanks for your post. I think checking the language coming from the database is in the list of allowed languages might be the best bet as you suggested - whilst setting a foreign key et al could work, if the attacker has direct access to the db then they should be able to remove the constraints; using substr would work too, but would need to be expanded, at least in my use case as I can have locales such as en-GB.
    – Brett
    Commented Nov 22, 2016 at 8:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .