Conversation
|
QHelp previews: csharp/ql/src/Security Features/CWE-451/MissingXFrameOptions.qhelpMissing clickjacking protectionWeb sites that do not restrict framing using the RecommendationSet the For ASP.NET Framework applications, the header may be specified either in the For ASP.NET Core applications, set the header on ExampleThe following example shows how to specify the This next example shows how to specify the protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("X-Frame-Options", "DENY");
}The following ASP.NET Core example uses an enforced Content Security Policy to disallow framing: void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
context.Response.Headers["Content-Security-Policy"] = "frame-ancestors 'none'";
await next();
});
}References
|
michaelnebel
left a comment
There was a problem hiding this comment.
Thank you very much for doing this! It would be great, if we can eliminate some false positives!
I have added some initial comments.
Starting our internal DCA testing of the query as well.
There was a problem hiding this comment.
🟡 Changes recommended
The CSP matcher accepts empty frame-ancestors directives that browsers do not enforce.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Extends the C# missing clickjacking protection query to recognize ASP.NET Core response headers and enforced CSP frame-ancestors directives.
Changes:
- Adds reusable header-write and CSP recognition predicates.
- Updates query documentation and metadata.
- Expands ASP.NET Core and Web.config regression coverage.
File summaries
| File | Description |
|---|---|
WebConfigAddedHeaderInLocation/MissingXFrameOptions.qlref |
Uses direct query expectations. |
WebConfigAddedHeader/Web.config |
Tests case-insensitive X-Frame-Options. |
WebConfigAddedHeader/PrefixedCsp.Web.config |
Tests unsupported prefixed CSP. |
WebConfigAddedHeader/MissingXFrameOptions.qlref |
Uses direct query expectations. |
WebConfigAddedHeader/MissingXFrameOptions.expected |
Records negative CSP cases. |
WebConfigAddedHeader/CspSubstring.Web.config |
Tests directive substring rejection. |
WebConfigAddedHeader/Csp.Web.config |
Tests valid case-insensitive CSP. |
NoHeader/MissingXFrameOptions.expected |
Updates the alert message. |
HeaderWrites/Web.config |
Provides an unprotected test configuration. |
HeaderWrites/options |
Loads ASP.NET Core stubs. |
HeaderWrites/MissingXFrameOptions.qlref |
Runs the production query. |
HeaderWrites/MissingXFrameOptions.expected |
Expects production-query suppression. |
HeaderWrites/HeaderWrites.qlref |
Configures inline-expectation testing. |
HeaderWrites/HeaderWrites.ql |
Exposes recognized header writes. |
HeaderWrites/HeaderWrites.expected |
Records recognized write expressions. |
HeaderWrites/HeaderWrites.cs |
Tests supported and ignored header writes. |
CodeAddedHeader/MissingXFrameOptions.qlref |
Uses direct query expectations. |
MissingXFrameOptionsLib.qll |
Implements header and CSP recognition. |
MissingXFrameOptionsAspNetCore.cs |
Adds an ASP.NET Core help example. |
MissingXFrameOptions.ql |
Integrates broader clickjacking protection detection. |
MissingXFrameOptions.qhelp |
Documents CSP and ASP.NET Core usage. |
2026-09-10-missing-x-frame-options.md |
Adds the analysis change note. |
Review details
- Files reviewed: 21/22 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
3ed8a8f to
66d4840
Compare
There was a problem hiding this comment.
Thank you!
A couple of notes.
- It would be great, if we could re-use some of the properties and put some of the code in other libraries. Furthermore, if we consider pushing the local dataflow to the top level predicate, it might be easier to re-factor in the future to use general data flow. I have opened a PR with a suggestion for a minor re-factor. Could you cherry-pick the last commit of this PR? (I will also run some tests on the PR).
- I am bit concerned about the quality of the query in general (this is not at all related to your work, but just an observation in case someone reads the history later).
- The notion of "global" enablement in code doesn't take into account whether the code is ever executed.
- Furthermore, if there is just a single location that indicates setting of
x-frame-options, then we don't report anything for the entire repository. It should be considered, if the query should be made compilation aware (not in scope for this PR).
- Is there a specific (public) repository that encouraged you to make this improvement (where you expect some FPs to be removed)?
Makes sense, I cherry-picked it. I agree with the quality issue. I'm new to CodeQL and wasn't sure what the philosophy/design standards for false positives vs false negatives are, so I just followed the pattern of the existing query and focused on false positives. No, there's not a specific public repository, but I was seeing many of these false positives in some of my company's private repositories - about 1 of these per microservice. It's a large company with a "no external contributions allowed" policy so I'm only able to publicly contribute to this in my personal time. |
Summary
The
cs/web/missing-x-frame-optionsquery was primarily modeled around legacy ASP.NET Framework applications hosted by IIS. As a result, it could report false positives for ASP.NET Core applications that correctly configure clickjacking-related response headers in code.This change:
X-Frame-Optionswritten through ASP.NET CoreHttpResponse.HeadersContent-Security-Policyheaders containing aframe-ancestorsdirectiveAppend,Add, andTryAddLegacy ASP.NET Framework and
Web.confighandling remains supported.Testing
Web.configtests for CSPframe-ancestorshandling.