|
| 1 | +# Introduction to CodeQL (formerly known as Semmle QL) |
| 2 | + |
| 3 | +👋 by Thanat Sirithawornsant, Senior Security Engineer, Citrix 🥳 |
| 4 | +# What is CodeQL? |
| 5 | + |
| 6 | +- CodeQL is advertised as a variant analysis tool. |
| 7 | +- It is a query language which has its own syntax. |
| 8 | +- It can be used to find a piece of code in a code base, not necessarily bugs or defects. |
| 9 | +- It can be used as part of you CI/CD pipelines to detect bad smells. |
| 10 | +- Free for research and open source |
| 11 | + |
| 12 | + |
| 13 | + |
| 14 | +## I am comfortable with grep, so I could just stick with that 🤔 |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | +## Or even ripgrep 💭 |
| 19 | + |
| 20 | + |
| 21 | + |
| 22 | +# well, how about unsafe deserialisation vulnerabilities? 😟 |
| 23 | + |
| 24 | + |
| 25 | +# Example Vulnerable Java Application 😑 |
| 26 | + |
| 27 | +https://github.com/ScaleSec/vulnado |
| 28 | + |
| 29 | +- written in Java based on spring framework |
| 30 | +- MVC model |
| 31 | +- with some writeup |
| 32 | + |
| 33 | +# Getting Started 🧐 |
| 34 | + |
| 35 | +CodeQL offers 2 ways to use their tool |
| 36 | + |
| 37 | +1. CodeQL CLI for engineers |
| 38 | +2. LGTM.com -> CodeQL Platform |
| 39 | + |
| 40 | +## CodeQL CLI 🥂 |
| 41 | + |
| 42 | +Instructions: https://help.semmle.com/codeql/codeql-cli/procedures/get-started.html |
| 43 | + |
| 44 | +- can compile a database for CodeQL locally |
| 45 | + - allowing engineers to do experiments and research locally |
| 46 | +- can easily run batches on queries with ease |
| 47 | + |
| 48 | +## LGTM.com 🖖 |
| 49 | + |
| 50 | +- can be used straight away on their platform for open source projects |
| 51 | +- fancy UI |
| 52 | +- a bit slower than querying locally, probably because of shared environment or some sort of restrictions |
| 53 | +- once the project has been imported, the database can be exported |
| 54 | + |
| 55 | +# Create a database 🛠🖍 |
| 56 | + |
| 57 | + |
| 58 | + |
| 59 | + |
| 60 | +# Running the built-in queries 🧰 |
| 61 | + |
| 62 | +## Issues ⚠️ |
| 63 | + |
| 64 | +| Issue | Type | Location | Line Number | |
| 65 | +| --------------------------------------------------- | ------- | ------------------------------------------------- | -------------- | |
| 66 | +| Query built without neutralizing special characters | error | /src/main/java/com/scalesec/vulnado/User.java | 49, 40, 49, 44 | |
| 67 | +| Use of a broken or risky cryptographic algorithm | warning | /src/main/java/com/scalesec/vulnado/Postgres.java | 67, 32, 67, 63 | |
| 68 | +| Executing a command with a relative path | warning | /src/main/java/com/scalesec/vulnado/Cowsay.java | 11, 28, 11, 33 | |
| 69 | + |
| 70 | +## Run `codeql database analyze` to run queries in a batch |
| 71 | + |
| 72 | + |
| 73 | + |
| 74 | +# List all the endpoints |
| 75 | + |
| 76 | +- let's observe how the application declare endpoints |
| 77 | + - it should be within controller files |
| 78 | +- what are the characteristics or the definitions? |
| 79 | + - find the patterns and confirm your results |
| 80 | + |
| 81 | +```java |
| 82 | +import org.springframework.http.HttpStatus; |
| 83 | +import org.springframework.web.bind.annotation.*; |
| 84 | +import org.springframework.beans.factory.annotation.*; |
| 85 | +import org.springframework.boot.autoconfigure.*; |
| 86 | +import java.util.List; |
| 87 | +import java.io.Serializable |
| 88 | + |
| 89 | +@RestController |
| 90 | +@EnableAutoConfiguration |
| 91 | +public class CommentsController { |
| 92 | + @Value("${app.secret}") |
| 93 | + private String secret; |
| 94 | + |
| 95 | + @CrossOrigin(origins = "*") |
| 96 | + @RequestMapping(value = "/comments", method = RequestMethod.GET, produces = "application/json") |
| 97 | + List<Comment> comments(@RequestHeader(value="x-auth-token") String token) { |
| 98 | + User.assertAuth(secret, token); |
| 99 | + return Comment.fetch_all(); |
| 100 | + } |
| 101 | + [...] |
| 102 | +} |
| 103 | +``` |
| 104 | + |
| 105 | +# List all public endpoint |
| 106 | + |
| 107 | +```java |
| 108 | + @CrossOrigin(origins = "*") |
| 109 | + @RequestMapping(value = "/comments", method = RequestMethod.GET, produces = "application/json") |
| 110 | + List<Comment> comments(@RequestHeader(value="x-auth-token") String token) { |
| 111 | + User.assertAuth(secret, token); |
| 112 | + return Comment.fetch_all(); |
| 113 | + } |
| 114 | + |
| 115 | + @CrossOrigin(origins = "*") |
| 116 | + @RequestMapping(value = "/comments", method = RequestMethod.POST, produces = "application/json", consumes = "application/json") |
| 117 | + Comment createComment(@RequestHeader(value="x-auth-token") String token, @RequestBody CommentRequest input) { |
| 118 | + return Comment.create(input.username, input.body); |
| 119 | + } |
| 120 | +``` |
| 121 | + |
| 122 | + |
| 123 | +# List all the user input |
| 124 | + |
| 125 | +```java |
| 126 | + @CrossOrigin(origins = "*") |
| 127 | + @RequestMapping(value = "/comments", method = RequestMethod.POST, produces = "application/json", consumes = "application/json") |
| 128 | + Comment createComment(@RequestHeader(value="x-auth-token") String token, @RequestBody CommentRequest input) { |
| 129 | + return Comment.create(input.username, input.body); |
| 130 | + } |
| 131 | + |
| 132 | + @CrossOrigin(origins = "*") |
| 133 | + @RequestMapping(value = "/comments/{id}", method = RequestMethod.DELETE, produces = "application/json") |
| 134 | + Boolean deleteComment(@RequestHeader(value="x-auth-token") String token, @PathVariable("id") String id) { |
| 135 | + return Comment.delete(id); |
| 136 | + } |
| 137 | +``` |
| 138 | + |
| 139 | + |
| 140 | + |
| 141 | +# User Input Taint Tracking |
| 142 | + |
| 143 | +## we could |
| 144 | + |
| 145 | +- list all the endpoints |
| 146 | + - including public ones, with allow list even |
| 147 | +- list all the user input |
| 148 | + - including URL query, HTTP body, URL path |
| 149 | + |
| 150 | +## Now, we would like to see which input ends up in an unsafe method |
| 151 | + |
| 152 | +# I am sold! How do I get started? |
| 153 | + |
| 154 | +## RTFM |
| 155 | + |
| 156 | +https://help.semmle.com/QL/learn-ql/ |
| 157 | + |
| 158 | +### References |
| 159 | + |
| 160 | +https://help.semmle.com/QL/ql-handbook/index.html |
| 161 | + |
| 162 | +### Built-in queries |
| 163 | + |
| 164 | +https://help.semmle.com/wiki/display/JAVA/Java+queries |
| 165 | +https://github.com/github/codeql/tree/master/java/ql/src/Security/CWE |
| 166 | + |
| 167 | +## CTF challenges with real bugs |
| 168 | + |
| 169 | +https://securitylab.github.com/ctf |
| 170 | + |
| 171 | +## Real bugs advisories |
| 172 | + |
| 173 | +https://blog.semmle.com/ |
| 174 | + |
| 175 | +## Or just use the aforementioned example and play with it |
| 176 | + |
| 177 | +# Thank you 2600 staff members and the community 🙏 |
0 commit comments