輸入驗證和表示法問題是由中繼字元、替代編碼和數值表示法引起的。信任輸入會導致安全問題。問題包括:「Buffer Overflows」、「Cross-Site Scripting」攻擊、「SQL Injection」及其他許多問題。
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
NSString *regex = @"^(e+)+$";
NSPredicate *pred = [NSPRedicate predicateWithFormat:@"SELF MATCHES %@", regex];
if ([pred evaluateWithObject:mystring]) {
//do something
}
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
let regex : String = "^(e+)+$"
let pred : NSPredicate = NSPRedicate(format:"SELF MATCHES \(regex)")
if (pred.evaluateWithObject(mystring)) {
//do something
}
Example 1
而言,如果攻擊者提供了組合字串「eeeeZ」,則 regex 必須通過 16 種內部評估以識別該組合。如果攻擊者提供的組合字串有 16 個「e」(「eeeeeeeeeeeeeeeeZ」),那麼 regex 解析器就必須進行 65536 (2^16) 組評估。攻擊者可能輕易地藉由提高連續符合字元數來耗用計算資源。目前沒有已知的規則運算式實作對此弱點免疫。所有平台和語言都會受到此類攻擊。routes.Ignore
方法整合萬用字元路由模式而產生的。此方法允許透過外部輸入來定義路由行為。具體來說,使用萬用字元 (例如 {*allaspx}
) 為攻擊者提供了操縱路由動作的立足點。當控制這些萬用字元模式的輸入沒有經過徹底驗證或清理時,就會出現核心問題。
Marker child = MarkerManager.getMarker("child");
Marker parent = MarkerManager.getMarker("parent");
child.addParents(MarkerManager.getMarker(userInput));
parent.addParents(MarkerManager.getMarker(userInput2));
String toInfinity = child.toString();
child
和 parent
的父標記設定為使用者定義的標記。如果使用者輸入 child
的父項作為 parent
,並將 parent
的父項作為 child
,就會在 Marker 資料結構中建立循環連結。在包含循環連結的資料結構上執行遞迴 toString
方法時,程式會擲回堆疊溢位異常並當機。如此會透過 Stack Exhaustion 導致 Denial of Service。StringBuilder
或 StringBuffer
執行個體,可能會導致 JVM 過度消耗堆積記憶體空間。StringBuilder
或 StringBuffer
執行個體,可能會導致應用程式在調整基礎陣列大小以適合使用者資料時消耗大量的堆積記憶體。將資料附加至 StringBuilder
或 StringBuffer
執行個體時,執行個體會判斷支援字元陣列是否有足夠空間來儲存資料。如果資料不適合,則 StringBuilder
或 StringBuffer
執行個體會建立新陣列並使其陣列大小為先前的至少兩倍,同時,舊陣列將在記憶體回收之前保留在堆積中。攻擊者可使用此實作詳細資料執行 Denial of Service (DoS) 攻擊。StringBuilder
執行個體。
...
StringBuilder sb = new StringBuilder();
final String lineSeparator = System.lineSeparator();
String[] labels = request.getParameterValues("label");
for (String label : labels) {
sb.append(label).append(lineSeparator);
}
...
StringBuilder
或 StringBuffer
執行個體,可能會導致 JVM 過度消耗堆積記憶體空間。StringBuilder
或 StringBuffer
執行個體,可能會導致應用程式在調整基礎陣列大小以適合使用者資料時消耗大量的堆積記憶體。將資料附加至 StringBuilder
或 StringBuffer
執行個體時,執行個體會判斷支援字元陣列是否有足夠空間來儲存資料。如果資料不適合,則 StringBuilder
或 StringBuffer
執行個體會建立新陣列並使其陣列大小為先前的至少兩倍,同時,舊陣列將在記憶體回收之前保留在堆積中。攻擊者可使用此實作詳細資料執行 Denial of Service (DoS) 攻擊。StringBuilder
執行個體。
...
val sb = StringBuilder()
val labels = request.getParameterValues("label")
for (label in labels) {
sb.appendln(label)
}
...
...
user_ops = request->get_form_field( 'operation' ).
CONCATENATE: 'PROGRAM zsample.| FORM calculation. |' INTO code_string,
calculator_code_begin user_ops calculator_code_end INTO code_string,
'ENDFORM.|' INTO code_string.
SPLIT code_string AT '|' INTO TABLE code_table.
GENERATE SUBROUTINE POOL code_table NAME calc_prog.
PERFORM calculation IN PROGRAM calc_prog.
...
operation
參數是理想值時,程式會正常運作。不過,如果攻擊者指定同時為有效且惡意的語言作業,則會使用父系程序的完整權限來執行那些作業。此類攻擊在插入的程式碼存取系統資源或執行系統指令時更危險。例如,如果攻擊者指定「MOVE 'shutdown -h now' to cmd.CALL 'SYSTEM' ID 'COMMAND' FIELD cmd ID 'TAB' FIELD TABL[].」做為 operation
的值,則會在主機系統上執行系統關機指令。
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var userOps:String = String(params["operation"]);
result = ExternalInterface.call("eval", userOps);
...
operation
參數是良性的值時,例如「8 + 7 * 2」,程式會正常運作。在此案例中,會指定 result
變數的值為 22。不過,如果攻擊者指定同時為有效且惡意的語言作業,則會使用父系程序的完整權限來執行這些作業。當主要語言提供系統資源的存取權限或允許執行系統指令時,這類攻擊會更加危險。在 ActionScript 案例中,攻擊者可能使用此弱點執行 Cross-site scripting 攻擊。
...
public static object CEval(string sCSCode)
{
CodeDomProvider icc = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters cparam = new CompilerParameters();
cparam.ReferencedAssemblies.Add("system.dll");
cparam.CompilerOptions = "/t:library";
cparam.GenerateInMemory = true;
StringBuilder sb_code = new StringBuilder("");
sb_code.Append("using System;\n");
sb_code.Append("namespace Fortify_CodeEval{ \n");
sb_code.Append("public class FortifyCodeEval{ \n");
sb_code.Append("public object EvalCode(){\n");
sb_code.Append(sCSCode + "\n");
sb_code.Append("} \n");
sb_code.Append("} \n");
sb_code.Append("}\n");
CompilerResults cr = icc.CompileAssemblyFromSource(cparam, sb_code.ToString());
if (cr.Errors.Count > 0)
{
logger.WriteLine("ERROR: " + cr.Errors[0].ErrorText);
return null;
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("Fortify_CodeEval.FortifyCodeEval");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
return s;
}
...
sCSCode
參數是良性值 (例如「return 8 + 7 * 2」) 時,程式會正常運作,在此案例中,函數 CEval
的傳回值為 22。不過,如果攻擊者指定同時為有效且惡意的語言作業,則會使用父系程序的完整權限來執行那些作業。當主要語言提供系統資源的存取權限或允許執行系統指令時,這類攻擊會更加危險。例如,.Net 允許叫用 Windows API,如果攻擊者指定「return System.Diagnostics.Process.Start(\"shutdown\", \"/s /t 0\");」做為 operation
的值,則會在主機系統上執行關機指令。
...
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
userOps = request.getParameter("operation");
Object result = scriptEngine.eval(userOps);
...
operation
參數是良性值時,例如「8 + 7 * 2」,程式會正常運作。在此情況下,會指定 result
變數的值為 22。不過,如果攻擊者指定有效且惡意的語言作業,則會使用父系程序的完整權限來執行這些作業。當主要語言提供系統資源的存取權限或允許執行系統指令時,這類攻擊會更加危險。例如,JavaScript 允許叫用 Java 物件,如果攻擊者指定「java.lang.Runtime.getRuntime().exec("shutdown -h now")」作為 operation
的值,則會在主機系統上執行關機指令。
...
userOp = form.operation.value;
calcResult = eval(userOp);
...
operation
參數是良性的值時,例如「8 + 7 * 2」,程式會正常運作。在此案例中,會指定 calcResult
變數的值為 22。不過,如果攻擊者指定同時為有效且惡意的語言作業,則會使用父系程序的完整權限來執行這些作業。當主要語言提供系統資源的存取權限或允許執行系統指令時,這類攻擊會更加危險。在 JavaScript 案例中,攻擊者可能使用此弱點執行 Cross-site scripting 攻擊。
...
@property (strong, nonatomic) WKWebView *webView;
@property (strong, nonatomic) UITextField *inputTextField;
...
[_webView evaluateJavaScript:[NSString stringWithFormat:@"document.body.style.backgroundColor="%@";", _inputTextField.text] completionHandler:nil];
...
webView
內的 <body>
元素會具有藍色背景樣式。然而,如果攻擊者提供的惡意輸入仍然有效,便可能可以執行任意 JavaScript 程式碼。例如,由於 JavaScript 可以存取某些類型的私密資訊,如 Cookie,因此如果攻擊者指定 "white";document.body.innerHTML=document.cookie;"" 做為 UITextField 的輸入,則 Cookie 資訊會明顯寫入頁面。當基礎語言提供系統資源的存取權或允許執行系統指令時,這類攻擊會更加危險,因為在那些情況下,會使用父系程序的完整權限來執行插入的程式碼。
...
$userOps = $_GET['operation'];
$result = eval($userOps);
...
operation
參數是良性的值時,例如「8 + 7 * 2」,程式會正常運作。在此案例中,會指定 result
變數的值為 22。不過,如果攻擊者指定同時為有效且惡意的作業,則會使用父系程序的完整權限來執行這些作業。當主要語言提供系統資源的存取權限或允許執行系統指令時,這類攻擊會更加危險。例如,如果攻擊者指定「exec('shutdown -h now')」做為 operation
的值,則會在主機系統上執行系統關機指令。
...
userOps = request.GET['operation']
result = eval(userOps)
...
operation
參數是良性的值時,例如「8 + 7 * 2」,程式會正常運作。在此案例中,會指定 result
變數的值為 22。不過,如果攻擊者指定同時為有效且惡意的作業,則會使用父系程序的完整權限來執行這些作業。當主要語言提供系統資源的存取權限或允許執行系統指令時,這類攻擊會更加危險。例如,如果攻擊者指定「os.system('shutdown -h now')」做為 operation
的值,則會在主機系統上執行系統關機指令。
...
user_ops = req['operation']
result = eval(user_ops)
...
operation
參數是良性的值時,例如「8 + 7 * 2」,程式會正常運作。在此案例中,會指定 result
變數的值為 22。不過,如果攻擊者指定同時為有效且惡意的語言作業,則會使用父系程序的完整權限來執行這些作業。當主要語言提供系統資源的存取權限或允許執行系統指令時,這類攻擊會更加危險。如果使用 Ruby,則允許執行此作業,由於可透過使用分號 (;
) 區隔行來執行多個指令,因此還能夠在不中斷程式的情況下使用簡單插入來執行許多指令。 operation
"system(\"nc -l 4444 &\");8+7*2",則此作業會開啟連結埠 4444 以偵聽機器上的連線,且仍然會將值 22 回傳到 result
...
var webView : WKWebView
var inputTextField : UITextField
...
webView.evaluateJavaScript("document.body.style.backgroundColor="\(inputTextField.text)";" completionHandler:nil)
...
webView
內的 <body>
元素會具有藍色背景樣式。然而,如果攻擊者提供的惡意輸入仍然有效,便可能可以執行任意 JavaScript 程式碼。例如,由於 JavaScript 可以存取某些類型的私密資訊,如 Cookie,因此如果攻擊者指定 "white";document.body.innerHTML=document.cookie;"" 做為 UITextField 的輸入,則 Cookie 資訊會明顯寫入頁面。當基礎語言提供系統資源的存取權或允許執行系統指令時,這類攻擊會更加危險,因為在那些情況下,會使用父系程序的完整權限來執行插入的程式碼。
...
strUserOp = Request.Form('operation')
strResult = Eval(strUserOp)
...
operation
的範例。strResult
變數所回傳的值為 22。但是,如果使用者指定其他有效的語言作業,不僅會執行那些作業,還會使用父系程序的完整權限來執行。當基本語言提供系統資源的存取權限或允許執行系統指令時,執行任意的程式碼會變得更加危險。例如:如果攻擊者將 operation
指定為「Shell('C:\WINDOWS\SYSTEM32\TSSHUTDN.EXE 0 /DELAY:0 /POWERDOWN')」,則可能會在主機系統上執行關閉指令。
...
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
ScriptContext newContext = new SimpleScriptContext();
Bindings engineScope = newContext.getBindings(request.getParameter("userName"));
userOps = request.getParameter("operation");
Object result = scriptEngine.eval(userOps,newContext);
...
page_scope
參數是預期的使用者名稱,程式會正常運作。不過,如果攻擊者指定 GLOBAL_SCOPE
的值,操作將會存取由同一個 ScriptEngine
建立的所有引擎中的所有屬性。