@GetMapping("/prompt_injection_persistent")
String generation(String userInput1, ...) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users WHERE ...");
String userName = "";
if (rs != null) {
rs.next();
userName = rs.getString("userName");
}
return this.clientBuilder.build().prompt()
.system("Assist the user " + userName)
.user(userInput1)
.call()
.content();
}
client = new Anthropic();
# Simulated attacker's input attempting to inject a malicious system prompt
attacker_query = ...;
attacker_name = db.qyery('SELECT name FROM user_profiles WHERE ...');
response = client.messages.create(
model = "claude-3-5-sonnet-20240620",
max_tokens=2048,
system = "Provide assistance to the user " + attacker_name,
messages = [
{"role": "user", "content": attacker_query}
]
);
...
client = OpenAI()
# Simulated attacker's input attempting to inject a malicious system prompt
attacker_name = cursor.fetchone()['name']
attacker_query = ...
completion = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "Provide assistance to the user " + attacker_name},
{"role": "user", "content": attacker_query}
]
)
select()
SimpleDB que procura faturas correspondentes a uma categoria de produto especificada pelo usuário. O usuário também pode especificar a coluna pela qual os resultados são classificados. Suponha que o aplicativo já tenha sido devidamente autenticado e defina o valor de customerID
antes desse segmento de código.
...
String customerID = getAuthenticatedCustomerID(customerName, customerCredentials);
...
AmazonSimpleDBClient sdbc = new AmazonSimpleDBClient(appAWSCredentials);
String query = "select * from invoices where productCategory = '"
+ productCategory + "' and customerID = '"
+ customerID + "' order by '"
+ sortColumn + "' asc";
SelectResult sdbResult = sdbc.select(new SelectRequest(query));
...
select * from invoices
where productCategory = 'Fax Machines'
and customerID = '12345678'
order by 'price' asc
productCategory
e price
não contiverem caracteres de aspas simples. Porém, se um invasor fornecer a string "Fax Machines' or productCategory = \"
" para productCategory
e a string "\" order by 'price
" para sortColumn
, a consulta se tornará a seguinte:
select * from invoices
where productCategory = 'Fax Machines' or productCategory = "'
and customerID = '12345678'
order by '" order by 'price' asc
select * from invoices
where productCategory = 'Fax Machines'
or productCategory = "' and customerID = '12345678' order by '"
order by 'price' asc
customerID
e permite que ele veja registros de faturas correspondentes a 'Fax Machines'
para todos os clientes.customerID
antes desse segmento de código.
...
productCategory = this.getIntent().getExtras().getString("productCategory");
sortColumn = this.getIntent().getExtras().getString("sortColumn");
customerID = getAuthenticatedCustomerID(customerName, customerCredentials);
c = invoicesDB.query(Uri.parse(invoices), columns, "productCategory = '" + productCategory + "' and customerID = '" + customerID + "'", null, null, null, "'" + sortColumn + "'asc", null);
...
select * from invoices
where productCategory = 'Fax Machines'
and customerID = '12345678'
order by 'price' asc
productCategory
. Portanto, ela se comportará corretamente somente se productCategory
e sortColumn
não contiverem caracteres de aspas simples. Se um invasor fornecer a string "Fax Machines' or productCategory = \"
" para productCategory
e a string "\" order by 'price
" para sortColumn
, a consulta se tornará:
select * from invoices
where productCategory = 'Fax Machines' or productCategory = "'
and customerID = '12345678'
order by '" order by 'price' asc
select * from invoices
where productCategory = 'Fax Machines'
or productCategory = "' and customerID = '12345678' order by '"
order by 'price' asc
customerID
e permite que ele veja registros de faturas correspondentes a 'Fax Machines'
para todos os clientes.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "app.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
...
public class Box{
public int area;
public static final int width = 10;
public static final Box box = new Box();
public static final int height = (int) (Math.random() * 100);
public Box(){
area = width * height;
}
...
}
...
Example 1
, o desenvolvedor esperaria que box.area
fosse um número inteiro aleatório que, por acaso, é um múltiplo de 10, já que width
é igual a 10. Porém, na realidade, isso sempre terá um valor inserido em código fixo de 0. Campos estáticos finais declarados com uma constante em tempo de compilação são inicializados primeiros e depois cada um é executado em ordem. Isso significa que, como height
não é uma constante em tempo de compilação, ela é declarada após a declaração de box
e, portanto, o construtor é chamado antes da inicialização do campo height
.
...
class Foo{
public static final int f = Bar.b - 1;
...
}
...
class Bar{
public static final int b = Foo.f + 1;
...
}
This example is perhaps easier to identify, but would be dependent on which class is loaded first by the JVM. In this exampleFoo.f
could be either -1 or 0, andBar.b
could be either 0 or 1.
parse()
e format()
em java.text.Format
contêm uma falha de design que pode fazer com que um usuário veja os dados de outro usuário.parse()
e format()
em java.text.Format
contêm uma condição de corrida que pode fazer com que um usuário veja os dados de outro usuário.
public class Common {
private static SimpleDateFormat dateFormat;
...
public String format(Date date) {
return dateFormat.format(date);
}
...
final OtherClass dateFormatAccess=new OtherClass();
...
public void function_running_in_thread1(){
System.out.println("Time in thread 1 should be 12/31/69 4:00 PM, found: "+ dateFormatAccess.format(new Date(0)));
}
public void function_running_in_thread2(){
System.out.println("Time in thread 2 should be around 12/29/09 6:26 AM, found: "+ dateFormatAccess.format(new Date(System.currentTimeMillis())));
}
}
format()
.
public class GuestBook extends HttpServlet {
String name;
protected void doPost (HttpServletRequest req, HttpServletResponse res) {
name = req.getParameter("name");
...
out.println(name + ", thanks for visiting!");
}
}
Dick
" a name
Jane
" a name
Jane, thanks for visiting!
"Jane, thanks for visiting!
"
public class ConnectionManager {
private static Connection conn = initDbConn();
...
}
null
antes que seja verificado se ele é realmente null
. Erros de desreferência após a verificação ocorrem quando um programa faz uma verificação explícita em busca de valores null
, mas prossegue para desreferenciar o ponteiro quando se sabe que ele é null
. Erros desse tipo são frequentemente o resultado de um erro de digitação ou de uma desatenção do programador. Um erro de desreferência após o armazenamento ocorre quando um programa define explicitamente um ponteiro como null
e o desreferencia mais tarde. Esse erro é frequentemente o resultado de um programador inicializar uma variável como null
quando ela é declarada.foo
é null
e depois o desreferencia erroneamente. Se foo
for null
quando for verificado na instrução if
, ocorrerá um cancelamento de referência null
, o que causa uma exceção de ponteiro nulo.Exemplo 2: No código a seguir, o programador supõe que a variável
if (foo is null) {
foo.SetBar(val);
...
}
foo
não seja null
e confirma essa suposição desfazendo a referência ao objeto. No entanto, o programador mais tarde contradiz a suposição, verificando foo
com base em null
. Se a variável foo
puder ser null
quando for verificada na instrução if
, ela também poderá ser null
quando sua referência for desfeita, podendo causar uma exceção de ponteiro nulo. Ou o cancelamento de referência não é seguro, ou a verificação subsequente é desnecessária.Exemplo 3: No código a seguir, o programador define explicitamente a variável
foo.SetBar(val);
...
if (foo is not null) {
...
}
foo
como null
. Mais tarde, o programador desreferencia foo
antes de verificar o objeto em busca de um valor null
.
Foo foo = null;
...
foo.SetBar(val);
...
}
null
antes que seja verificado se ele é realmente null
. Erros de desreferência após a verificação ocorrem quando um programa faz uma verificação explícita em busca de valores null
, mas prossegue para desreferenciar o ponteiro quando se sabe que ele é null
. Erros desse tipo são frequentemente o resultado de um erro de digitação ou de uma desatenção do programador. Um erro de desreferência após o armazenamento ocorre quando um programa define explicitamente um ponteiro como null
e o desreferencia mais tarde. Esse erro é frequentemente o resultado de um programador inicializar uma variável como null
quando ela é declarada.ptr
não seja NULL
. Essa suposição se torna explícita quando o programador desreferencia o ponteiro. Mais tarde, essa suposição é contrariada quando o programador verifica ptr
contra NULL
. Se a variável ptr
puder ser NULL
quando for verificada na instrução if
, ela também poderá ser NULL
quando desreferenciada, podendo causar uma falha de segmentação.Exemplo 2: No código a seguir, o programador confirma que a variável
ptr->field = val;
...
if (ptr != NULL) {
...
}
ptr
é NULL
e depois a desreferencia erroneamente. Se a variável ptr
for NULL
quando for verificada na instrução if
, ocorrerá uma desreferência null
, causando assim uma falha de segmentação.Exemplo 3: No código a seguir, o programador se esquece de que a cadeia de caracteres
if (ptr == null) {
ptr->field = val;
...
}
'\0'
é, na verdade, 0 ou NULL
, desreferenciando assim um ponteiro nulo e provocando uma falha de segmentação.Exemplo 4: No código a seguir, o programador define explicitamente a variável
if (ptr == '\0') {
*ptr = val;
...
}
ptr
como NULL
. Mais tarde, o programador desreferencia ptr
antes de verificar o objeto em busca de um valor null
.
*ptr = NULL;
...
ptr->field = val;
...
}
null
, mas prossegue para cancelar a referência ao objeto quando se sabe que ele é null
. Erros desse tipo são frequentemente o resultado de um erro de digitação ou de uma desatenção do programador.foo
é null
e depois a desreferencia erroneamente. Se a variável foo
for null
quando for verificada na instrução if
, ocorrerá um cancelamento de referência null
, provocando assim uma exceção de ponteiro nulo.
if (foo == null) {
foo.setBar(val);
...
}
Content-Disposition
configurado incorretamente, o que permite que o invasor controle os cabeçalhos Content-Type
e/ou Content-Disposition
na resposta HTTP ou o aplicativo de destino inclui um Content-Type
que não é renderizado por padrão no navegador.ContentNegotiationManager
para produzir dinamicamente diferentes formatos de resposta, ele atende às condições necessárias para tornar possível um ataque RFD.ContentNegotiationManager
está configurado para decidir o formato de resposta com base na extensão do caminho do pedido e para usar o Java Activation Framework (JAF) para encontrar um Content-Type
que melhor corresponda ao formato solicitado pelo cliente. Ele também permite que o cliente especifique o tipo de conteúdo de resposta por meio do tipo de mídia que é enviado no cabeçalho Accept
da solicitação.Exemplo 2: No exemplo a seguir, o aplicativo é configurado para permitir o cabeçalho
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="true" />
<property name="useJaf" value="true" />
</bean>
Accept
da solicitação para determinar o tipo de conteúdo da resposta:
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="ignoreAcceptHeader" value="false" />
</bean>
ContentNegotiationManagerFactoryBean
no Spring 4.2.1 são:useJaf
: true
favorPathExtension
: true
ignoreAcceptHeader
: false
Example 1
permite que um invasor formule uma URL mal-intencionada, como:ContentNegotiationManager
usará o Java Activation Framework (se activation.jar for encontrado no classpath) para tentar resolver o tipo de mídia para a extensão de arquivo fornecida e definir o cabeçalho ContentType
da solicitação de forma adequada. Neste exemplo, a extensão do arquivo é "bat", resultando em um cabeçalho Content-Type
de application/x-msdownload
(embora o Content-Type
exato possa variar, dependendo do sistema operacional do servidor e da configuração JAF). Como resultado, assim que a vítima visitar esse URL mal-intencionado, sua máquina iniciará automaticamente o download de um arquivo ".bat" contendo conteúdo controlado pelo invasor. Se este arquivo for executado, a máquina das vítimas executará quaisquer comandos especificados pela carga útil do invasor.
...
host_name = request->get_form_field( 'host' ).
CALL FUNCTION 'FTP_CONNECT'
EXPORTING
USER = user
PASSWORD = password
HOST = host_name
RFC_DESTINATION = 'SAPFTP'
IMPORTING
HANDLE = mi_handle
EXCEPTIONS
NOT_CONNECTED = 1
OTHERS = 2.
...
int rPort = Int32.Parse(Request.Item("rPort"));
...
IPEndPoint endpoint = new IPEndPoint(address,rPort);
socket = new Socket(endpoint.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
socket.Connect(endpoint);
...
...
char* rPort = getenv("rPort");
...
serv_addr.sin_port = htons(atoi(rPort));
if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
...
...
ACCEPT QNAME.
EXEC CICS
READQ TD
QUEUE(QNAME)
INTO(DATA)
LENGTH(LDATA)
END-EXEC.
...
ServerSocket
Java e usa um número de porta lido de uma solicitação HTTP para criar um soquete.
<cfobject action="create" type="java" class="java.net.ServerSocket" name="myObj">
<cfset srvr = myObj.init(#url.port#)>
<cfset socket = srvr.accept()>
Passing user input to objects imported from other languages can be very dangerous.
final server = await HttpServer.bind('localhost', 18081);
server.listen((request) async {
final remotePort = headers.value('port');
final serverSocket = await ServerSocket.bind(host, remotePort as int);
final httpServer = HttpServer.listenOn(serverSocket);
});
...
func someHandler(w http.ResponseWriter, r *http.Request){
r.parseForm()
deviceName := r.FormValue("device")
...
syscall.BindToDevice(fd, deviceName)
}
String remotePort = request.getParameter("remotePort");
...
ServerSocket srvr = new ServerSocket(remotePort);
Socket skt = srvr.accept();
...
WebView
.
...
WebView webview = new WebView(this);
setContentView(webview);
String url = this.getIntent().getExtras().getString("url");
webview.loadUrl(url);
...
var socket = new WebSocket(document.URL.indexOf("url=")+20);
...
char* rHost = getenv("host");
...
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)rHost, 80, &readStream, &writeStream);
...
<?php
$host=$_GET['host'];
$dbconn = pg_connect("host=$host port=1234 dbname=ticketdb");
...
$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM pricelist WHERE name = $1');
$result = pg_execute($dbconn, "my_query", array("ticket"));
?>
...
filename := SUBSTR(OWA_UTIL.get_cgi_env('PATH_INFO'), 2);
WPG_DOCLOAD.download_file(filename);
...
host=request.GET['host']
dbconn = db.connect(host=host, port=1234, dbname=ticketdb)
c = dbconn.cursor()
...
result = c.execute('SELECT * FROM pricelist')
...
def controllerMethod = Action { request =>
val result = request.getQueryString("key").map { key =>
val user = db.getUser()
cache.set(key, user)
Ok("Cached Request")
}
Ok("Done")
}
...
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
var inputStream : NSInputStream?
var outputStream : NSOutputStream?
...
var readStream : Unmanaged<CFReadStream>?
var writeStream : Unmanaged<CFWriteStream>?
let rHost = getQueryStringParameter(url.absoluteString, "host")
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, rHost, 80, &readStream, &writeStream);
...
}
func getQueryStringParameter(url: String?, param: String) -> String? {
if let url = url, urlComponents = NSURLComponents(string: url), queryItems = (urlComponents.queryItems as? [NSURLQueryItem]) {
return queryItems.filter({ (item) in item.name == param }).first?.value!
}
return nil
}
...
...
Begin MSWinsockLib.Winsock tcpServer
...
Dim Response As Response
Dim Request As Request
Dim Session As Session
Dim Application As Application
Dim Server As Server
Dim Port As Variant
Set Response = objContext("Response")
Set Request = objContext("Request")
Set Session = objContext("Session")
Set Application = objContext("Application")
Set Server = objContext("Server")
Set Port = Request.Form("port")
...
tcpServer.LocalPort = Port
tcpServer.Accept
...
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
super("callback");
}
}
GET /api/latest.json?callback=myCallbackFunction
, o método do controlador gerará uma resposta do tipo:
HTTP/1.1 200 Ok
Content-Type: application/json; charset=utf-8
Date: Tue, 12 Dec 2017 16:16:04 GMT
Server: nginx/1.12.1
Content-Length: 225
Connection: Close
myCallbackFunction({<json>})
Script
para carregar a resposta do ponto de extremidade JSONP, que se transformará na execução da função myCallbackFunction
. Um invasor poderia usar um nome de retorno de chamada diferente para navegar e interagir com o DOM. Por exemplo, opener.document.body.someElemnt.firstChild.nextElementSibling.submit
poderia ser usado para localizar um formulário na página de destino e enviá-lo.
def myJSONPService(callback: String) = Action {
val json = getJSONToBeReturned()
Ok(Jsonp(callback, json))
}
GET /api/latest.json?callback=myCallbackFunction
, o método do controlador descrito em Example 1
gerará uma resposta do tipo:
HTTP/1.1 200 Ok
Content-Type: application/json; charset=utf-8
Date: Tue, 12 Dec 2017 16:16:04 GMT
Server: nginx/1.12.1
Content-Length: 225
Connection: Close
myCallbackFunction({<json>})
Script
para carregar a resposta do ponto de extremidade JSONP, que se transformará na execução da função myCallbackFunction
. Um invasor poderia usar um nome de retorno de chamada diferente para navegar e interagir com o DOM. Por exemplo, opener.document.body.someElemnt.firstChild.nextElementSibling.submit
poderia ser usado para localizar um formulário na página de destino e enviá-lo.
...
lv_uri = request->get_form_field( 'uri' ).
CALL METHOD cl_http_utility=>set_request_uri
EXPORTING
request = lo_request
uri = lv_uri.
...
http
ou https
, como:
...
PageReference ref = ApexPages.currentPage();
Map<String,String> params = ref.getParameters();
HttpRequest req = new HttpRequest();
req.setEndpoint(params.get('url'));
HTTPResponse res = new Http().send(req);
http
ou https
, como:
string url = Request.Form["url"];
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
http
ou https
, como:
char *url = maliciousInput();
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url);
CURLcode res = curl_easy_perform(curl);
http
ou https
, como:
...
final server = await HttpServer.bind('localhost', 18081);
server.listen((request) async {
final headers = request.headers;
final url = headers.value('url');
final client = IOClient();
final response = await client.get(Uri.parse(url!));
...
}
http
ou https
, como:
url := request.Form.Get("url")
res, err =: http.Get(url)
...
http
ou https
, como:
String url = request.getParameter("url");
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response1 = httpclient.execute(httpGet);
http
ou https
, como:
var http = require('http');
var url = require('url');
function listener(request, response){
var request_url = url.parse(request.url, true)['query']['url'];
http.request(request_url)
...
}
...
http.createServer(listener).listen(8080);
...
http
ou https
, como:
val url: String = request.getParameter("url")
val httpclient: CloseableHttpClient = HttpClients.createDefault()
val httpGet = HttpGet(url)
val response1: CloseableHttpResponse = httpclient.execute(httpGet)
http
ou https
, como:
$url = $_GET['url'];
$c = curl_init();
curl_setopt($c, CURLOPT_POST, 0);
curl_setopt($c,CURLOPT_URL,$url);
$response=curl_exec($c);
curl_close($c);
http
ou https
, como:
url = request.GET['url']
handle = urllib.urlopen(url)
http
ou https
, como:
url = req['url']
Net::HTTP.get(url)
http
ou https
, como:
def getFile(url: String) = Action { request =>
...
val url = request.body.asText.getOrElse("http://google.com")
ws.url(url).get().map { response =>
Ok(s"Request sent to $url")
}
...
}
http
ou https
, como:
// Set up the context data
VelocityContext context = new VelocityContext();
context.put( "name", user.name );
// Load the template
String template = getUserTemplateFromRequestBody(request);
RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices();
StringReader reader = new StringReader(template);
SimpleNode node = runtimeServices.parse(reader, "myTemplate");
template = new Template();
template.setRuntimeServices(runtimeServices);
template.setData(node);
template.initDocument();
// Render the template with the context data
StringWriter sw = new StringWriter();
template.merge( context, sw );
Example 1
usa Velocity
como o mecanismo de modelo. Nesse mecanismo, um invasor pode enviar o seguinte modelo para executar comandos arbitrários no servidor:
$name.getClass().forName("java.lang.Runtime").getRuntime().exec(<COMMAND>)
app.get('/', function(req, res){
var template = _.template(req.params['template']);
res.write("<html><body><h2>Hello World!</h2>" + template() + "</body></html>");
});
Example 1
usa Underscore.js
como o mecanismo de modelo em um aplicativo Node.js
. Nesse mecanismo, um invasor pode enviar o seguinte modelo para executar comandos arbitrários no servidor:
<% cp = process.mainModule.require('child_process');cp.exec(<COMMAND>); %>
Jinja2
.
from django.http import HttpResponse
from jinja2 import Template as Jinja2_Template
from jinja2 import Environment, DictLoader, escape
def process_request(request):
# Load the template
template = request.GET['template']
t = Jinja2_Template(template)
name = source(request.GET['name'])
# Render the template with the context data
html = t.render(name=escape(name))
return HttpResponse(html)
Example 1
usa Jinja2
como o mecanismo de modelo. Nesse mecanismo, um invasor pode enviar o seguinte modelo para ler arquivos arbitrário do servidor:Exemplo 2: O exemplo a seguir mostra como um modelo é recuperado de uma solicitação HTTP e renderizado usando o mecanismo de modelo
template={{''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()}}
Django
.
from django.http import HttpResponse
from django.template import Template, Context, Engine
def process_request(request):
# Load the template
template = source(request.GET['template'])
t = Template(template)
user = {"name": "John", "secret":getToken()}
ctx = Context(locals())
html = t.render(ctx)
return HttpResponse(html)
Example 2
usa Django
como o mecanismo de modelo. Nesse mecanismo, um invasor não conseguirá executar comandos arbitrários, mas poderá acessar todos os objetos no contexto do modelo. Neste exemplo, um token secreto está disponível no contexto e poderia ser vazado pelo invasor.
<http auto-config="true">
...
<session-management session-fixation-protection="none"/>
</http>
Example 1
, o invasor faz isso por meio de um método direto óbvio que não se adapta bem a ataques que envolvem sites menos conhecidos. No entanto, não se deixe convencer pela complacência; os invasores têm muitas ferramentas que ajudam a contornar as limitações desse vetor de ataque. A técnica mais comum usada pelos invasores consiste em tirar proveito de vulnerabilidades de cross-site scripting ou divisão de respostas HTTP no site de destino [1]. Enganando a vítima para induzi-la a enviar uma solicitação mal-intencionada a um aplicativo vulnerável que reflete JavaScript ou outro código de volta para o navegador da vítima, um invasor pode criar um cookie que faz com que a pessoa reutilize um identificador de sessão controlado por ele.bank.example.com
e recipes.example.com
, uma vulnerabilidade em um aplicativo poderá permitir que um invasor defina um cookie com um identificador de sessão fixo usado em todas as interações com qualquer aplicativo no domínio example.com
[2].use_strict_mode
para cookies de sessão.
ini_set("session.use_strict_mode", "0");
@SessionAttributes
significará que o Spring replica as alterações nos atributos de modelo no objeto de sessão. Se um invasor for capaz de armazenar valores arbitrários dentro de um atributo de modelo, essas alterações serão replicadas no objeto de sessão, onde podem ser confiáveis pelo aplicativo. Se o atributo de sessão for inicializado com dados confiáveis que o usuário não deve poder modificar, o invasor poderá realizar um ataque de Session Puzzling e abusar da lógica do aplicativo.
@Controller
@SessionAttributes("user")
public class HomeController {
...
@RequestMapping(value= "/auth", method=RequestMethod.POST)
public String authHandler(@RequestParam String username, @RequestParam String password, RedirectAttributes attributes, Model model) {
User user = userService.findByNamePassword(username, password);
if (user == null) {
// Handle error
...
} else {
// Handle success
attributes.addFlashAttribute("user", user);
return "redirect:home";
}
}
...
}
User
a partir da sessão, pois a classe é anotada com @SessionAttributes("user")
e a usa para verificar a questão de redefinição da senha.
@Controller
@SessionAttributes("user")
public class ResetPasswordController {
@RequestMapping(value = "/resetQuestion", method = RequestMethod.POST)
public String resetQuestionHandler(@RequestParam String answerReset, SessionStatus status, User user, Model model) {
if (!user.getAnswer().equals(answerReset)) {
// Handle error
...
} else {
// Handle success
...
}
}
}
user
da sessão na qual ela foi armazenada durante o processo de logon. No entanto, o Spring verificará a solicitação e tentará vincular seus dados na instância do modelo user
. Se a solicitação recebida contiver dados que podem ser vinculados à classe User
, o Spring combinará os dados recebidos no atributo de sessão do usuário. É possível abusar desse cenário, enviando uma resposta arbitrária no parâmetro de consulta answerReset
e também o mesmo valor para substituir o valor armazenado na sessão. Dessa forma, o invasor pode definir uma nova senha arbitrária para usuários aleatórios.
...
taintedConnectionStr = request->get_form_field( 'dbconn_name' ).
TRY.
DATA(con) = cl_sql_connection=>get_connection( `R/3*` && taintedConnectionStr ).
...
con->close( ).
CATCH cx_sql_exception INTO FINAL(exc).
...
ENDTRY.
...
sethostid(argv[1]);
...
sethostid()
com êxito, usuários sem privilégios podem ser capazes de invocar o programa. O código nesse exemplo permite que a entrada do usuário controle diretamente o valor de uma configuração do sistema. Se um invasor fornece um valor mal-intencionado para a ID de host, o invasor poderá identificar incorretamente a máquina afetada na rede ou causar outro comportamento indesejado.
...
ACCEPT OPT1.
ACCEPT OPT2
COMPUTE OPTS = OPT1 + OPT2.
CALL 'MQOPEN' USING HCONN, OBJECTDESC, OPTS, HOBJ, COMPOCODE REASON.
...
...
<cfset code = SetProfileString(IniPath,
Section, "timeout", Form.newTimeout)>
...
Form.newTimeout
é usado para especificar um tempo limite, um invasor pode ser capaz de preparar um ataque de negação de serviço (DoS) contra o aplicativo especificando um número suficientemente grande.
...
catalog := request.Form.Get("catalog")
path := request.Form.Get("path")
os.Setenv(catalog, path)
...
HttpServletRequest
e a define como o catálogo ativo para um banco de dados Connection
.
...
conn.setCatalog(request.getParamter("catalog"));
...
http.IncomingMessage
e a utiliza para definir sinalizadores adicionais de linha de comando V8.
var v8 = require('v8');
...
var flags = url.parse(request.url, true)['query']['flags'];
...
v8.setFlagsFromString(flags);
...
<?php
...
$table_name=$_GET['catalog'];
$retrieved_array = pg_copy_to($db_connection, $table_name);
...
?>
...
catalog = request.GET['catalog']
path = request.GET['path']
os.putenv(catalog, path)
...
Connection
.
def connect(catalog: String) = Action { request =>
...
conn.setCatalog(catalog)
...
}
...
sqlite3(SQLITE_CONFIG_LOG, user_controllable);
...
Request
e define-a como o catálogo ativo de um banco de dados Connection
.
...
Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
Dim rsTables As ADODB.Recordset
Dim Catalog As New ADOX.Catalog
Set Catalog.ActiveConnection = conn
Catalog.Create Request.Form("catalog")
...
String beans = getBeanDefinitionFromUser();
GenericApplicationContext ctx = new GenericApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
xmlReader.loadBeanDefinitions(new UrlResource(beans));
ctx.refresh();
ACTUATOR
podem acessá-los.
management.security.enabled=false
endpoints.health.sensitive=false
@Component
public class CustomEndpoint implements Endpoint<List<String>> {
public String getId() {
return "customEndpoint";
}
public boolean isEnabled() {
return true;
}
public boolean isSensitive() {
return false;
}
public List<String> invoke() {
// Custom logic to build the output
...
}
}