Summary
The following examples demonstrate how Krugle is used to detect a range of common and important application security vulnerabilities. Other approaches and analysis are possible with Krugle, and the following information provides background needed to understand and use Krugle for application security analysis.
Krugle provides instantaneous, "on-demand" search and detection of known security vulnerabilities in application software and internet web code. Because SAST products are not capable of keeping pace with the speed and scope of modern security attacks, the agile detection capabilities demonstrated below are becoming increasingly important for any organization that needs to operate at the speed and scope of cyber aggression.
Example 1
Vulnerable and Outdated Software Components
Krugle Techniques Used
Data Trace
String Encoding
Direct Inspection
Component Provinence
Functional Dependency
Human Artifact Analysis
Description
A vulnerable software component is a third party software module, plug in, or application that is known to contain one or more vulnerabilities. Also these vulnerabilities are known to exist in specific version(s) of the component. When components of the affected version(s) are deployed by your organization, each instance of the component represents a security vulnerability.
Software component vulnerabilities are common when:
How to Detect and Verify
The following 3 examples show how Krugle is used to detect vulnerabilities documented through CVE and similar issue databases. These sources provide the most timely, accurate and trustworthy information about known defects. As such, these examples outline how a rapid response, application security audit could be performed with Krugle.
Example: log4j 0-day (CVE-2021-44228) ("Log4Shell")
The log4j 0-day (CVE-2021-44228) ("Log4Shell") is widely reported (https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228)
Apache Log4j2 2.0-beta9 through 2.15.0 (excluding security releases 2.12.2, 2.12.3, and 2.3.1) JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.15.0, this behavior has been disabled by default. From version 2.16.0 (along with 2.12.2, 2.12.3, and 2.3.1), this functionality has been completely removed. Note that this vulnerability is specific to log4j-core and does not affect log4net, log4cxx, or other Apache Logging Services projects.
This issue only affects the version 2.0-beta9 through 2.15.0 and only affects log4j-core. The steps to identify the log4j 0-day (CVE-2021-44228) ("Log4Shell") via Krugle is straightforward. First, find all projects with log4j and then for each instance, check the version number of log4j instance against the vulnerable version list. Krugle "Advanced Search" supports snippet pattern to find everywhere log4j is used across all your code. In Java projects, we can search the following snippet in XML files.
Open the "Advanced Search" dialog, enter the Snippet field as shown below. Select XML in Document Type and then choose
.<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.</version>
</dependency>
In the Krugle search results for this query, we found the pom.xml files of project Flink 1.6, Flink master and Security Demo Java.
Upon opening the first result from our search, we can see that the log4j-core version is 2.10.0 and identifies the CVE-2021-44228 in Security Demo Java project.
The second and third results indicate the log4j-core version is 2.9.1 and identifies the CVE-2021-44228 in Flink v1.6.0 project.
In some situations, developers use a property to identify the version. The last result is one such example and indicates the log4j-core version is 2.17.1, and therefore does not have the vulnerability.
Example - CSRF CVE-2020-7749
The full documentation for the CVE issue can be found here: CVE-2020-7749.The nodejs puppeteer lib contains a setContent method, if unverified user data can reach the setContent method it can result in CWE-918: Server-Side Request Forgery (SSRF) vulnerabilities.
This affects all versions of package osm-static-maps. If User input is not properly escaped ({{{ ... }}}) it is possible for an attacker to inject arbitrary HTML/JS code, for cross site scripting and other vulnerabilities on the server side.
The following code snippet can be used for a source pattern to identify this vulnerability:
Next, we use Krugle to find this issue:
Next - search require('puppeteer') lang:javascript to locate the projects which uses the puppeteer lib.
https://opensearch.krugle.org/document/search/#query=require('puppeteer')%20lang%3Ajavascript&qtype=basic
This search produced a match in the "osm-static-maps" project. Next, we want to find calls to the function setContent in the project osm-static-maps". We can do this by entering the search functioncall:setContent project:osm-static-maps
(https://opensearch.krugle.org/document/search/#query=functioncall%3AsetContent%20project%3Aosm-static-maps&qtype=basic) and find a js file result that calling setContent() and using a variable instead of a string.
Then we must determine if this variable is escaped (or not) by the code. Clicking the line in the search result. We can find the definition of the html variable.
(https://opensearch.krugle.org/document/view_filecontent/osm_static_maps-1350256972501836683/scmi_30.20.55.1_8767/b380/src/lib.js?query=functioncall%3AsetContent%20project%3Aosm-static-maps&qtype=basic#96)
We can then see that the lib.js is a module being used by other files. To find these dependencies we can search require lib.js project:osm-static-maps. Our search results show that the server.js file has this dependency.
(https://opensearch.krugle.org/document/search/#query=require%20lib.js%20project%3Aosm-static-maps&qtype=basic)
Upon inspecting this file's source code, we see that req.query and req.body are not HTML escaped - confirming the existence of vulnerability in the osm-static-maps project.
Example: Outdated Django with SQL injection Vulnerability CVE-2019-14234
An issue was discovered in Django 1.11.x before 1.11.23, 2.1.x before 2.1.11, and 2.2.x before 2.2.4. Due to an error in shallow key transformation, key and index lookups for django.contrib.postgres.fields.JSONField, and key lookups for django.contrib.postgres.fields.HStoreField, were subject to SQL injection. This could, for example, be exploited via crafted use of code such as "OR 1=1" in a key or index name to return all records, using a suitably crafted dictionary, with dictionary expansion, as the **kwargs passed to the QuerySet.filter() function.To detect the presence of this issue with Krugle, we perform a Basic search for Django filename:requirements.txt to find all Django dependencies in all projects/repositories. https://opensearch.krugle.org/document/search/#query=Django%20filename%3Arequirements.txt&qtype=basic
This query produces a single match in the requirements.txt file:
The source code clearly indicates that the Django version is 2.2.1. With this information, Krugle positively identified the vulnerability in CVE-2019-14234.
Example 2
Access Control Vulnerabilities
Krugle Techniques Used
Configuration Errors Artifact Metdata Direct Inspection
Description
Exploitation of access control is a common attack vection. SAST and DAST tools can detect the absence of access control but cannot verify if it is functional when it is present. Access control is detectable using manual means, or possibly through automation for the absence of access controls in certain frameworks.
Access control weaknesses are common due to the lack of automated detection, and lack of effective functional testing by application developers. Access control detection is not typically amenable to automated static or dynamic testing. Manual testing is the best way to detect missing or ineffective access control, including HTTP method (GET vs PUT, etc), controller, direct object references, etc.
Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification, or destruction of all data or performing a business function outside the user's limits. Common access control vulnerabilities include:
How to Detect and Verify
Insecure Direct Object Reference is a common vulnerability with web applications that provides the attacker varying levels of access (including read, write and delete) or exposes unauthorized information (URLs, files, account numbers, etc.).
The user may be authorized to access the web application, but not a specific object, such as a database record, specific file or even an URL. Potential threats can come from an authorized user of the web application who alters a parameter value that directly points to an object that the user isn’t authorized to access. If the application doesn't verify the user for that specific object, it can result in an insecure direct object reference flaw.
The following examples explore some of the more common/significant vulnerabilities and Krugle methods for pinpointing these vulnerabilities in source code.
Example: Insecure Direct Object Reference (IDOR)
This example is based on a Python Django backend project that uses the djangorestframework to expose API endpoints. The API functions in views.py accepts the request.DATA to read HTTP POST/GET parameters. In case of IDOR vulnerability, developer should validate all HTTP request parameters of accessing the specific object are belongs to current signed in user.
In Krugle perform an "Advanced Search" for request.DATA[] of all python files.
Only one file found in the result set; let's inspect the file in detail to understand if the vulnerability exists.
In this file, the code only checks if the user is signed in. However, the list_ids could belong to other users. That means a attacker can simulate a POST request and pass any list IDs to delete the other users' data.
To eliminate this vulnerability, the code should confirm the IDs of list_ids belong to the current signed user.
Example: CORS misconfigurations
CORS vulnerabilities are common entry point vulnerabilities for attackers. CORS vulnerabilities result from a misconfiguration of the CORS protocol on web servers.
Cross-Origin Resource Sharing (CORS) is a technology used by websites to make web browsers relax the Same Origin Policy, enabling cross-domain communication between different websites. It's frequently used by web APIs in particular, but in a modern complex website it can turn up anywhere. It’s widely understood that certain CORS configurations are dangerous, but some associated subtleties and implications are easily misunderstood. This protocol built on top of HTTP allows server APIs to be accessed from a different origin or domain in a controlled way. For example, when YouTube retrieves your Google account data, it certainly uses CORS since youtube.com is sending requests to google.com (which is another origin). Normally, without CORS, this shouldn’t be allowed due to the Same Origin Policy or SOP that helps prevent cross-site vulnerabilities.
All CORS vulnerabilities come from incorrectly configuring CORS on the server. Some misconfigurations allow malicious domains to access the API endpoints, others allow credentials like cookies to be sent from untrusted sources. The most serious and common CORS vulnerabilities are listed below, and the easiest way to exploit and detect them.
Origin Reflection
If you want to allow cross-origin.com to access content from initial-origin.com you will need to specify it in the configuration of CORS in initial-origin.com using the Access-Control-Allow-Origin header:
But what if there is another domain that also needs access to the resources of initial-origin? CORS does not allow developers to specify a static list of allowed domains. In order to solve this problem, developers either use the wildcard character * , or generate the Access-Control-Allow-Origin header dynamically. We will come back to the first solution later on. Generating this header dynamically can be devastating to your security if it is not done properly. Many servers read the Origin header of the request and write it to the Access-Control-Allow-Origin header, thus giving access to all domains, including malicious ones.
In Krugle Opensearch, we can search for headers.get('Origin') ['Access-control-allow-credentials'] lang:python project:"security-demo-python-django" to find an "origin reflection" exploit of a python project.
The API endpoint list_items() sets the CORS header from the request header Origin without any validation, and the Access-control-allow-credentials is set to true. This represents a significant CORS vulnerability.
It is also possible to confirm this vulnerability directly - by sending HTTP requests from custom origins and check if the response gives access control to these origins.
This is called "Origin Reflection" because the server is reflecting the Request origin in the response access-control-allow-origin.
A more critical problem in this response is the Access-control-allow-credentials header set to true. This means that evil-domain.com can send cookies to secure-bank.com. This header allows the attacker to use the victim's credentials when sending the request to secure-bank.com, thus retrieving his sensitive information.
This vulnerability can be easily exploited - by using the following Javascript imbedded in a page sent to the victim.
The above exploit sends the received private key to the attacker's website who can gain access to all user's sensitive information.
Wildcard Origin
As mentioned above, one way to provide access to many origins is to using the Wildcard Origin in the response headers. Doing so gives explicit permission to all domains to read responses from secure-bank.com .
This vulnerability is less serious than Origin Reflection, but still important. The reason is that when a server sends a response with the two critical headers enabled,
credentials will never be sent or taken into consideration.
Fortunately, using the wildcard origin will automatically disable cookies sharing. However, if the server does not require authentication, it's still possible to access the data on the server. This can happen on internal servers that are not accessible from the Internet. The attacker’s website can then pivot into the internal network and access the server’s data without authentication. In this case, exploiting this vulnerability is similar to the exploit of Origin Reflection.
Null Origin
Some servers allow access to an origin called the Null Origin. This creates a critical vulnerability becuase allows everyone to access the resources on these websites, with credentials. You can detect this vulnerability in any response that contains:
null in this case does NOT mean ‘no one’ but rather ‘everyone’. To exploit this vulnerability the attacker must know: how can the null origin be generated? It is clear that sending a request from a any domain like evil-domain.com will put the actual name of the domain under the request origin header.
How can we transform this
----> Origin: evil-domain.com
into this
----> Origin: null
A few stackoverflow posts show that local HTML files get the Null Origin. Perhaps due to the association with local files, quite a few websites whitelist this Origin, including Google's PDF reader:
This is attractive for attackers, because any website can easily obtain the null origin using a sandboxed iframe:
The request sent using the above payload is going to have a Null Origin and thus successfully retrieving the private key.
As we have seen, misconfiguring CORS on a web server can be very critical and can allow the leakage of sensitive information. The easiest way to mitigate such serious vulnerabilities is to avoid the usage of dynamically generated access control headers if possible. If this is not possible, rigorous testing should be done to programmatically verify domain names. Access privileges should not, in any case, be given randomly.
Example 3
Cryptographic Exploits
Krugle Techniques Used
Functional Fingerprinting Cryptographic Assessment Artifact Metdata Direct Inspection Component Provinence
Description
Pinpointing cryptographic issues starts with understanding the protection requirements for data in transit and at rest. For example, passwords, credit card numbers, health records, personal information, and business secrets require extra protection, mainly if that data falls under privacy laws, e.g., EU's General Data Protection Regulation (GDPR), or regulations, e.g., financial data protection such as PCI Data Security Standard (PCI DSS). For all sensitive data:
How to Detect and Verify
Example: Not TLS enforced
A site doesn't use or enforce TLS for all pages or supports weak encryption. An attacker monitors network traffic (e.g., at an insecure wireless network), downgrades connections from HTTPS to HTTP, intercepts requests, and steals the user's session cookie. The attacker then replays this cookie and hijacks the user's (authenticated) session, accessing or modifying the user's private data. Instead of the above they could alter all transported data, e.g., the recipient of a money transfer.
Nginx server settings are provided in .conf files and we want to list all references to the ports that the server is listening on. To complete this in Krugle, run a Basic search for listen filename:*.conf. We can find all http server settings in all Nginx setting files. https://opensearch.krugle.org/document/search/#query=listen%20filename%3A*.conf&qtype=basic
We can see from the file that the myproject.conf file has both HTTP and HTTPS settings, however, the HTTP protocol should be disabled or rewritten to the HTTPS URL.
When we search ssl_protocols filename:*.conf, and inspect the result files we see that this file is still using an outdated TLS protocol, i.e. TLS 1.0. The DevOps developer should take actions to disable these outdated protocols and add the latest and safer protocols (i.e. TLS 1.1, 1.2, etc.)
Example 4
Code Injection Vulnerabilities
Krugle Techniques
String Encoding Data Serialization Direct Inspection Functional Fingerprinting
Description
Code injection happens when a deliberate attack of your application changes the code which your application executes. An application is vulnerable to an injection attack when:
Some of the more common injections are SQL, NoSQL, OS command, Object Relational Mapping (ORM), LDAP, and Expression Language (EL) or Object Graph Navigation Library (OGNL) injection. The attack concept is identical among all interpreters. Source code review is the best method of detecting if applications are vulnerable to injections. Automated testing of all parameters, headers, URL, cookies, JSON, SOAP, and XML data inputs is strongly encouraged.
How to Detect and Verify
Example - Searching for a command injection vulnerability (CIV)
A command injection vulnerability often has the signature of user input being passed to a function that executes system commands without any sanitization or input validation. So we are going to look for one of these dangerous functions that could signify a command injection vulnerability. Across a lot of programming languages and libraries a function/method named eval() is used to evaluate a string as the input and then executes whatever is in that string as a system command. So a good starting point is to search for the function eval() in your code repositories and verify whether the input being passed to it could cause a command injection vulnerability.
Execute a Basic search on: functioncall:eval lang:java project:"Security Demo Java" with Krugle. (https://opensearch.krugle.org/document/search/#query=functioncall%3Aeval%20lang%3Ajava%20project%3A%22Security%20Demo%20Java%22&qtype=basic)
One result matches in the Security Demo Java project. The call to the function eval() is at ServletTarPit.java line 63. Click the file name to open an exact copy of the actual file in Krugle - for inspection.
As we can see, this line of code is getting the request URI parameter named module from the user and then plugging i into an eval() function directly without any validation. So this is a verifiable point of command injection.
Example - SQL Injection
Let's look at an example in Java where the application connects to a database via JDBC when processing the HTTP requests in a Servlet. If the user-supplied data is not validated, filtered, or sanitized by the application, but used directly in a SQL statement it leave open a security hole for SQL injection.
In Krugle OpenSearch, enter a Solr search for the code pattern HttpServletRequest functioncall:prepareStatement language:Java functioncall:getParameter. https://opensearch.krugle.org/document/search/#query=HttpServletRequest%20functioncall%3AprepareStatement%20language%3AJava%20functioncall%3AgetParameter&qtype=solrq
The result produces two files that process user input and use that input to execute a SQL query via JDBC.
By inspecting the source code for each file, you can see that the input parameters are not validated, filtered, or sanitized by the application, but they are used in SQL statement directly. This positively confirms SQL injection vulnerability for this project.
Example 5
Security Configuration Exploits
Krugle Techniques Used
Artifact Metdata API Patterns Direct Inspection Configuration Errors
Description
Many applications are vulnerable because of incorrect or incomplete security configurations. Vulnerabilities will exist when the application has been deployed with:
Without a concerted, repeatable application security configuration process, systems are at a higher risk.
How to Detect and Verify
Example - Searching for log level settings
The application server's configuration allows detailed error messages, e.g. stack traces, to be returned to users. This potentially exposes sensitive information or underlying flaws such as component versions that are known to be vulnerable.
We can search the debug logging level of log4j2 settings for any Java projects.
Search level="debug" lang:xml we will find all log4j2 xml setting files. Code inspector, developer and OPS people should verify if they should be configured as debug for production. Normally this should be set to INFO level.
Example - Searching for hardcoded credentials
Many API keys also adhere to a very specific format. You can detect these sensitive strings by looking for patterns and source code using Krugle. e.g. AWS access key IDs commonly start with the pattern AKIA followed by 16 alphanumeric characters.
This time, we'll use the RegExp search feature in Krugle and construct a pattern query as akia.{16} project:"Security Demo Java". https://opensearch.krugle.org/document/search/#query=akia.%7B16%7D%20%20project%3A%22Security%20Demo%20Java%22&qtype=regexq
The search pattern above identifies strings that start with AKIA and are followed by 16 characters. This query helped us quickly find an instance where an AWS access key ID and associated access key have been exposed in the source code.
Other examples of exposed credentials could include leaked customer email addresses, phone numbers, bank cards etc. Just build your own Krugle search patterns and give it a try.
Example - Searching for hardcoded application secrets
For Java projects, we can make use of the Boolean search functionality available via the Solr search mode e.g. "String key =" OR "String secret =" OR "String token =" lang:java to find potential exposures.
Or for Python projects, we can query SECRET_KEY=" filename:settings.py or SECRET_KEY=" lang:python to determine if the application secret key is exposed among all the repositories.
Example - Find insecure comments
Sometimes developers may add design snippets with important information as comments in the source code e.g. the word production is used to differentiate between internal and external run configurations. To verify that in the production settings the developer hasn't exposed information, a Basic search in Krugle for comment:production lang:python project:security-demo-python-django could be performed (here we are limiting our search to the project "security-demo-python-django"). https://opensearch.krugle.org/document/search/#query=comment%3Aproduction%20lang%3Apython%20project%3Asecurity-demo-python-django&qtype=basic
We get one result back in the target project security-demo-python-django.
A quick inspection of the file shows that SECRET_KEY is exposed and the DEBUG setting should be turned off.
Example 6
Authentication Vulnerabilities
Krugle Techniques
Cryptographic Assessment Artifact Metdata Direct Inspection Functional Discovery
Description
Confirmation of the user's identity, authentication, and session management is critical to protect against authentication-related attacks. There may be authentication vulnerabilities if the application:
How to Detect and Verify
Example - Search for weak cryptography or hashing algorithms
The use of weak cryptography or hashing algorithms is another very significant vulnerability. Some algorithms like MD5, SHA1 are no longer considered to be secure as it's easy to come up with hash collisions and with a little computational processing a attacker could come up with alternate input that generates the same hash. This kind of vulnerability is hard to find during a dynamic test or doing a penetration test. But it's easy to identify potential issues by doing a code search. Using simple Krugle queries such as md5 or sha1 or des, can confirm one of these vulnerabilities.
To do a more specific check in say Java, we can do a Solr search for all MD5 hash generators with pattern getinstance md5 lang:java in Krugle.
And a Solr search with pattern getInstance /sha[0-9]+/ lang:java will find all java based SHA hash generators.
At this point the code reviewer should determine if the source code should use a safer cryptography or hashing algorithm.
Example 7
Software and Data Integrity
Krugle Techniques Used
Direct Inspection Functional Dependency Configuration Errors Artifact Metdata
Description
Software and data integrity failures relate to code and infrastructure that does not protect against integrity violations. An example of this is where an application relies upon plugins, libraries, or modules from untrusted sources, repositories, and content delivery networks (CDNs). An insecure CI/CD pipeline can introduce the potential for unauthorized access, malicious code, or system compromise. Lastly, many applications now include auto-update functionality, where updates are downloaded without sufficient integrity verification and applied to the previously trusted application. Attackers could potentially upload their own updates to be distributed and run on all installations. Another example is where objects or data are encoded or serialized into a structure that an attacker can see and modify is vulnerable to insecure deserialization.
How to Detect and Verify
Example: Insecure deserialization
Let's see a serialization and deserialization example in Python. Do a Basic search for functioncall:pickle.loads project:security-demo-python-django in Krugle. https://opensearch.krugle.org/document/search/#query=functioncall%3Apickle.loads%20project%3Asecurity-demo-python-django&qtype=basic
In the file pickleprick.py, pickle is used in order to retrieve all adventures. So if an attacker uploads a malicious pickle, it will be executed. However, if the developer wants to be able to read the result of the code execution, the reducer callable must return an object that meets with the adventures signature (which is an array of dictionary having a date, universe, planet and a morty). In order to do that, we will use the vulnerability twice: a first time to upload malicious python code, and a second time to execute it.
To avoid this vulnerability, software development teams must not use pickle (or any other untrusted component) to parse untrusted data. It is easy to write custom convert_data_to_string(data) and convert_string_to_data(string) functions that handle malicious code properly. This type of validation should also be present inside any serialization and deserialization functions.
Example 8
Logging & Monitoring Vulnerabilities
Krugle Techniques Used
Functional Dependency Configuration Errors Artifact Metdata Direct Inspection
Description
Exploitation of insufficiently configured logging and monitoring is a powerful attack vector. Attackers often rely on the lack of monitoring and timely response to achieve their goals without being detected.
In response, the goal of identifying and then remedying insufficient logging is to help detect, escalate, and respond to active breaches in a timely manner. Without logging and monitoring, breaches cannot be detected. Significant issues can result when:
How to Detect and Verify
Example: Sensitive logging detection
Searching functioncall:info lang:java project:"Security Demo Java" in the example project Security Demo Java produces 3 results:
Upon inspection of the second file we see that the developer tries to log the sensitive information ACCESS_KEY_ID and SECRET_KEY. In this example, even user credit card information is written to the log files.
Example 9
Server Side Request Forgery Vulnerabilities (SSRF)
Krugle Techniques Used
Functional Dependency Configuration Errors Artifact Metdata Direct Inspection
Description
SSRF vulnerabilities occur whenever a web application is fetching a remote resource without validating the user-supplied URL. It allows an attacker to coerce the application to send a crafted request to an unexpected destination, even when protected by a firewall, VPN, or another type of network access control list (ACL).
As modern web applications provide end-users with convenient features, fetching a URL becomes a common scenario. As a result, the incidence of SSRF is increasing. Also, the severity of SSRF is becoming higher due to cloud services and the complexity of architectures.
How to Detect and Verify
If any part of the URL being forwarded, or redirected, to is based on user input, then the site could be at risk. Ensure:
Example - Search for SSRF
This example shows you how to scan all redirect behavior based on user input which is a potential SSRF in the Java web application.
A search for getParameter functioncall:sendRedirect lang:java produces hits for Servlets or controllers that accept the user input and use them inside a redirect.
The result shows that the project Security Demo Java and Hadoop v3.1.1 have SSRF. Let's review each of them to confirm the vulnerability.
For the file LoginHandlerServlet.java of the Security Demo Java project, notice that the theNextURL is a user input without any whitelist/trusted site validation. This positively confirms a dangerous SSRF vulerability in this project.
Now let's check Hadoop. In v3.1.3, the file WebAppProxyServlet.java has calls to ProxyUtils.sendRedirect everywhere to directly redirect the user input toFetch parameter without validation. This positively confirms a SSRF vulnerability in this version of Hadoop.