Skip to content

Conversation

@paldepind
Copy link
Contributor

No description provided.

@github-actions github-actions bot added documentation Rust Pull requests that update Rust code labels Nov 24, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 24, 2025

QHelp previews:

rust/ql/src/queries/security/CWE-079/XSS.qhelp

Cross-site scripting

Directly writing user input (for example, an HTTP request parameter) to a web page, without properly sanitizing the input first, allows for a cross-site scripting vulnerability.

Recommendation

To guard against cross-site scripting, consider encoding/escaping the untrusted input before including it in the HTML.

Example

The following example shows a simple web handler that writes a URL path parameter directly to an HTML response, leaving the website vulnerable to cross-site scripting:

use actix_web::{web, HttpResponse, Result};

// BAD: User input is directly included in HTML response without sanitization
async fn vulnerable_handler(path: web::Path<String>) -> impl Responder {
    let user_input = path.into_inner();

    let html = format!(
        r#"
        <!DOCTYPE html>
        <html>
        <head><title>Welcome</title></head>
        <body>
            <h1>Hello, {}!</h1>
        </body>
        </html>
        "#,
        user_input
    );

    Html::new(html) // Unsafe: User input included directly in the response
}

To fix this vulnerability, the user input should be HTML-encoded before being included in the response. In the following example encode_text from the html_escape crate is used:

use actix_web::{web, HttpResponse, Result};

// GOOD: Manual HTML encoding using an `html_escape::encode_text` function
async fn safe_handler_with_encoding(path: web::Path<String>) -> impl Responder {
    let user_input = path.into_inner();
    let escaped_input = html_escape::encode_text(&user_input);
    let html = format!(
        r#"
        <!DOCTYPE html>
        <html>
        <head><title>Welcome</title></head>
        <body>
            <h1>Hello, {}!</h1>
        </body>
        </html>
        "#,
        escaped_input
    );

    Html::new(html) // Safe: user input is HTML-encoded
}

References

@paldepind paldepind marked this pull request as ready for review November 25, 2025 08:20
@paldepind paldepind requested a review from a team as a code owner November 25, 2025 08:20
Copilot AI review requested due to automatic review settings November 25, 2025 08:20
Copilot finished reviewing on behalf of paldepind November 25, 2025 08:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new security query rust/xss to detect cross-site scripting (XSS) vulnerabilities in Rust web applications. The implementation includes comprehensive test coverage across multiple Rust web frameworks (actix-web, warp, and axum) and follows the established patterns for security queries in the codebase.

  • New XSS detection query with taint tracking configuration
  • Framework support for actix-web and warp with sink models for HTML injection
  • Test cases demonstrating vulnerable and safe patterns across multiple frameworks

Reviewed changes

Copilot reviewed 23 out of 27 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
rust/ql/src/queries/security/CWE-079/XSS.ql Main query implementation using taint tracking to detect XSS vulnerabilities
rust/ql/src/queries/security/CWE-079/XSS.qhelp Documentation explaining the vulnerability, recommendations, and examples
rust/ql/src/queries/security/CWE-079/XSSBad.rs Example demonstrating vulnerable code pattern
rust/ql/src/queries/security/CWE-079/XSSGood.rs Example demonstrating safe code pattern with HTML escaping
rust/ql/src/change-notes/2025-11-24-xss-query.md Release notes for the new query
rust/ql/lib/codeql/rust/security/XssExtensions.qll Core library defining sources, sinks, and barriers for XSS detection
rust/ql/lib/codeql/rust/frameworks/warp.model.yml Added HTML injection sink model for warp::reply::html
rust/ql/lib/codeql/rust/frameworks/actix-web.model.yml Added HTML injection sink model for actix_web::types::html::Html::new
rust/ql/test/query-tests/security/CWE-079/warp/* Test cases for warp framework including main.rs, expected results, and dependencies
rust/ql/test/query-tests/security/CWE-079/axum/* Test cases for axum framework with MISSING annotation for expected alert
rust/ql/test/query-tests/security/CWE-079/actix/* Test cases for actix-web framework with both vulnerable and safe handlers
rust/ql/test/query-tests/security/CWE-079/Cargo.lock Auto-generated consolidated dependency lock file for all test cases
rust/ql/integration-tests/query-suite/*.qls.expected Updated query suite expectations to include new XSS query

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

.map(|name: String| { // $ Source
// Vulnerable to XSS because it directly includes user input in the response
let body = format!("<h1>Hello, {name}!</h1>");
warp::reply::html(body) // $ Alert[rust/xss]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider tagging the source as well.

user_input
);

Html::new(html) // $ Alert[rust/xss]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider tagging the source as well.

@paldepind paldepind self-assigned this Nov 25, 2025
Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made a good number of comments, but make no mistake - this is great work on a query we really want. Will also need a DCA run + docs review at some stage before merging.


async fn greet_handler(Query(params): Query<GreetingParams>) -> Html<String> {
let html_content = format!("<p>Hello, {}!</p>", params.name);
Html(html_content) // $ MISSING: Alert[rust/xss]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the plan to add sink models for this one as part of the axum modelling task?

Also we model poem for some similar queries, should we model (and optionally test) that here as well? (or just create an issue to add this extension)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. From the stats on crates.rs it's the most popular web framework and it's also the one used in the example that motivated the XSS query. So the goal is that these tests should work once we model Axum.

Poem isn't really on my mind so I didn't add tests for it. We could create an issue. But if we don't plan to actually work on it then maybe it's not worth it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created an improvements issue for this query containing this idea - but I've not prioritized it for now. We can do that later if the query performs well enough we want to expand it.

@paldepind
Copy link
Contributor Author

Thanks for the reviews! I should have addressed the comments now :)


async fn greet_handler(Query(params): Query<GreetingParams>) -> Html<String> {
let html_content = format!("<p>Hello, {}!</p>", params.name);
Html(html_content) // $ MISSING: Alert[rust/xss]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created an improvements issue for this query containing this idea - but I've not prioritized it for now. We can do that later if the query performs well enough we want to expand it.

@geoffw0 geoffw0 added the ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. label Nov 25, 2025
@geoffw0
Copy link
Contributor

geoffw0 commented Nov 25, 2025

I've added the ready-for-doc-review tag so that the docs team will take a look.

@isaacmbrown
Copy link
Contributor

I've added this to the Docs review board, our normal turnaround time is around two days

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. Rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants