Code Scanning with CodeQL
CodeQL is GitHub's code analysis engine and is the default scanner behind GitHub's code scanning feature. It treats code as data - compiling it into a queryable database and then running semantic analysis queries against that database to find vulnerabilities.
CodeQL supports a wide range of languages, including:
- JavaScript
- TypeScript
- Python
- Java
- C#
- Go
- Ruby
- C
- C++.
For most languages, enabling code scanning is as simple as adding the official CodeQL workflow to your repository.
Setting Up Code Scanning
The default setup can be enabled directly in the repository's Security tab with a single click, or configured via a workflow file for more control:
name: CodeQL Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 2 * * 1' # Weekly scan every Monday at 2am
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
strategy:
matrix:
language: [csharp, javascript-typescript]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-extended # Run extended security query suite
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"
What CodeQL Finds
CodeQL's query suites detect a wide range of vulnerability classes, including:
- Injection vulnerabilities: SQL injection, command injection, path traversal.
- Cross-site scripting (XSS: reflected, stored, and DOM-based XSS.
- Insecure deserialisation: unsafe object deserialization patterns.
- Cryptographic issues: use of weak algorithms, insecure random number generation.
- Taint tracking: end-to-end data flow analysis from untrusted input to sensitive sinks.
- Authentication weaknesses: hardcoded credentials, missing authentication checks.
Results appear directly in pull requests as annotations on the affected lines of code, in the Security tab of the repository, and can trigger branch protection rules that block merging until findings are resolved or dismissed.
Third-Party Scanners via SARIF
Code scanning is not limited to CodeQL. GitHub supports the SARIF (Static Analysis Results Interchange Format) standard, which means any SARIF-compatible scanner can upload results to GitHub. This includes tools like Semgrep, Snyk, Checkmarx, Veracode, SonarQube, and many others. All findings are consolidated in the same Security tab, giving a unified view regardless of which scanner produced them.
Secret Scanning
Secret scanning automatically detects secrets, API keys, tokens, connection strings, private keys, and other credentials committed to a repository. It operates on both the current state of the repository and on the entire commit history retrospectively.
How It Works
GitHub maintains patterns for over 200 secret types from providers such as AWS, Azure, Google Cloud, Stripe, Twilio, Slack, and many others. When a secret matching one of these patterns is detected:
- The repository owner and security manager are alerted.
- If the secret is from a partnered provider, GitHub notifies the provider directly, who can revoke the token automatically
- The finding appears in the repository's Security tab under Secret Scanning alerts.
Push Protection
The most powerful aspect of secret scanning is push protection. Rather than detecting secrets after they have been committed, push protection blocks the push at the point of git push if a secret is detected in the new commits. The developer sees an error message identifying the secret and is blocked from pushing until they either remove the secret or explicitly acknowledge the bypass (which is logged for audit purposes).
remote: Push rejected. Secret scanning found a potential secret.
remote:
remote: To push this commit, please remove the secret detected in:
remote: file: src/appsettings.json
remote: line: 12
remote: type: Azure Storage Account Key
This stops the secret from ever reaching the repository, rather than relying on detection and rotation after the fact.
Custom Patterns
For organisation-specific secrets (internal service tokens, proprietary API formats), GitHub supports custom secret scanning patterns defined using regular expressions. These can be applied at the repository, organisation, or enterprise level.
Dependency Review and Dependabot
Third-party dependencies are one of the most common sources of vulnerabilities in modern applications. GitHub provides two complementary tools to address this.
Dependency Review
The dependency review action checks pull requests that modify dependency files (package.json, *.csproj, requirements.txt, go.mod, etc.) and reports any newly introduced dependencies that have known vulnerabilities in the GitHub Advisory Database.
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate
deny-licenses: GPL-2.0, AGPL-3.0
This blocks pull requests from merging if they introduce a vulnerable dependency above a configurable severity threshold, or if they introduce a dependency with a licence that the organisation does not permit.
Dependabot Alerts and Security Updates
Dependabot continuously monitors the dependency graph of every repository and raises alerts when a dependency is found to have a known CVE. It goes further than just alerting — Dependabot can automatically open pull requests to update the vulnerable dependency to a patched version.
Dependabot version updates extend this to proactive maintenance: keeping all dependencies current on a configured schedule, reducing the gap between what teams are running and what is latest.
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 10
reviewers:
- my-org/security-team
Security Overview: Organisation-Wide Visibility
For security teams and engineering managers, GitHub Enterprise provides a Security Overview dashboard at the organisation and enterprise level. This gives a consolidated view of:
- Which repositories have GHAS features enabled
- Outstanding code scanning alerts by severity and age
- Secret scanning alerts and their remediation status
- Dependabot alert counts and fix rates
This makes it possible to prioritise remediation effort, identify repositories with the highest risk exposure, and track security posture over time — all without leaving GitHub.
Comparing with Azure DevOps Security Capabilities
Azure DevOps does not include native static analysis, secret scanning, or dependency review. Organisations using Azure DevOps typically rely on:
- Third-party extensions from the Azure DevOps Marketplace (e.g., SonarQube, WhiteSource/Mend, Checkmarx)
- Separate CI pipeline steps that run scanners and report results externally
- Manual processes for detecting and rotating leaked secrets
This fragmented model means results are scattered across multiple tools, integration requires custom effort, and there is no unified view of security posture.
GitHub Advanced Security provides all of this natively, with results surfaced in the exact context where developers are already working.
Rolling Out GHAS Across an Organisation
For large organisations with many repositories, a phased rollout is recommended:
- Enable on new repositories by default: configure the organisation to automatically enable GHAS on all newly created repositories
- Enable push protection organisation-wide: this is low-friction and high-value; block secrets before they are committed
- Pilot code scanning on high-risk repositories: start with repositories that handle authentication, payments, or sensitive data
- Review and triage existing alerts: before broad rollout, review the backlog and establish a triage process
- Integrate with your security workflow: connect GitHub Security alerts to your SIEM, ticketing system, or security operations tooling via webhooks or the GitHub API
Conclusion
GitHub Advanced Security represents a significant shift in how organisations approach application security, moving from reactive scanning to proactive prevention, integrated directly into the development workflow. The combination of CodeQL's semantic analysis, push protection for secrets, and Dependabot's automated remediation provides a security posture that would require multiple separate tools to replicate in Azure DevOps.
The final article in this series looks at the capability that is arguably the most exciting development in GitHub Enterprise: how GitHub Copilot and its enterprise features can fundamentally change the productivity and quality of your engineering organisation.