Application security is vitally important for every software project, especially so for security projects. This is why the validation process for QRadar app submissions go through a secure engineering review. As a member of the secure development team, this blog post will hopefully give you (the app developer) some insight regarding what to expect during our app validation process. Keep in mind most QRadar apps are based in Python using the flask framework, so the basis for most of the examples will be based on Python and Flask. If you have chosen to use a different technology stack, the concepts outlined in this guide will still be useful, but you’ll have to modify the examples to fit your needs.

Keep in mind there is no one size fits all solution for security, nor is there any tool that can detect all issues. One of the best tools for secure engineering is simply knowing that these problems exist and that you should be worried about them.

 

How to prevent app submissions from being rejected

Each application undergoes an individual security review as part of the submission process. The tips and discussion in this article are intended to guide users to the types of items we review and take questions about frequently to reduce the chance of an app submissions from being rejected based off of common issues.

As mentioned, all submitted apps for QRadar on the X-Force App Exchange go through a security review. Our job is to review apps for issues and notify developers when an app fails the secure app validation process.  This blog post include examples of common issues seen with app submissions that are insecure. Fortunately, many of these issue have some simple fixes and these examples will assist you with writing secure apps and outlines the items reviewed during app validation.

1. SQL Injection (SQLi) in your QRadar App

SQL injection is the number one issue we see when validating security in apps. Ff you don’t know why this statement is bad, then you should go read this OWASP article, or watch this video by Computerphile (YouTube). This attack gives the power to a malicious actor to do almost anything to your database.

# Do NOT do it this way.
cmd = "update people set name='%s' where id='%s'" % (name, id) curs.execute(cmd)
#OR
cmd = "update people set name="+name+" where id="+id curs.execute(cmd)

In general, you should always use parametrized SQL statements (sometimes called prepared statements). Building your query in risky ways, such as string formatting or concatenation above will leave you open to SQL injection attacks when the variables contain untrusted input. Even if you know a given variable comes from somewhere you consider to be safe, keep in mind that in the future that same variable may become user editable, or if you have written reusable code, someone may call your function with unsafe data.

For that reason, it is best practice to always use parametrized SQL statements. The added benefit for app validation is when I see safe parametrized SQL, it is an easy pass. When unsafe query construction is used I must spend time backing through the source code to determine if it is exploitable or not.

There is a form post with more examples and implementation details:https://developer.ibm.com/answers/questions/417797/how-to-prevent-sql-injection-in-an-app/

SQL Injection recap:

  • Use parametrized (prepared) SQL statements for user data input
  • For dynamic query building (instructions) use a whitelist approach to set
  • Treat all data as untrusted, even if it is trusted now it might not always be, and it makes validation quicker.

2. Cross Site Scripting (XSS) in a QRadar App

Speaking of untrusted data, another very common issue is cross site scripting. Kind of like SQLi, this is caused when the data and instructions get mixed together. OWASP and Computerphile (YouTube) do a great job at explaining these injection attacks. In short, XSS attacks allow a malicious user to inject their own JavaScript into your page and complete nefarious actions.

While the fix for XSS is still quite easy, it’s not quite as cut and dry as SQLi prevention. I’ll highlight some key points, but reading more into OWASP’s XSS Prevention guide is well worth it.

Many popular JS frameworks have some version of XSS prevention, and it’s worth a read to see what your framework has to offer. The Key points are to make sure that data is escaped. A great example is are the .text() and .html() functions of jQuery. The .html() function will put the literal contents of a string into the target DOM element. So if you pass “<script>alert(“xss”)</script>” then a script element will get inserted. Where using the same string with .text() will result in the following being inserted:

&lt;script&gt;alert(&ldquo;xss&rdquo;)&lt;/script&gt;&rdquo;

The encoded string does not create a script element, and the text displays as intended.

Not escaping QRadar API provided data

Speaking of untrusted data, you shouldn’t implicitly trust all data from the QRadar API. That is because QRadar does not do any sanitation on output of API data. While not every field is untrustable, it is easier to treat it all as untrusted. You are allowed to name a log source <script>alert(“xss!”)</script>, and in QRadar we escape the log source name when we display it.

3. Cross Site Request Forgery (CSRF / XSRF) in a QRadar App

The last of the big 3 vulnerabilities. Does your application let the user create, modify, or delete any data? Then you need CSRF protection.

