diff --git a/README.md b/README.md new file mode 100644 index 0000000..b2c38fd --- /dev/null +++ b/README.md @@ -0,0 +1,269 @@ +# Code Scanning Java Tutorial + +Welcome to the Code Scanning Java Tutorial! This tutorial will take you through how to set up Github Advanced Security: Code Scanning as well as interpret results that it may find. The following repository contains SQL injection vulnerability for demonstration purpose. + +## Introduction + +Code scanning is a feature that you use to analyze the code in a GitHub repository to find security vulnerabilities and coding errors. Any problems identified by the analysis are shown in GitHub. + +You can use code scanning with CodeQL, a semantic code analysis engine. CodeQL treats code as data, allowing you to find potential vulnerabilities in your code with greater confidence than traditional static analyzers. + +This tutorial with use CodeQL Analysis with Code Scanning in order to search for vulnerabilities within your code. + +## Instructions + +
+Create repository fork +

+ +Begin by [creating a new repository from a fork (public)](https://docs.github.com/en/get-started/quickstart/fork-a-repo) or [cloning the repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository). + + + +Where creating the forked repository, make sure to + +1. Select the correct org / user account +2. Create a name for your new repository +3. Disable main branch only cloning +4. Create the repository from the template + +

+
+ +
+Enable Code Scanning +

+ +#### Security tab + +Click on the `Security` tab. + + + + +#### Set up code scanning + +Click `Set up code scanning`. + + + +#### Setup Workflow + +Click the `Setup this workflow` button by CodeQL Analysis. + + + +This will create a GitHub Actions Workflow file with CodeQL already set up. Since Java is a compiled language you will need to setup the build in later steps. See the [documentation](https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/running-codeql-code-scanning-in-your-ci-system) if you would like to configure CodeQL Analysis with a 3rd party CI system instead of using GitHub Actions. +

+
+ +
+ +Actions Workflow file +

+ +#### Actions Workflow + +The Actions Workflow file contains a number of different sections including: +1. Checking out the repository +2. Initializing the CodeQL Action +3. Running Autobuilder (or code your own build steps if autobuild doesn't work) +4. Running the CodeQL Analysis + + + +Click `Start Commit` -> `Commit this file` to commit the changes to _main_ branch. +

+
+ +
+ +Workflow triggers +

+ +#### Workflow triggers + +There are a [number of events](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows) that can trigger a GitHub Actions workflow. In this example, the workflow will be triggered on + + + +- push to _main_ branch +- pull request to merge to _main_ branch +- on schedule, at 6:33 every Thursday + +Setting up the new CodeQL workflow and committing it to _main_ branch in the step above will trigger the scan. + +

+
+ + +
+GitHub Actions Progress + +

+ +#### GitHub Actions Progress + +Click `Actions` tab -> `CodeQL` + +Click the specific workflow run. You can view the progress of the Workflow run until the analysis completes. + + + +

+
+ +
+Security Issues +

+ +Once the Workflow has completed, click the `Security` tab -> ` Code Scanning Alerts`. An security alert "Query built from user-controlled sources" should be visible. + +#### Security Alert View + +Clicking on the security alert will provide details about the security alert including:
+

+ + +#### Security Alert Description + +Click `Show more` to view a full desciption of the alert including examples and links to additional information. + + + +#### Security Full Description + + + +

+
+ +
+Show Paths +

+ +#### Show Paths Button + +CodeQL Analysis is able to trace the dataflow path from source to sink and gives you the ability to view the path traversal within the alert. + +Click `show paths` in order to see the dataflow path that resulted in this alert. + + + +#### Show Paths View + + + +

+
+ +
+

+ +

Fix the Security Alert + +In order to fix this specific alert, we will need to ensure parameters used in the SQL query is validated and sanitized. + +Click on the `Code` tab and [Edit](https://docs.github.com/en/free-pro-team@latest/github/managing-files-in-a-repository/editing-files-in-your-repository) the file [`IndexController.java`](./src/main/java/com/github/hackathon/advancedsecurityjava/Controllers/IndexController.java) in the `Controllers` folder, replace the content with the file [`fixme`](./fixme). + + + +Click `Create a new branch for this commit and start a pull request`, name the branch `fix-sql-injection`, and create the Pull Request. + +#### Pull Request Status Check + +In the Pull Request, you will notice that the CodeQL Analysis has started as a status check. Wait until it completes. + + + +#### Security Alert Details + +After the Workflow has completed click on `Details` by the `Code Scanning Results / CodeQL` status check. + + + +#### Fixed Alert + +Notice that Code Scanning has detected that this Pull Request will fix the SQL injection vulnerability that was detected before. + + + +Merge the Pull Request. After the Pull Request has been merged, another Workflow will kick off to scan the repository for any vulnerabilties. + +#### Closed Security Alerts + +After the final Workflow has completed, navigate back to the `Security` tab and click `Closed`. Notice that the **Query built from user-controlled sources** security alert now shows up as a closed issue. + + + +#### Traceability + +Click on the security alert and notice that it details when the fix was made, by whom, and the specific commit. This provides full traceability to detail when and how a security alert was fixed and exactly what was changed to remediate the issue. + + + +

+
+ +
+Prevent new Alerts in a Pull Request +

+ +#### Create Pull Request from new feature Branch + +Now that we have setup CodeQL Analysis and have fix a security alert, we can try to introduce an alert into a Pull Request. + +Create a new Pull Request with the base branch as your `main` branch and the compare branch as the `new-feature` branch. + + + +Make sure that the base branch is set to your own repositories `main` branch versus the original repository's `main` branch. + + +#### Pull Request Status Check + +Once the Pull Request has been created, you will notice that the CodeQL Analysis has started as a status check. Wait until it completes. + +After the Workflow has completed, the `Code Scanning Results / CodeQL` status check will have failed. +Notice that Code Scanning has detected that this Pull Request introduces a new security alert. + + + + +#### Alert Centric Notifications + +Directly in the Pull Request, you will notice that GitHub Code Scanning bot has left a review of the Pull Request with the security alert details. +This will help developers to quickly identify security issues introduced in their Pull Requests. + + + + +This also allows for collaboration between developers and security teams to discuss the security alert and how to remediate it. + + + +#### Security Alert Details + +Click on `Show more details` by the new `Code Scanning Alert` to jump to the `Security` tab and view the security alert details. + + + +Notice that the security alert was found `In pull request` and not in the `main` branch (production). + + +

+
+ + +## Next Steps + +Ready to talk about advanced security features for GitHub Enterprise? [Contact Sales](https://enterprise.github.com/contact) for more information! + +Check out [GitHub's Security feature page](https://github.com/features/security) for more security features embedded into GitHub. + +Check out the Code Scanning [documentation](https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/about-code-scanning) for additional configuration options and technical details. diff --git a/src/main/java/com/github/hackathon/advancedsecurityjava/Controllers/IndexController.java b/src/main/java/com/github/hackathon/advancedsecurityjava/Controllers/IndexController.java index 2a8439e..21f7aa9 100644 --- a/src/main/java/com/github/hackathon/advancedsecurityjava/Controllers/IndexController.java +++ b/src/main/java/com/github/hackathon/advancedsecurityjava/Controllers/IndexController.java @@ -2,9 +2,9 @@ import java.sql.Connection; import java.sql.DriverManager; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Statement; import java.util.ArrayList; import java.util.List; @@ -28,31 +28,41 @@ public List getBooks(@RequestParam(name = "name", required = false) String @RequestParam(name = "read", required = false) Boolean bookread) { List books = new ArrayList(); - Statement statement = null; + PreparedStatement statement = null; + List parameters = new ArrayList<>(); try { // Init connection to DB connection = DriverManager.getConnection(Application.connectionString); - statement = connection.createStatement(); String query = null; if (bookname != null) { // Filter by book name - query = "SELECT * FROM Books WHERE name LIKE '%" + bookname + "%'"; + query = "SELECT * FROM Books WHERE name LIKE ?"; + parameters.add("%" + bookname + "%"); } else if (bookauthor != null) { // Filter by book author - query = "SELECT * FROM Books WHERE author LIKE '%" + bookauthor + "%'"; + query = "SELECT * FROM Books WHERE author LIKE ?"; + parameters.add("%" + bookauthor + "%"); } else if (bookread != null) { // Filter by if the book has been read or not Integer read = bookread ? 1 : 0; - query = "SELECT * FROM Books WHERE read = '" + read.toString() + "'"; + query = "SELECT * FROM Books WHERE read = ?"; + parameters.add(read.toString()); } else { // All books query = "SELECT * FROM Books"; } - ResultSet results = statement.executeQuery(query); + statement = connection.prepareStatement(query); + int index = 1; + for (String parameter : parameters) { + statement.setString(index, parameter); + index += 1; + } + + ResultSet results = statement.executeQuery(); while (results.next()) { Book book = new Book(results.getString("name"), results.getString("author"), (results.getInt("read") == 1));