How GitHub Copilot Helps You Write More Secure Code
GitHub Copilot can help you write more secure code — but only if you guide it correctly. This post walks through real examples.
Join the DZone community and get the full member experience.
Join For FreeEarly-career developers often struggle with secure coding practices. GitHub Copilot, an AI pair programmer, can assist in writing safer code when used wisely. However, guidance is key; a 2021 study found that approximately 40% of Copilot’s generated code had security vulnerabilities when developers weren’t careful. GitHub responded by upgrading Copilot’s AI model and adding a real-time vulnerability filter to block common insecure patterns.
In this post, we’ll explore how Copilot can help you write more secure code through clear prompts and examples.
Guiding Copilot to Write Secure Code
Copilot learns from billions of lines of code, including both good and bad practices. To get secure suggestions, you must steer it in the right direction. The GitHub documentation notes that many vulnerabilities (like SQL injection, cross-site scripting, etc.) can be avoided with practices such as parameterized queries, input validation, and avoiding hard-coded secrets.
You encourage safer code outputs by explicitly asking Copilot for these practices in your prompts (e.g., via comments or function names). Always review Copilot’s suggestions — think of them as helpers that still need your verification.
Let’s walk through five examples where Copilot assists in writing more secure code. Each example highlights a common security issue and how a well-crafted prompt yields a secure solution.
Example 1: Avoid Hard-Coding Secrets (Use Environment Variables)
Hard-coding API keys or passwords in code is a serious risk — it could expose secrets if your code is leaked. Copilot’s vulnerability filter is designed to catch this by flagging hard-coded credentials. For example, if you write a comment indicating you want to use an environment variable for an API key, Copilot will suggest doing exactly that:
# Use environment variable for API key
api_key = os.getenv('SERVICE_API_KEY')
if not api_key:
raise RuntimeError("API key not found in environment")
# ... proceed to use api_key ...
Why This Helps
Instead of inserting a secret directly in code, the suggestion uses an environment variable. This way, the sensitive key isn’t stored in your source code, reducing the chance of accidental exposure. Avoiding hard-coded sensitive data is a core secure coding practice. With Copilot’s guidance, you easily implement this best practice. (Feeling confident with secrets? Next, let’s tackle database queries).
Example 2: Prevent SQL Injection With Parameterized Queries
SQL injection is one of the most common web vulnerabilities. It happens when user input is concatenated into SQL statements without proper handling, allowing attackers to inject malicious SQL. GitHub Copilot can help prevent this by suggesting parameterized queries instead of raw string building. For instance, if you prompt Copilot to insert data using a parameterized query, you might get code like:
# Insert user input into database with a parameterized query
sql = "INSERT INTO orders (email, product_name) VALUES (?, ?)"
cursor.execute(sql, (user_email, product_name))
Why This Helps
Using "?" placeholders (or $1, $2 in some languages) with cursor.execute ensures that the database driver handles the user data safely. This prevents malicious input from altering the SQL command, thwarting injection attacks.
In contrast, an insecure approach would build the query as a string (e.g., "... VALUES ('" + user_email + "')"), which is vulnerable. Copilot’s suggestion follows the secure pattern, as GitHub’s own guides emphasize, parameterized queries neutralize SQL injection risk. (We’ve secured our database writes. Now, how about securing user-facing outputs?)
Example 3: Sanitize Outputs to Prevent XSS
Cross-site scripting (XSS) occurs when an application injects user input into web pages without sanitization, potentially letting attackers run scripts in the user’s browser. Copilot can assist by proposing safer output methods. Suppose we have JavaScript code that displays a user’s name on a page. Instead of using a vulnerable property, we can ask Copilot to ensure it’s safe. For example:
// Display user-provided name safely on the page
const nameElement = document.getElementById('name-display');
nameElement.textContent = `Showing results for "${name}"`;
Why This Helps
Here, Copilot suggested using textContent
instead of setting HTML directly. The textContent
property will automatically escape any malicious content in the name, preventing it from being interpreted as HTML or script. An insecure version using innerHTML
might have been exploited by a name like "<script>...</script>".
In fact, Copilot is capable of detecting this XSS issue and recommending textContent
as a fix. By following such suggestions, you ensure that user input is sanitized before rendering. (With front-end display secured, let’s wrap up what we’ve learned.)
Example 4: Safe DOM Update to Prevent XSS
Copilot Prompt
In a JavaScript file, we write a function outline with a comment describing our goal:
// Safely display user-provided comment on the page without XSS vulnerabilities
function renderComment(commentText) {
// TODO: add commentText to the DOM safely
}
Copilot Suggestion
GitHub Copilot autocompletes the function with a secure implementation:
function renderComment(commentText) {
const commentDiv = document.createElement('div');
commentDiv.textContent = commentText; // assign text safely, not as HTML
document.getElementById('comments').appendChild(commentDiv);
}
Explanation
In this suggestion, Copilot chose textContent instead of innerHTML
when inserting user input into the DOM. This is more secure because textContent treats the content strictly as text, meaning any HTML tags or scripts in commentText are not executed but shown as plain text.
By avoiding innerHTML
, the code prevents cross-site scripting (XSS) attacks, where malicious scripts could otherwise be injected and run on your page. The Copilot prompt included “without XSS,” so it knew to avoid insecure patterns. This way, even a beginner can automatically get a safer solution for rendering user input.
Example 5: Enforcing HTTPS in an Express App
Copilot Prompt
In a Node.js/Express application, we add a comment indicating the need for HTTPS enforcement:
// Express middleware to redirect HTTP requests to HTTPS for security
Copilot Suggestion
Copilot generates a middleware snippet that forces secure connections:
app.enable('trust proxy'); // enable if behind a proxy (e.g., Heroku)
app.use((req, res, next) => {
if (!req.secure) {
// Redirect to the same URL but with HTTPS
return res.redirect('https://' + req.headers.host + req.url);
}
next();
});
Explanation
Copilot recognized the security intent and suggested a common Express pattern for HTTPS enforcement. The code checks req.secure, a boolean provided by Express that is false for HTTP requests and true for HTTPS. If the request isn’t secure, it automatically redirects the client to the HTTPS version of the URL. This ensures all data transfer is encrypted via SSL/TLS, protecting sensitive information in transit.
The inclusion of app.enable('trust proxy') is a bonus best practice Copilot added for scenarios (like cloud hosting) where a proxy might handle SSL — it makes the req.secure check reliable. For a beginner, this generated snippet not only saves time but also instills a security best practice (always using HTTPS) without having to know the exact code upfront.
Conclusion: Copilot as a Security Co-Pilot
GitHub Copilot can be a valuable ally in writing secure code when guided thoughtfully. We saw how clear prompts (like “use env var” or “parameterized query”) lead to security-conscious code suggestions. By leveraging Copilot’s knowledge of best practices, even a novice developer can implement defenses against common vulnerabilities.
That said, Copilot is a generalist, not a specialist — it doesn’t replace dedicated security tools or your own vigilance. Always review Copilot’s output and use additional measures like code scanning and dependency checks for a comprehensive security strategy. The good news is that Copilot’s real-time checks (for hard-coded secrets, injection patterns, etc.), combined with your oversight, create a strong feedback loop for safer coding.
In summary, GitHub Copilot can help you write more secure code faster, from catching injection risks to suggesting safer libraries. With the right guidance and verification, it transforms from an auto-completion tool into a pseudo-security coach. Use it to amplify your secure coding practices — and remember, the best results come when you pair Copilot’s power with your own careful eye. Guided thoughtfully, Copilot becomes not just an AI assistant, but a reliable partner in building robust, secure software
Opinions expressed by DZone contributors are their own.
Comments