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:
<script>alert(“xss”)</script>”
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 untreatable, 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.
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
#QRadar1
#QRadar#Security