...
tid = request->get_form_field( 'tid' ).
CALL TRANSACTION tid USING bdcdata MODE 'N'
MESSAGES INTO messtab.
...
APPHOME
and then loads a native library based on a relative path from the specified directory.
...
string lib = ConfigurationManager.AppSettings["APPHOME"];
Environment.ExitCode = AppDomain.CurrentDomain.ExecuteAssembly(lib);
...
APPHOME
to point to a different path containing a malicious version of LIBNAME
. Because the program does not validate the value read from the environment, if attacker can control the value of the system property APPHOME
, then they can fool the application into running malicious code and take control of the system.
...
RegQueryValueEx(hkey, "APPHOME",
0, 0, (BYTE*)home, &size);
char* lib=(char*)malloc(strlen(home)+strlen(INITLIB));
if (lib) {
strcpy(lib,home);
strcat(lib,INITCMD);
LoadLibrary(lib);
}
...
INITLIB
. Because the program does not validate the value read from the environment, if an attacker can control the value of APPHOME
, they can fool the application into running malicious code.liberty.dll
, which is intended to be found in a standard system directory.
LoadLibrary("liberty.dll");
liberty.dll
. If an attacker places a malicious library named liberty.dll
higher in the search order than the intended file and has a way to execute the program in their environment rather than the web server's environment, then the application will load the malicious library instead of the trusted one. Because this type of application runs with elevated privileges, the contents of the attacker's liberty.dll
is now be run with elevated privileges, potentially giving them complete control of the system.LoadLibrary()
when an absolute path is not specified. If the current directory is searched before system directories, as was the case up until the most recent versions of Windows, then this type of attack becomes trivial if the attacker may execute the program locally. The search order is operating system version dependent, and is controlled on newer operating systems by the value of this registry key:
HKLM\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
LoadLibrary()
behaves as follows:SafeDllSearchMode
is 1, the search order is as follows:PATH
environment variable.SafeDllSearchMode
is 0, the search order is as follows:PATH
environment variable.
...
ACCEPT PROGNAME.
EXEC CICS
LINK PROGRAM(PROGNAME)
COMMAREA(COMA)
LENGTH(LENA)
DATALENGTH(LENI)
SYSID('CONX')
END-EXEC.
...
APPHOME
to determine the directory in which it is installed and then loads a native library based on a relative path from the specified directory.
...
String home = System.getProperty("APPHOME");
String lib = home + LIBNAME;
java.lang.Runtime.getRuntime().load(lib);
...
APPHOME
to point to a different path containing a malicious version of LIBNAME
. Because the program does not validate the value read from the environment, if an attacker can control the value of the system property APPHOME
, then they can fool the application into running malicious code and take control of the system.System.loadLibrary()
to load code from a native library named library.dll
, which is normally found in a standard system directory.
...
System.loadLibrary("library.dll");
...
System.loadLibrary()
accepts a library name, not a path, for the library to be loaded. From the Java 1.4.2 API documentation this function behaves as follows [1]:library.dll
higher in the search order than file the application intends to load, then the application will load the malicious copy instead of the intended file. Because of the nature of the application, it runs with elevated privileges, which means the contents of the attacker's library.dll
will now be run with elevated privileges, possibly giving them complete control of the system.Express
to dynamically load a library file. Node.js
will then continue to search through its regular library load path for a file or directory containing this library[1].
var express = require('express');
var app = express();
app.get('/', function(req, res, next) {
res.render('tutorial/' + req.params.page);
});
Express
, the page passed to Response.render()
will load a library of the extension when previously unknown. This is usually fine for input such as "foo.pug", as this will mean loading the pug
library, a well known templating engine. However, if an attacker can control the page and thus the extension, then they can choose to load any library within the Node.js
module loading paths. Since the program does not validate the information received from the URL parameter, the attacker may fool the application into running malicious code and take control of the system.APPHOME
to determine the directory in which it is installed and then loads a native library based on a relative path from the specified directory.
...
$home = getenv("APPHOME");
$lib = $home + $LIBNAME;
dl($lib);
...
APPHOME
to point to a different path containing a malicious version of LIBNAME
. Because the program does not validate the value read from the environment, if an attacker can control the value of the system property APPHOME
, then they can fool the application into running malicious code and take control of the system.dl()
to load code from a library named sockets.dll
, which can be loaded from various places depending on your installation and configuration.
...
dl("sockets");
...
dl()
accepts a library name, not a path, for the library to be loaded.sockets.dll
higher in the search order than file the application intends to load, then the application will load the malicious copy instead of the intended file. Because of the nature of the application, it runs with elevated privileges, which means the contents of the attacker's sockets.dll
will now be run with elevated privileges, possibly giving them complete control of the system.Kernel.system()
to run an executable called program.exe
, which is normally found within a standard system directory.
...
system("program.exe")
...
Kernel.system()
executes something via a shell. If an attacker can manipulate environment variables RUBYSHELL
or COMSPEC
, they may be able to point to a malicious executable which will be called with the command given to Kernel.system()
. Because of the nature of the application, it runs with the privileges necessary to perform system operations, which means the attacker's program.exe
will now be run with these privileges, possibly giving them complete control of the system.Kernel.system()
. If an attacker can modify the $PATH
variable to point to a malicious binary called program.exe
and then execute the application in their environment, the malicious binary will be loaded instead of the one intended. Because of the nature of the application, it runs with the privileges necessary to perform system operations, which means the attacker's program.exe
will now be run with these privileges, possibly giving them complete control of the system.InvokerServlet
class can allow attackers to invoke any class on the server.InvokerServlet
class can be used to invoke any class available to the server's virtual machine. By guessing the fully qualified name of a class, an attacker may load not only Servlet classes, but also POJO classes or any other class available to the JVM.
@GetMapping("/prompt_injection")
String generation(String userInput1, ...) {
return this.clientBuilder.build().prompt()
.system(userInput1)
.user(...)
.call()
.content();
}
client = new Anthropic();
# Simulated attacker's input attempting to inject a malicious system prompt
attacker_input = ...
response = client.messages.create(
model = "claude-3-5-sonnet-20240620",
max_tokens=2048,
system = attacker_input,
messages = [
{"role": "user", "content": "Analyze this dataset for anomalies: ..."}
]
);
...
client = OpenAI()
# Simulated attacker's input attempting to inject a malicious system prompt
attacker_input = ...
completion = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": attacker_input},
{"role": "user", "content": "Compose a poem that explains the concept of recursion in programming."}
]
)
@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()
query that searches for invoices that match a user-specified product category. The user can also specify the column by which the results are sorted. Assume that the application has already properly authenticated and set the value of customerID
prior to this code segment.
...
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
and price
do not contain single-quote characters. If, however, an attacker provides the string "Fax Machines' or productCategory = \"
" for productCategory
, and the string "\" order by 'price
" for sortColumn
, then the query becomes the following:
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
, and allows the attacker to view invoice records matching 'Fax Machines'
for all customers.customerID
prior to this code segment.
...
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
. So the query behaves correctly only if productCategory
and sortColumn
do not contain single-quote characters. If an attacker provides the string "Fax Machines' or productCategory = \"
" for productCategory
, and the string "\" order by 'price
" for sortColumn
, then the query becomes:
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
and allows the attacker to view invoice records matching 'Fax Machines'
for all customers.
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
, the developer would expect that box.area
would be a random integer that happens to be a multiple of 10, due to width
being equal to 10. In reality however, this will always have a hardcoded value of 0. Static final fields declared with a compile-time constant are initialized first, and then each one is executed in order. This means that since height
is not a compile-time constant, it is declared after the declaration of box
, and therefore the constructor is called prior to the field height
being initialized.
...
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()
and format()
in java.text.Format
contain a design flaw that can cause one user to see another user's data.parse()
and format()
in java.text.Format
contains a race condition that can cause one user to see another user's data.
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
" to name
Jane
" to name
Jane, thanks for visiting!
"Jane, thanks for visiting!
"
public class ConnectionManager {
private static Connection conn = initDbConn();
...
}
null
before checking if the pointer is null
. Dereference-after-check errors occur when a program makes an explicit check for null
, but proceeds to dereference the pointer when it is known to be null
. Errors of this type are often the result of a typo or programmer oversight. A dereference-after-store error occurs when a program explicitly sets a pointer to null
and dereferences it later. This error is often the result of a programmer initializing a variable to null
when it is declared.foo
is null
and subsequently dereferences it erroneously. If foo
is null
when it is checked in the if
statement, then a null
dereference occurs, which causes a null-pointer exception.Example 2: In the following code, the programmer assumes that the variable
if (foo is null) {
foo.SetBar(val);
...
}
foo
is not null
and confirms this assumption by dereferencing the object. However, the programmer later contradicts the assumption by checking foo
against null
. If foo
can be null
when it is checked in the if
statement then it can also be null
when it is dereferenced and might cause a null-pointer exception. Either the dereference is unsafe or the subsequent check is unnecessary.Example 3: In the following code, the programmer explicitly sets the variable
foo.SetBar(val);
...
if (foo is not null) {
...
}
foo
to null
. Later, the programmer dereferences foo
before checking the object for a null
value.
Foo foo = null;
...
foo.SetBar(val);
...
}
null
before checking if the pointer is null
. Dereference-after-check errors occur when a program makes an explicit check for null
, but proceeds to dereference the pointer when it is known to be null
. Errors of this type are often the result of a typo or programmer oversight. A dereference-after-store error occurs when a program explicitly sets a pointer to null
and dereferences it later. This error is often the result of a programmer initializing a variable to null
when it is declared.ptr
is not NULL
. That assumption is made explicit when the programmer dereferences the pointer. This assumption is later contradicted when the programmer checks ptr
against NULL
. If ptr
can be NULL
when it is checked in the if
statement then it can also be NULL
when it dereferenced and may cause a segmentation fault.Example 2: In the following code, the programmer confirms that the variable
ptr->field = val;
...
if (ptr != NULL) {
...
}
ptr
is NULL
and subsequently dereferences it erroneously. If ptr
is NULL
when it is checked in the if
statement, then a null
dereference will occur, thereby causing a segmentation fault.Example 3: In the following code, the programmer forgets that the string
if (ptr == null) {
ptr->field = val;
...
}
'\0'
is actually 0 or NULL
, thereby dereferencing a null-pointer and causing a segmentation fault.Example 4: In the following code, the programmer explicitly sets the variable
if (ptr == '\0') {
*ptr = val;
...
}
ptr
to NULL
. Later, the programmer dereferences ptr
before checking the object for a null
value.
*ptr = NULL;
...
ptr->field = val;
...
}
null
, but proceeds to dereference the object when it is known to be null
. Errors of this type are often the result of a typo or programmer oversight.foo
is null
and subsequently dereferences it erroneously. If foo
is null
when it is checked in the if
statement, then a null
dereference will occur, thereby causing a null-pointer exception.
if (foo == null) {
foo.setBar(val);
...
}
Content-Disposition
header, allows the attacker to control the Content-Type
and/or Content-Disposition
headers in the HTTP response, or the target application includes a Content-Type
that is not rendered by default in the browser.ContentNegotiationManager
to dynamically produce different response formats, it meets the conditions necessary to make an RFD attack possible.ContentNegotiationManager
is configured to decide the response format based on the request path extension and to use Java Activation Framework (JAF) to find a Content-Type
that better matches the client's requested format. It also allows the client to specify the response content type through the media type that is sent in the request's Accept
header.Example 2: In the following example, the application is configured to allow the request's
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="true" />
<property name="useJaf" value="true" />
</bean>
Accept
header to determine the response's content type:
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="ignoreAcceptHeader" value="false" />
</bean>
ContentNegotiationManagerFactoryBean
property defaults in Spring 4.2.1 are:useJaf
: true
favorPathExtension
: true
ignoreAcceptHeader
: false
Example 1
allows an attacker to craft a malicious URL such as:ContentNegotiationManager
will use Java Activation Framework (if activation.jar is found in the classpath) to try to resolve the media type for the given file extension and set the response's ContentType
header accordingly. In this example, the file extension is "bat", resulting in a Content-Type
header of application/x-msdownload
(although the exact Content-Type
may vary depending on the server OS and JAF configuration). As a result, once the victim visits this malicious URL, his or her machine will automatically initiate the download of a ".bat" file containing attacker-controlled content. If this file is then executed, the victims machine will run any commands specified by the attacker's payload.
...
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
object and uses a port number read from an HTTP request to create a socket.
<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
, the controller method will generate a response such as:
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
tag to load the response from the JSONP endpoint, which will turn into the execution of the myCallbackFunction
function. An attacker could use a different callback name to navigate and interact with the DOM. For example opener.document.body.someElemnt.firstChild.nextElementSibling.submit
could be used to locate a form in the target page and submit it.
def myJSONPService(callback: String) = Action {
val json = getJSONToBeReturned()
Ok(Jsonp(callback, json))
}
GET /api/latest.json?callback=myCallbackFunction
, the controller method described in Example 1
will generate a response such as:
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
tag to load the response from the JSONP endpoint, which will turn into the execution of the myCallbackFunction
function. An attacker could use a different callback name to navigate and interact with the DOM. For example opener.document.body.someElemnt.firstChild.nextElementSibling.submit
could be used to locate a form in the target page and submit it.
...
lv_uri = request->get_form_field( 'uri' ).
CALL METHOD cl_http_utility=>set_request_uri
EXPORTING
request = lo_request
uri = lv_uri.
...
http
or https
such as:
...
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
or https
such as:
string url = Request.Form["url"];
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
http
or https
like:
char *url = maliciousInput();
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url);
CURLcode res = curl_easy_perform(curl);
http
or https
such as:
...
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
or https
such as:
url := request.Form.Get("url")
res, err =: http.Get(url)
...
http
or https
like:
String url = request.getParameter("url");
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response1 = httpclient.execute(httpGet);
http
or https
like:
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
or https
like:
val url: String = request.getParameter("url")
val httpclient: CloseableHttpClient = HttpClients.createDefault()
val httpGet = HttpGet(url)
val response1: CloseableHttpResponse = httpclient.execute(httpGet)
http
or https
like:
$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
or https
like:
url = request.GET['url']
handle = urllib.urlopen(url)
http
or https
like:
url = req['url']
Net::HTTP.get(url)
http
or https
like:
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
or https
like:Example 2: A few examples of how an attacker that has control over the
POST /checkDetails HTTP/1.1
url=https://example.com/product/1
url
parameter can tamper the request in Example 1
.
POST /checkDetails HTTP/1.1
url=https://localhost.com/admin
POST /checkDetails HTTP/1.1
url=file:///etc/passwd
http
or https
like:
// 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
uses Velocity
as the template engine. For that engine, an attacker could submit the following template to run arbitrary commands on the server:
$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
uses Underscore.js
as the template engine within a Node.js
application. For that engine, an attacker could submit the following template to run arbitrary commands on the server:
<% cp = process.mainModule.require('child_process');cp.exec(<COMMAND>); %>
Jinja2
template engine.
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
uses Jinja2
as the template engine. For that engine, an attacker could submit the following template to read arbitrary files from the server:Example 2: The following example shows how a template is retrieved from an HTTP request and rendered using the
template={{''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()}}
Django
template engine.
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
uses Django
as the template engine. For that engine, an attacker will not be able to execute arbitrary commands, but they will be able to access all the objects in the template context. In this example, a secret token is available in the context and could be leaked by the attacker.
<http auto-config="true">
...
<session-management session-fixation-protection="none"/>
</http>
Example 1
, the attacker does this through an obvious direct method that does not suitably scale for attacks involving less well-known web sites. However, do not be lulled into complacency; attackers have many tools in their belts that help bypass the limitations of this attack vector. The most common technique attackers use involves taking advantage of cross-site scripting or HTTP response splitting vulnerabilities in the target site [1]. By tricking the victim into submitting a malicious request to a vulnerable application that reflects JavaScript or other code back to the victim's browser, an attacker can create a cookie that causes the victim to reuse a session identifier controlled by the attacker.bank.example.com
and recipes.example.com
, a vulnerability in one application can enable an attacker to set a cookie with a fixed session identifier that is used in all interactions with any application on the domain example.com
[2].use_strict_mode
attribute for session cookies.
ini_set("session.use_strict_mode", "0");