Like SQLi and XSS OWASP and Computerphile have some great resources on it. CSRF attacks work by tricking the browser of the victim into sending a legitimate seeming request without the victim intending it.

If you’re using flask, this is a very easy fix with the Flask-WTF library and a few lines in your templates and JavaScript.  There is another form post discussing that.

 

4. Leaked Credentials in a QRadar App

You should never print off credentials anywhere in your application, but I’ve seen numerous places where developers have leaked credentials in their application.

4a. Hard coded into source code

This is a bad security practice in general on many levels. If hard coded credentials are part of the app, then they should be configurable by the end user. If it is a test/validation file, then the file should be removed from the application or removed during the build process.

4b. Commented out in source code

Like above, I’ve seen commented out credentials that were valid and let me log into the external source.

4c. Printed in logs

Auditing changes is always a good practice. For example, you can log the fact that a parameter or value was changed; however, do not log token values or passwords in your application logs.

Never do anything like this:

logger.info("Changed token to : %s" % token)

Intead, note that the token value was changed without writing the value to the logs:

logger.info("Changed token." )

4d. Query strings

While you should never create, modify, or delete with a GET anyway, one more reason not to do that is because the query string is often logged so  /app/updateToken/123-abc-xyz shows up in the logs.

5. Interactions with the File System or Operating System (Added August 2018)

Similar to XSS and SQLi, untrusted input can be a disaster when it comes to interacting with the server you’re application runs on.

5a. Directory / Path Traversal

An app might allow a user to upload and delete files. If the app simply asks “what file do you want to delete” and allows the user to specify a filename, and the app just appends the filename to a base path, the user could escape or traverse to other files.

file_to_delete = "../logs/audit.log"
file_to_replace = "../../../etc/passwd"
base_directory = "/store/app/user_files/"
os.delete(  base_directory  + file_to_delete )
os.replace( base_directory  + file_to_replace )

If you’re modifying files on disk, you need to ensure they are the files you expect! Checkout the forum post detailing more on Directory Traversal Prevention or checkout the OWASP guide

5b. Command Injection

Just as bad, if not worse, is command injection. If you need to invoke an external script, or interact with the operating system on your host you could potentially run into this issue. Like many of the issues outlined here, it is because of untrusted input.

import subprocess

ip = "192.168.2.1"
syslog_path = "something"
unique_id = "haxor & touch badFileOrCommand.txt"

subprocess.Popen(['exec python target.py {0} {1} {2}'.format(ip, syslog_path, unique_id)],shell=True)

The above example shows three variables being passed to another python script, the ‘&’ tells the OS we want to run another command, in this case we only create a file, but it could be any command the account has privilege to run. Take a look at the new forum post about it or the OWASP article.

Issues that extend the app validation review

a. Excessive files

If you’ve decided to include every JavaScript library in your apps /static folder “just in case” that means I’ll be looking to see what security implementations they have or if you even use them.

b. Undocumented code

When you have large sections of non-trivial code without comments, it takes time to decipher what they do. A few comments go a long way when manually reviewing code.

c. Large codebase

This is something that really cannot be changed, if you’re app does a lot then it will bigger than an app that does less. Just keep in mind larger apps take longer to validate.

What can I do to make my QRadar app more secure?

Just thinking about secure engineering is one of the best resources. Secure app development is not just getting your app to work, but to look at your app from the perspective of someone who would willingly try to abuse it. It can be hard since as developers we have a finite amount of time and resources to dedicate and security can be an after though. But you must keep in mind that hackers have much more time, and security is their focus.

Depending on the size of your app, having a resource dedicated to doing secure code review or make security checks part of your code review checklist.

No tool can find all potential vulnerabilities, but they can sure help. OWASP has a great list of tools. I recommend Bandit for python flask apps. It’s part of our validation process. It finds issues in your source code like SQLi, and will flag some unsafe libraries, such as pickle. The code analysis tool installation and usage is pretty straight forward.

The following command will generate you a HTML report of potential issues:

pip install bandit

bandit /path/to/code -r -a file -f html -o file.html

 

If you have follow-up questions, ask in our forums: https://ibm.biz/qradarappdev

2 comments on"Secure Engineering & Your QRadar App"

  1. Jeanchris June 24, 2018

    Hello bradley , awesom article , i would like to ask you a few question about security in Qradar App 🙂

Join The Discussion

Your email address will not be published. Required fields are marked *