mirror of
https://github.com/github/codeql.git
synced 2026-06-12 08:21:09 +02:00
Promote user prompt injection query to stable security
Move UserPromptInjection out of experimental into stable JavaScript security locations. Set js/user-prompt-injection precision to low and remove experimental tagging. Move supporting dataflow libraries, qhelp/examples, and tests to stable paths and update references.
This commit is contained in:
@@ -20,7 +20,7 @@ context, or trigger unintended tool calls.</p>
|
||||
<ul>
|
||||
<li>Ensure that all data flowing into user-input is intended and necessary for the purpose of the AI system.</li>
|
||||
<li>Ensure the system prompt clearly describes the purpose, scope and boundaries of the AI system. Instruct the system to deny input that falls outside these boundaries.</li>
|
||||
<li>If creating a prompt out of multiple user-controlled values, assume that each of them can be malicious. Ensure the range of possible values is restricted and validated.
|
||||
<li>If creating a prompt out of multiple user-controlled values, assume that each of them can be malicious. Ensure the range of possible values is restricted and validated.
|
||||
For example, if a prompt includes a question and the intended language to respond in, validate that the language is one of the supported options.</li>
|
||||
<li>Consider using guardrails on the input like the OpenAI guardrails library to enforce constraints and prevent malicious content from being processed.</li>
|
||||
<li>Apply output filtering to detect and block responses that indicate prompt injection attempts.</li>
|
||||
@@ -5,15 +5,14 @@
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 5.0
|
||||
* @precision medium
|
||||
* @precision low
|
||||
* @id js/user-prompt-injection
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-1427
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import experimental.semmle.javascript.security.PromptInjection.UserPromptinjectionQuery
|
||||
import semmle.javascript.security.dataflow.UserPromptInjectionQuery
|
||||
import UserPromptInjectionFlow::PathGraph
|
||||
|
||||
from UserPromptInjectionFlow::PathNode source, UserPromptInjectionFlow::PathNode sink
|
||||
@@ -1,70 +0,0 @@
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* "user prompt injection"
|
||||
* vulnerabilities, as well as extension points for adding your own.
|
||||
*/
|
||||
|
||||
import javascript
|
||||
private import semmle.javascript.dataflow.DataFlow
|
||||
private import semmle.javascript.Concepts
|
||||
private import semmle.javascript.security.dataflow.RemoteFlowSources
|
||||
private import semmle.javascript.dataflow.internal.BarrierGuards
|
||||
private import semmle.javascript.frameworks.data.ModelsAsData
|
||||
private import semmle.javascript.frameworks.OpenAI
|
||||
private import semmle.javascript.frameworks.Anthropic
|
||||
private import semmle.javascript.frameworks.GoogleGenAI
|
||||
private import semmle.javascript.frameworks.OpenRouter
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* "user prompt injection"
|
||||
* vulnerabilities, as well as extension points for adding your own.
|
||||
*/
|
||||
module UserPromptInjection {
|
||||
/**
|
||||
* A data flow source for "user prompt injection" vulnerabilities.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A data flow sink for "user prompt injection" vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A sanitizer for "user prompt injection" vulnerabilities.
|
||||
*/
|
||||
abstract class Sanitizer extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* An active threat-model source, considered as a flow source.
|
||||
*/
|
||||
private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { }
|
||||
|
||||
/**
|
||||
* A prompt to an AI model, considered as a flow sink.
|
||||
*/
|
||||
class AIPromptAsSink extends Sink {
|
||||
AIPromptAsSink() { this = any(AIPrompt p).getAPrompt() }
|
||||
}
|
||||
|
||||
private class SinkFromModel extends Sink {
|
||||
SinkFromModel() { this = ModelOutput::getASinkNode("user-prompt-injection").asSink() }
|
||||
}
|
||||
|
||||
private class PromptContentSink extends Sink {
|
||||
PromptContentSink() {
|
||||
this = OpenAI::getUserPromptNode().asSink()
|
||||
or
|
||||
this = Anthropic::getUserPromptNode().asSink()
|
||||
or
|
||||
this = GoogleGenAI::getUserPromptNode().asSink()
|
||||
or
|
||||
this = AgentSdk::getUserPromptNode().asSink()
|
||||
or
|
||||
this = OpenRouter::getUserPromptNode().asSink()
|
||||
or
|
||||
this = OpenRouterAgent::getUserPromptNode().asSink()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Provides a taint-tracking configuration for detecting "prompt injection" vulnerabilities.
|
||||
*
|
||||
* Note, for performance reasons: only import this file if
|
||||
* `PromptInjection::Configuration` is needed, otherwise
|
||||
* `PromptInjectionCustomizations` should be imported instead.
|
||||
*/
|
||||
|
||||
private import javascript
|
||||
import semmle.javascript.dataflow.DataFlow
|
||||
import semmle.javascript.dataflow.TaintTracking
|
||||
import UserPromptInjectionCustomizations::UserPromptInjection
|
||||
|
||||
private module UserPromptInjectionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node instanceof Source }
|
||||
|
||||
predicate isSink(DataFlow::Node node) { node instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
/** Global taint-tracking for detecting "user prompt injection" vulnerabilities. */
|
||||
module UserPromptInjectionFlow = TaintTracking::Global<UserPromptInjectionConfig>;
|
||||
Reference in New Issue
Block a user