SAST/DAST

Cards (92)

  • One of the methods used for developing secure applications is frequently testing the code for security bugs through a process known as code review. Code reviews consist of looking at the source code of an application to search for possible vulnerabilities using a white box approach. By having access to the code, the reviewer can guarantee a greater coverage of the application's functionalities and lower the time required to find bugs.
  • Manual vs Automated Code Review
    • Manual code reviews have the advantage of a human evaluating the code, which allows for a thorough analysis and more precise results. However, since an application often has thousands and thousands of lines of code, the task can quickly become overwhelming for the reviewer, leading to some vulnerabilities being missed because of fatigue.
  • Manual vs Automated Code Review
    • Automated tools excel at finding common vulnerabilities almost instantly, saving loads of time to the reviewer. Automated tools will also perform consistently, no matter the size of the code base, so they won't miss vulnerabilities as a human could do, as long as they have predefined rules to match them. If the tool has no rules configured for a specific type of vulnerability, they are likely to miss those.
  • Manual vs Automated Code Review
    • The cost of a manual review will often be higher, as a reviewer must spend lots of time tracing vulnerabilities through the code. Automated tools will perform their analysis almost instantly.
    • For these reasons, you will typically want to run automated tests early in the development lifecycle to take care of all the low-hanging fruits with lower costs and have manual reviews spaced periodically or when important project goals are met to take care of complex vulnerabilities that the automated tools may not be able to detect.
  • Searching for Insecure Functions
    • The first step when reviewing code is identifying potentially insecure functions in use. Since we are looking for SQL injections, we should focus on any functions that could be used to send raw queries to the database. Since our code uses PHP and MySQL, here are some functions that are typically used to send MySQL queries:
  • Manual Code Review: A straightforward way to manually search instances of such functions is to use grep to check all of our project's files recursively. For example, to search for instances of mysqli_query(), go to the project's base directory and run the following command:
    • The-roption tells grep to recursively search all files under the current directory, and the-noption indicates that we want grep to tell us the number of the line where the pattern was found. In the above terminal output, we can see that a single instance ofmysqli_query()was found on line18.
  • Understanding the Context
    • Here we can see that mysqli_query() is wrapped into the db_query() function, and that the $query parameter is passed directly without modification. It is very common for functions to be nested into other functions, so simply analysing the local context of a function is sometimes not enough to determine if a vulnerability is present. We now need to trace the uses of the db_query() function throughout our code to identify potential vulnerabilities.
  • Tracing User Inputs to Potentially Vulnerable Functions
    • We can use grep again to search for uses of db_query():
  • Tracing User Inputs to Potentially Vulnerable Functions
    • SQL injection! Whatever is passed in the guest_id parameter via the GET method will be concatenated to a raw SQL query without any input sanitisation, enabling the attacker to change the query.
  • Tracing User Inputs to Potentially Vulnerable Function
    • Again, we have some GET parameters being concatenated into SQL queries. This would give us the impression that we have two more vulnerabilities identified. Still, in both cases, the GET parameters are sanitised through preg_replace() using different regular expressions to replace any character that isn't allowed with an empty string. To decide if these lines of code are vulnerable, we will need to evaluate if the filters in place allow SQL injections to pass.
  • Tracing User Inputs to Potentially Vulnerable Function
    • The query on $sql2 is passed through a filter that only allows characters that are either alphanumeric or double-quotes. While double-quotes may seem like a possible vector for SQLi, they don't pose a threat in this case since the SQL sentence encloses the string passed through $_GET['log_id'] between single-quotes ('). Since an attacker would have no way to escape from the string in the SQL sentence, we can be sure that this line isn't vulnerable.
    • The query on $sql3 is even more restrictive, allowing only numeric characters to be passed through $_GET['art_id']. However, notice that the preg_replace() function is called with a third parameter set to "1". If we refer to the manual page of the function, we will learn that the third parameter indicates the maximum number of replacements to be done. Since it is set to 1, only the first character that isn't a number will be replaced with an empty string. Any other characters will pass without being replaced, enabling SQL injections. This line is indeed vulnerable.
  • Static Application Security Testing
    • Static Application Security Testing (SAST) refers to using automated tools for code analysis. The idea is not to replace manual code reviews but to provide a simple method to automate simple code checks to quickly find vulnerabilities during the development process without requiring a specialised individual.
  • Static Application Security Testing (SAST)
    • SAST complements other techniques, such as Dynamic Application Security Testing (DAST) or Software Composition Analysis (SCA), to provide a holistic approach to application security during the development lifecycle. Just as with any of the other techniques, SAST will have its pros and cons that we need to be aware of:
  • SAST Pros and Cons:
  • Transform the code into an abstract model: SAST tools usually ingest the source code and produce an abstract representation for further analysis. Most SAST tools will represent the code using Abstract Syntax Trees (AST), but some tools may have other equivalent proprietary structures. This allows for easier code analysis in a way that is independent of the programming language in use. This step is crucial for later analysis, as any feature of a programming language that isn't correctly translated into the AST will probably not be analysed for security issues effectively.
  • Analyse the abstract model for security issues: Different analysis techniques will be used to search for potential vulnerabilities in the code model.
  • SAST Analysis Techniques:
    Semantic analysis: This type of analysis can be compared to grepping for potentially insecure functions while doing manual code reviews. It aims to find flaws concerning the use of potentially insecure code in a localised context.
    • Examples of this include searching for calls to mysqli_query() where GET or POST parameters are directly concatenated into the query string:
  • SAST Analysis Techniques:
    Dataflow analysis
    • There are situations where potentially dangerous functions are in use, but it isn't clear whether or not a vulnerability is present just by analysing the local context around the function call. Take, for example, a function defined as follows:
    • By looking at the function's code, it's hard to say if there are any vulnerabilities. Analysing the local context of the call to a dangerous function is not enough in this case.
  • Dataflow analysis will trace how information flows from inputs the user can manipulate to potentially vulnerable functions, just as we did when manually analysing the provided application's code. In dataflow analysis terminology, data inputs will be referred to as sources, and potentially vulnerable functions will be referred to as sinks. If data flows from a source to a sink without sanitisation, we have a vulnerability.
  • Dataflow analysis
    • Going back to the db_query() function, dataflow analysis would have to find all of its usages and trace back to see if any tainted input (the source) is sent to it, finally ending up as part of the query executed by mysqli_query() (the sink).
  • Control flow analysis: Analyses the order of operations in the code in search for race conditions, use of uninitialised variables or resource leaks. As an example, look at the following piece of Java code:
    • If the cmd property isn't defined, the call to System.getProperty() will return NULL. Calling the trim method from a NULL variable will throw an exception on runtime.
  • Structural analysis: Analyses specific code structures of each programming language. This includes following best practices when declaring classes, evaluating code blocks that may never execute (dead code), correctly using try/catch blocks and other issues related to using insecure cryptographic material (weak keys or IVs).
    In this case, we have an implementation of RSA with a key size of 1024, considered insufficient by today's standards.
    • Here's a quick example of code that would be detected by structural analysis:
  • Configuration analysis: Searches for application configuration flaws rather than the code itself. As an example, applications running under Internet Information Services will have a configuration file called web.config, PHP will hold all of its configuration options in a file called php.ini, and most applications will use some configuration file. By checking configurations, the tool will identify possible improvements.
    • Here's an example of two configuration directives in PHP that would probably raise an alert on SAST tools, as they facilitate some attack vectors for RFI, SSRF or other:
  • Psalm (PHP Static Analysis Linting Machine), a simple tool for analysing PHP code
  • PSALM Config File:
    • We won't go too deep into the configuration options, but here you can see the errorLevel parameter, which indicates how strict Psalm will be when reporting issues. The lower the value, the more issues will be reported. There's also a section called projectFiles, where the files to be scanned are indicated. Only the html directory will be scanned for this project, and the vendor directory will be ignored (as we don't want to test third-party dependencies).
  • PSALM:
    • The default tests will search for issues with variable types, variable initialisation and other safe coding patterns. While these issues are not vulnerabilities, Psalm will make recommendations so your code follows coding best practices, which is a good start to avoid runtime errors.
    • Psalm also offers the possibility to run dataflow analysis on our code using the --taint-analysis flag. The output for this command will be much more interesting as it will pinpoint possible security issues. The output of the command will look like this:
  • Dataflow analysis usually gets the most interesting findings from a security standpoint. However, other structural findings are equally important to fix, even if they don't directly translate into an exploitable vulnerability. Structural flaws can often lead to business logic errors that may be hard to track or some unpredictable behaviours in your app.
  • Dealing With False Positives and False Negatives
    No matter what SAST tool you use, errors will always be present. Just as a quick reminder, we will generally be concerned with the two following error types:
    • False positives: The tool reports on a vulnerability that isn't present in the code.
    • False negatives: The tool doesn't report a vulnerability that is present in the code.
    These errors might present themselves because the tool cannot correctly assess the target code, but they can also be introduced if we, as users, don't use the tool correctly.
  • Finally, if you compare Psalm's results with our manual review, you should notice that there are some differences in the results:
  • A certain level of false positives and false negatives is always expected when using SAST tools. As with any other tool, you must manually check the report to search for any errors. SAST is an excellent complement to manual reviews but should never be considered as their replacement.
  • SAST is one of the first tools to appear during the development lifecycle. It is often implemented during the coding stage, as there's no need to have a functional application to use it.
  • Depending on each case, SAST can be implemented in one of the following ways:
    • CI/CD integration: Each time a pull request or a merge is made, SAST tools will check the code for vulnerabilities. Checking pull requests ensures that the code that makes it to merges has undergone at least a basic security check. On some occasions, instead of checking every single pull request, executing SAST scans only at merges may help prevent slowdowns in the development pipeline, as it avoids making all developers wait for full SAST scans.
    • IDE integrationSAST tools can be integrated into the developers' favourite IDEs instead of waiting for a pull request or merge to occur. This way, the code can be fixed as early as possible, saving time further ahead in the project.
  • Note that you may want SAST running on both the developers' IDEs and your CI/CD pipeline, which would be valid. For example, IDE tools may run basic structural checks and enforce secure coding guidelines, while CI/CD integrations may run more time-consuming dataflow/taint analysis. Remember that your specific setup will depend on the requirements of each project and should be evaluated by the team carefully.
  • Integrating SAST in IDEs
    • Psalm: The tool we've been using supports IDE integration by installing the Psalm plugin into VS Code directly from the Visual Studio Marketplace. This plugin will check anything you type in real-time and show you the same alerts as the console version directly into your code. Taint analysis won't be available, so you'll only see the structural problems reported on a basic Psalm analysis.
  • Integrating SAST in IDEs
    • Semgrep: Yet another SAST tool that can be installed into VS Code directly from the Visual Studio Marketplace. Just as with Psalm, it will show inline alerts directly in your code. Semgrep even allows us to build custom rules if needed. You can check the rules that are loaded for this project on the semgrep-rules directory inside the project's directory. The specifics on how to build Semgrep rules will be left for a future room, so don't worry about them now. You can check the rules in the directory, but this won't be required for this room.
  • Both tools will work similarly by showing any problems detected directly inline in your code. The only notable difference is that Semgrep will run when you start VS Code and will show you the problems it detects on all of the files, while Psalm will only show you issues related to the file you are currently editing. The plugins will add the following information to your IDE screen:
  • What is DAST?
    • Dynamic Application Security Testing (DAST) is the process of testing a running instance of a web application for weaknesses and vulnerabilities. It focuses on a black-box testing approach where vulnerabilities are found just like a regular attacker would find them. Simply put, DAST identifies vulnerabilities by trying to exploit them, either manually or through automated tools.
  • What is DAST?
    There are two ways in which DAST can be performed:
    • Manual DAST: A security engineer will manually perform tests against an application to check for vulnerabilities.
    • Automatic DAST: An automated tool will scan the web application for vulnerabilities.