3

Suppose an online coding platform that allows users to enter code and submit the code in the web page form. It also shows the code that was previously entered, by storing it in database. How to ensure that malicious code does not get executed both on the front-end and back-end? What are the things that need to be considered for security.

I know about safeguarding and implementing -

  1. Session Hijacking
  2. XSS attacks
  3. CSRF
  4. SQL injection
  5. Encypting user passwords
  6. Man in the middle attack

My question is to find out what else needs to be done, to stop the user provided code from executing on my backend. Any interesting topics that I can read about.

Should encrypting/encoding the code text and storing them in encrypted format will help? Or is it advisable to store code text in non-executable files on the server, creating them dynamically for each user?

8
  • Literally, a ton of things need to be considered for security in this context. Frankly, so much that you'd need an experienced professional programmer (or a small team of them) to build such a system that is reasonably safe to use. Commented Nov 23, 2019 at 1:45
  • Hi @DelightedD0D, I updated the question details. Thanks. Commented Nov 23, 2019 at 1:53
  • Are you using SQL or Mongo? The later is not a relational db. It would be close to impossible to use SQL injection agains it. Commented Nov 26, 2019 at 16:15
  • @AlexBlex: Thanks for replying. I am using mongodb. Ok, so, SQL injection is out. How to prevent user submitted code from being executed on backend. My question is independent of database used. What does everyone else in industry do to avoid it? Commented Nov 26, 2019 at 18:05
  • If you are concerned about execution of the code submitted from the legitimate form and stored in mongo - you are safe. It's just a string. This functionality alone is harmless unless you attempt to run this code on the backend yourself. It can be used on compromised systems in combination with other vulnerabilities tho. It is no different from any other request handler that stores incoming data in the db. Commented Nov 26, 2019 at 18:18

2 Answers 2

1
+50

There are the following risks for a service like an online coding platform using MongoDB as a data store:

Code injection

An attacker injects code that is then interpreted/executed by the application. For example, JavaScript eval() method:

let str = '2 + 2';
console.log(eval(str)); //4

If str is provided by user, an attacker can pass some malicious code.

In Java it is not common to execute or evaluate scripts.

So, unless you execute code that users provide, you are safe.

While it is still possible to execute user provided code on the server side like https://ideone.com/ does. For this code must be executed in isolated sandbox, e.g. isolated Docker container.

Also, you can Gzip code provided by user and/or encode in Base64 and store it this way in the DB.

NoSQL injection

The following query is vulnerable to injection:

const query = {
    username: req.body.username,
    password: req.body.password
}

db.collection('users').findOne(query, function (err, user) {
    console.log(user);
});

because a user can pass the following parameters:

{
    "username": {"$ne": null},
    "password": {"$ne": null}
}

and the query will return the first user without knowing his username or password.

Especially dangerous when JavaScript is also evaluated to allow more advanced conditions.

db.myCollection.find({
    $where: function() { 
        return obj.credits - obj.debits < 0; 
    }
});

More details in https://zanon.io/posts/nosql-injection-in-mongodb

The solution is to only accept strings from users and do not accept objects or sanitize an input (for example, using mongo-sanitize). It is mostly related to Node.js. MongoDB Java Driver provides another API that by design solves some types of injections (similar to JDBC PreparedStatement):

collection.find(and(gt("i", 50), lte("i", 100))).forEach(printBlock);

Moreover, if you use Morphia, a Java object-document mapper, you are safe.

Using components with known vulnerabilities

Attacker can try to exploit a vulnerability in the platform or framework you use (JDK, Spring Framework etc.) For example, the famous Heartbleed vulnerability in OpenSSl.

So, it is very important to use the latest version of platforms and frameworks and apply all security patches.

There is a great tool for scanning Java libraries using Maven or Gradle plugin or even using CLI - OWASP Dependency Check. It automatically scans all the dependencies and prepares and alerts if vulnerabilities are found.

Insecure deserialization

It is important to use some well-known data format like JSON and use mature and stable library for deserialization (Jackson or Gson) instead of parsing input manually, especially using eval() JavaScript method or alternative in other languages.

Sign up to request clarification or add additional context in comments.

6 Comments

I wouldn't refer to the amateur page on medium. The SQL injection described there exploits the fact that both data and operands in SQL query come in the same string. Mongo separates them on driver and protocol level. One will need to write quite sophisticated parser for user's input to make a string Robert”}).then(db.students.drop()) to actually drop the collection.
Removed this confusing link to Medium article.
@EvgeniyKhyst: Thanks a ton for detailed info. :) SO is amazing !
I have one last follow-up question (a very basic question). When we say 'execute the user provided code at backend', does that mean we execute the string using "exec" method in java? or does that also include operations such as "replace", esacping or "toLowerCase" on that string? Thanks.
Unless there are a bug in JVM, calling replace() or toLowerCase() methods is safe. Doesn't matter what is the content of the string: code or text. User provided code can be executed in Java like this: ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); engine.eval("var x = 10;");
|
0

I'll give you at least a part of the answer:

For

  • SQL statements: Use prepared statements!!
  • XSS attacks: have a look at trusted typing, which is however not activated on most browsers, thus you'll have to find someone to implement a good CSP for you, which mitigates the risk.
  • CSRF: use CSRF tokens

  • Encrypting user passwords: use a secure hash, combined with salt and pepper!

  • Man in the middle attack: use a HTTPS Certificate and enforce https on your site using HSTS.

please note, that this is an answer I just wrote quite fast for you now, s.t. you can have a look at some topics. There is always very much to consider and everything just adds an additional (possibly evaded) layer of security on your application.

I can recommend Django to you, which is a backend framework, already caring about security very much.

Cheers

3 Comments

What about the security of the code pasted by the user on my web page. How should I store it on backend so as to prevent it from being executed at any cost.
I think you should be able to store it just as any other data. You however have to take special care when reflecting given user data (this holds always true, if code or not, since all input is evil) onto your web page.
After reading the currently accepted answer, I also want to add to just not use MongoDB or other NoSQL environments - you got the same vulnerabilities as in SQL here, just worse. Use Django as backend framework (read documentation to get special hints where you have to take care about security yourself) and configure it to use some SQL database like PostgresSQL (or don't - I think standard is MySQL). Also, read some WebSecurity Book - or at least the parts important for you, - I can recommend The Tangled Web by Michal Zalewski.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.