Problemas de validação e representação da entrada são causados por metacaracteres, codificações alternativas e representações numéricas. Confiar na entrada resulta em problemas de segurança. Os problemas incluem: “Buffer Overflows”, ataques de “Cross-Site Scripting”, “SQL Injection”, entre outros.
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.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.sanitizeValue
como false
permite que entradas não sanitizadas levem a vulnerabilidades, como Cross-Site Scripting.sanitizeValue
determina se o sanitizador de HTML deve ser executado ou não quando o valor é aplicado à marcação HTML. A entrada pode vir diretamente do usuário e, portanto, pode ser considerada não segura. A propriedade sanitizeValue
pode ser definida como false
por diversos motivos, como permitir caracteres de entrada adicionais. Entretanto isso pode permitir inadvertidamente que entradas não seguras do usuário sejam executadas no código. É mais seguro definir a propriedade sanitizeValue
como true
, que é o valor padrão.sanitizeValue
no RichTextEditor
do SAPUI5 como false
:
new RichTextEditor({
sanitizeValue: false,
value: input
}).placeAt("moreContent");
...
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.@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")
...
myModule.config(function($compileProvider){
$compileProvider.imgSrcSanitizationWhitelist(userInput);
});
/^(http(s)?|javascript):.*/
, o aplicativo permitirá o uso de JavaScript embutido dentro de URLs de origem de imagem, o que pode resultar em ataques de execução de scripts entre sites.ProcessWorkitemRequest.setAction()
.
void processRequest() {
String workItemId = ApexPages.currentPage().getParameters().get('Id');
String action = ApexPages.currentPage().getParameters().get('Action');
Approval.ProcessWorkitemRequest req = new Approval.ProcessWorkitemRequest();
req.setWorkitemId(workItemId);
req.setAction(action);
Approval.ProcessResult res = Approval.process(req);
...
}
var hash = window.location.hash;
var myStartSymbol = decodeURIComponent(hash.substring(1, hash.length));
myModule.config(function($interpolateProvider){
$interpolateProvider.startSymbol(myStartSymbol);
});
...
public String inputValue {
get { return inputValue; }
set { inputValue = value; }
}
...
String queryString = 'SELECT Id FROM Contact WHERE (IsDeleted = false AND Name like \'%' + inputValue + '%\')';
result = Database.query(queryString);
...
SELECT Id FROM Contact WHERE (IsDeleted = false AND Name like '%inputValue%')
inputValue
não contiver um caractere de aspas simples. Se um invasor inserir a string name') OR (Name like '%
para inputValue
, a consulta se tornará a seguinte:
SELECT Id FROM Contact WHERE (IsDeleted = false AND Name like '%name') OR (Name like '%%')
name') OR (Name like '%
faz com que a cláusula "where" use a condição LIKE '%%'
, o que forçará a consulta a processar a saída de todos os valores de ID possíveis, já que ela se torna logicamente equivalente à consulta muito mais simples:
SELECT Id FROM Contact WHERE ... OR (Name like '%%')
...
public String inputValue {
get { return inputValue; }
set { inputValue = value; }
}
...
String queryString = 'Name LIKE \'%' + inputValue + '%\'';
String searchString = 'Acme';
String searchQuery = 'FIND :searchString IN ALL FIELDS RETURNING Contact (Id WHERE ' + queryString + ')';
List<List<SObject>> results = Search.query(searchQuery);
...
String searchQuery = 'FIND :searchString IN ALL FIELDS RETURNING Contact (Id WHERE Name LIKE '%' + inputValue + '%')';
inputValue
não contiver um caractere de aspas simples. Se um invasor inserir a string 1%' OR Name LIKE '
para inputValue
, a consulta se tornará a seguinte:
String searchQuery = 'FIND :searchString IN ALL FIELDS RETURNING Contact (Id WHERE Name LIKE '%1%' OR Name LIKE '%%')';
OR Name like '%%'
faz com que a cláusula "where" use a condição LIKE '%%'
, o que forçará a consulta a processar a saída de todos os registros que contêm a frase "map", já que ela se torna logicamente equivalente à consulta muito mais simples:
FIND 'map*' IN ALL FIELDS RETURNING Contact (Id WHERE Name LIKE '%%')
String beans = getBeanDefinitionFromUser();
GenericApplicationContext ctx = new GenericApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
xmlReader.loadBeanDefinitions(new UrlResource(beans));
ctx.refresh();
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="true">
...
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>false</param-value>
</context-param>
...
</web-app>
...
v_account = request->get_form_field( 'account' ).
v_reference = request->get_form_field( 'ref_key' ).
CONCATENATE `user = '` sy-uname `'` INTO cl_where.
IF v_account IS NOT INITIAL.
CONCATENATE cl_where ` AND account = ` v_account INTO cl_where SEPARATED BY SPACE.
ENDIF.
IF v_reference IS NOT INITIAL.
CONCATENATE cl_where "AND ref_key = `" v_reference "`" INTO cl_where.
ENDIF.
SELECT *
FROM invoice_items
INTO CORRESPONDING FIELDS OF TABLE itab_items
WHERE (cl_where).
...
SELECT *
FROM invoice_items
INTO CORRESPONDING FIELDS OF TABLE itab_items
WHERE user = sy-uname
AND account = <account>
AND ref_key = <reference>.
"abc` OR MANDT NE `+"
para v_reference e a string '1000' para v_account, a consulta se tornará a seguinte:
SELECT *
FROM invoice_items
INTO CORRESPONDING FIELDS OF TABLE itab_items
WHERE user = sy-uname
AND account = 1000
AND ref_key = `abc` OR MANDT NE `+`.
OR MANDT NE `+`
faz com que a cláusula WHERE
sempre seja avaliada como "true", pois o campo "client" nunca pode ser igual ao literal +, e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM invoice_items
INTO CORRESPONDING FIELDS OF TABLE itab_items.
invoice_items
, independentemente do usuário especificado.
PARAMETERS: p_street TYPE string,
p_city TYPE string.
Data: v_sql TYPE string,
stmt TYPE REF TO CL_SQL_STATEMENT.
v_sql = "UPDATE EMP_TABLE SET ".
"Update employee address. Build the update statement with changed details
IF street NE p_street.
CONCATENATE v_sql "STREET = `" p_street "`".
ENDIF.
IF city NE p_city.
CONCATENATE v_sql "CITY = `" p_city "`".
ENDIF.
l_upd = stmt->execute_update( v_sql ).
"ABC` SALARY = `1000000"
para o parâmetro p_street, o aplicativo permitirá que o banco de dados seja atualizado com o salário revisado!
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var username:String = String(params["username"]);
var itemName:String = String(params["itemName"]);
var query:String = "SELECT * FROM items WHERE owner = " + username + " AND itemname = " + itemName;
stmt.sqlConnection = conn;
stmt.text = query;
stmt.execute();
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
owner
corresponde ao nome do usuário autenticado no momento.
...
string userName = ctx.getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";
sda = new SqlDataAdapter(query, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'); DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
Exemplo 2:Como alternativa, um resultado semelhante pode ser obtido com o SQLite usando o seguinte código:
...
ctx.getAuthUserName(&userName); {
CString query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ request.Lookup("item") + "'";
dbms.ExecuteSQL(query);
...
...
sprintf (sql, "SELECT * FROM items WHERE owner='%s' AND itemname='%s'", username, request.Lookup("item"));
printf("SQL to execute is: \n\t\t %s\n", sql);
rc = sqlite3_exec(db,sql, NULL,0, &err);
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'); DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
...
ACCEPT USER.
ACCEPT ITM.
MOVE "SELECT * FROM items WHERE owner = '" TO QUERY1.
MOVE "' AND itemname = '" TO QUERY2.
MOVE "'" TO QUERY3.
STRING
QUERY1, USER, QUERY2, ITM, QUERY3 DELIMITED BY SIZE
INTO QUERY
END-STRING.
EXEC SQL
EXECUTE IMMEDIATE :QUERY
END-EXEC.
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itm
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula WHERE seja sempre avaliada como verdadeira, portanto a consulta torna-se logicamente equivalente à seguinte consulta, muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
...
<cfquery name="matchingItems" datasource="cfsnippets">
SELECT * FROM items
WHERE owner='#Form.userName#'
AND itemId=#Form.ID#
</cfquery>
...
SELECT * FROM items
WHERE owner = <userName>
AND itemId = <ID>;
Form.ID
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para Form.ID
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemId = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário hacker
inserir a string "hacker'); DELETE FROM items; --
" para Form.ID
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'hacker'
AND itemId = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'hacker'
AND itemId = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
...
final server = await HttpServer.bind('localhost', 18081);
server.listen((request) async {
final headers = request.headers;
final userName = headers.value('userName');
final itemName = headers.value('itemName');
final query = "SELECT * FROM items WHERE owner = '"
+ userName! + "' AND itemname = '"
+ itemName! + "'";
db.query(query);
}
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a cadeia de caracteres "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a cadeia de caracteres "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas seguintes consultas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
...
rawQuery := request.URL.Query()
username := rawQuery.Get("userName")
itemName := rawQuery.Get("itemName")
query := "SELECT * FROM items WHERE owner = " + username + " AND itemname = " + itemName + ";"
db.Exec(query)
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a cadeia de caracteres "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a cadeia de caracteres "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas seguintes consultas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a cadeia de caracteres "name'; DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três seguintes instruções válidas serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
...
String userName = ctx.getAuthenticatedUserName();
String itemName = request.getParameter("itemName");
String query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ itemName + "'";
ResultSet rs = stmt.execute(query);
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
Example 1
à plataforma Android.
...
PasswordAuthentication pa = authenticator.getPasswordAuthentication();
String userName = pa.getUserName();
String itemName = this.getIntent().getExtras().getString("itemName");
String query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ itemName + "'";
SQLiteDatabase db = this.openOrCreateDatabase("DB", MODE_PRIVATE, null);
Cursor c = db.rawQuery(query, null);
...
...
var username = document.form.username.value;
var itemName = document.form.itemName.value;
var query = "SELECT * FROM items WHERE owner = " + username + " AND itemname = " + itemName + ";";
db.transaction(function (tx) {
tx.executeSql(query);
}
)
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
...
$userName = $_SESSION['userName'];
$itemName = $_POST['itemName'];
$query = "SELECT * FROM items WHERE owner = '$userName' AND itemname = '$itemName';";
$result = mysql_query($query);
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não tiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
procedure get_item (
itm_cv IN OUT ItmCurTyp,
usr in varchar2,
itm in varchar2)
is
open itm_cv for ' SELECT * FROM items WHERE ' ||
'owner = '''|| usr || '''' ||
' AND itemname = ''' || itm || '''';
end get_item;
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itm
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula WHERE seja sempre avaliada como verdadeira, portanto a consulta torna-se logicamente equivalente à seguinte consulta, muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
...
userName = req.field('userName')
itemName = req.field('itemName')
query = "SELECT * FROM items WHERE owner = ' " + userName +" ' AND itemname = ' " + itemName +"';"
cursor.execute(query)
result = cursor.fetchall()
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não tiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
...
userName = getAuthenticatedUserName()
itemName = params[:itemName]
sqlQuery = "SELECT * FROM items WHERE owner = '#{userName}' AND itemname = '#{itemName}'"
rs = conn.query(sqlQuery)
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.
...
id = params[:id]
itemName = Mysql.escape_string(params[:itemName])
sqlQuery = "SELECT * FROM items WHERE id = #{userName} AND itemname = '#{itemName}'"
rs = conn.query(sqlQuery)
...
SELECT * FROM items WHERE id=<id> AND itemname = <itemName>;
itemName
e aparentemente isso impediu a vulnerabilidade contra a SQL Injection. No entanto, como a Ruby não é uma linguagem de digitação estática, mesmo que nós esperemos que id
seja um número inteiro de algum tipo uma vez que ele é atribuído a partir da entrada do usuário, ele não será necessariamente um número. Se um invasor puder, em vez disso, alterar o valor de id
para 1 OR id!=1--
, uma vez que não há nenhuma verificação de que id
é de fato numérico, a consulta SQL agora se tornará:
SELECT * FROM items WHERE id=1 OR id!=1-- AND itemname = 'anyValue';
SELECT * FROM items WHERE id=1 OR id!=1;
id
for igual a 1 ou não, o que naturalmente, equivale a tudo nessa tabela.
def doSQLQuery(value:String) = Action.async { implicit request =>
val result: Future[Seq[User]] = db.run {
sql"select * from users where name = '#$value'".as[User]
}
...
}
SELECT * FROM users
WHERE name = <userName>
userName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para userName
, a consulta se tornará a seguinte:
SELECT * FROM users
WHERE name = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM users;
users
, independentemente do usuário especificado.owner
corresponde ao nome do usuário autenticado no momento.
...
let queryStatementString = "SELECT * FROM items WHERE owner='\(username)' AND itemname='\(item)'"
var queryStatement: OpaquePointer? = nil
if sqlite3_prepare_v2(db, queryStatementString, -1, &queryStatement, nil) == SQLITE_OK {
if sqlite3_step(queryStatement) == SQLITE_ROW {
...
}
}
...
SELECT * FROM items
WHERE owner = '<userName>'
AND itemname = '<itemName>'
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'); DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
...
username = Session("username")
itemName = Request.Form("itemName")
strSQL = "SELECT * FROM items WHERE owner = '"& userName &"' AND itemname = '" & itemName &"'"
objRecordSet.Open strSQL, strConnect, adOpenDynamic, adLockOptimistic, adCmdText
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.Example 1
. Se um invasor com o nome de usuário wiley
inserir a string "name'; DELETE FROM items; --
" para itemName
, a consulta se transformará nas duas consultas a seguir:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
--'
Example 1
. Se um invasor inserir a string "name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
", as três instruções válidas a seguir serão criadas:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
owner
corresponde ao nome do usuário autenticado no momento.
...
string userName = ctx.getAuthenticatedUserName();
string queryString = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";
SimpleQuery<Item> queryObject = new SimpleQuery(queryString);
Item[] items = (Item[])queryObject.Execute(query);
...
SELECT * FROM items
WHERE owner = <userName>
AND itemname = <itemName>;
itemName
não contiver um caractere de aspas simples. Se um invasor com o nome de usuário wiley
inserir a string "name' OR 'a'='a
" para itemName
, a consulta se tornará a seguinte:
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
OR 'a'='a'
faz com que a cláusula "where" sempre seja avaliada como "true" e, portanto, a consulta torna-se logicamente equivalente à seguinte consulta muito mais simples:
SELECT * FROM items;
items
, independentemente do proprietário especificado.