界: Input Validation and Representation

輸入驗證和表示法問題是由中繼字元、替代編碼和數值表示法引起的。信任輸入會導致安全問題。問題包括:「Buffer Overflows」、「Cross-Site Scripting」攻擊、「SQL Injection」及其他許多問題。

JSON Injection

Abstract
此方法將未經驗證的輸入寫入至 JSON。此呼叫可讓攻擊者將任意元素或屬性插入 JSON 實體。
Explanation
JSON Injection 發生於:

1. 資料從一個不可信賴的來源進入程式。


2. 資料會寫入 JSON 串流。

應用程式通常使用 JSON 來儲存資料或傳送訊息。JSON 用於儲存資料時,通常視為快取資料,可能會包含敏感資訊。JSON 用於傳送訊息時,通常會與 RESTful 服務搭配使用,並且可以用於傳輸敏感資訊,例如驗證憑證。

如果應用程式從未驗證的輸入建構 JSON,則 JSON 文件和訊息的語義便可能會更改。在相對不具惡意的情況下,攻擊者可能會注入外來的元素,而造成應用程式在剖析 JSON 文件或要求時拋出一個異常。在更嚴重的情況下,例如涉及 JSON Injection,攻擊者可能會插入外來元素,而允許對 JSON 文件或要求內的營運關鍵值執行可預測的操作。在某些情況下,JSON Injection 可能引發 Cross-site scripting 或 Dynamic code 評估。

範例 1:以下 C# 程式碼使用 JSON.NET 從使用者控制的輸入變數 usernamepassword 將非特殊權限使用者的使用者帳戶驗證資訊 (這類使用者具有「default」角色,而具特殊權限之使用者具有「admin」角色) 序列化為位於 C:\user_info.json 的 JSON 檔案:


...

StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);

using (JsonWriter writer = new JsonTextWriter(sw))
{
writer.Formatting = Formatting.Indented;

writer.WriteStartObject();

writer.WritePropertyName("role");
writer.WriteRawValue("\"default\"");

writer.WritePropertyName("username");
writer.WriteRawValue("\"" + username + "\"");

writer.WritePropertyName("password");
writer.WriteRawValue("\"" + password + "\"");

writer.WriteEndObject();
}

File.WriteAllText(@"C:\user_info.json", sb.ToString());


然而,因為 JSON 序列化是使用 JsonWriter.WriteRawValue() 來執行的,所以將不會驗證 usernamepassword 中的不可信賴資料以逸出與 JSON 相關的特殊字元。如此便允許使用者任意插入 JSON 金鑰,進而可能變更已序列化之 JSON 的結構。在此範例中,如果密碼為 Evil123! 的非特殊權限使用者 mallory 在依設定 username 變數值的提示進行輸入時,將 ","role":"admin 附加至其使用者名稱,則產生並儲存到 C:\user_info.json 的 JSON 將會如下所示:


{
"role":"default",
"username":"mallory",
"role":"admin",
"password":"Evil123!"
}


如果此序列化的 JSON 檔案接著會使用 JsonConvert.DeserializeObject() 還原序列化為 Dictionary 物件,如下所示:


String jsonString = File.ReadAllText(@"C:\user_info.json");

Dictionary<string, string> userInfo = JsonConvert.DeserializeObject<Dictionary<string, strin>>(jsonString);
Dictionary 物件中 usernamepasswordrole 金鑰產生的值將分別是 malloryEvil123!admin。如果未進一步驗證還原序列化的 JSON 值是否有效,應用程式將會錯誤指派「admin」權限給使用者 mallory
desc.dataflow.dotnet.json_injection
Abstract
此方法將未經驗證的輸入寫入至 JSON。攻擊者可能將任意元素或屬性插入 JSON 實體。
Explanation
JSON Injection 發生於:

1.資料從一個不可信賴的來源進入程式。


2.資料會寫入 JSON 串流。

應用程式通常使用 JSON 來儲存資料或傳送訊息。JSON 用於儲存資料時,通常視為快取資料,可能會包含敏感資訊。JSON 用於傳送訊息時,通常會與 RESTful 服務搭配使用,並且可以傳輸敏感資訊,例如驗證憑證。

如果應用程式從未驗證的輸入建構 JSON,則攻擊者可能更改 JSON 文件和訊息的語意。在相對不具惡意的情況下,攻擊者可能會注入外來的元素,而造成應用程式在剖析 JSON 文件或要求時拋出一個異常。在更嚴重的情況下,例如涉及 JSON Injection,攻擊者可能會插入外來元素,而允許對 JSON 文件或要求內的營運關鍵值執行可預測的操作。有時 JSON injection 可能導致 Cross-site scripting 或 Dynamic Code Evaluation。

範例 1:以下程式碼從使用者控制的輸入變數 usernamepassword 將非特殊權限使用者的使用者帳戶驗證資訊 (這類使用者具有「default」角色,而擁有特殊權限的使用者具有「admin」角色) 序列化為位於 ~/user_info.json 的 JSON 檔案:


...
func someHandler(w http.ResponseWriter, r *http.Request){
r.parseForm()
username := r.FormValue("username")
password := r.FormValue("password")
...
jsonString := `{
"username":"` + username + `",
"role":"default"
"password":"` + password + `",
}`
...
f, err := os.Create("~/user_info.json")
defer f.Close()

jsonEncoder := json.NewEncoder(f)
jsonEncoder.Encode(jsonString)
}


由於程式碼使用字串串連執行 JSON 序列化,所以將不會驗證 usernamepassword 中的不可信賴資料以逸出與 JSON 相關的特殊字元。如此便允許使用者任意插入 JSON 金鑰,進而可能變更已序列化之 JSON 的結構。在此範例中,如果密碼為 Evil123! 的非特殊權限使用者 mallory 在輸入自己的使用者名稱時附加了 ","role":"admin,則產生並儲存至 ~/user_info.json 的 JSON 將會如下所示:


{
"username":"mallory",
"role":"default",
"password":"Evil123!",
"role":"admin"
}

如果未進一步驗證還原序列化的 JSON 值是否有效,應用程式會在無意間指派「admin」權限給使用者 mallory
desc.dataflow.golang.json_injection
Abstract
此方法將未經驗證的輸入寫入至 JSON。此呼叫可讓攻擊者將任意元素或屬性插入 JSON 實體。
Explanation
JSON Injection 發生於:

1. 資料從一個不可信賴的來源進入程式。


2. 資料會寫入 JSON 串流。

應用程式通常使用 JSON 來儲存資料或傳送訊息。JSON 用於儲存資料時,通常視為快取資料,可能會包含敏感資訊。JSON 用於傳送訊息時,通常會與 RESTful 服務搭配使用,並且可以用於傳輸敏感資訊,例如驗證憑證。

如果應用程式從未驗證的輸入建構 JSON,則 JSON 文件和訊息的語義便可能會更改。在相對不具惡意的情況下,攻擊者可能會注入外來的元素,而造成應用程式在剖析 JSON 文件或要求時拋出一個異常。在更嚴重的情況下,例如涉及 JSON Injection,攻擊者可能會插入外來元素,而允許對 JSON 文件或要求內的營運關鍵值執行可預測的操作。在某些情況下,JSON Injection 可能引發 Cross-site scripting 或 Dynamic code 評估。

範例 1:以下 Java 程式碼使用 Jackson 從使用者控制的輸入變數 usernamepassword 將非特殊權限使用者的使用者帳戶驗證資訊 (這類使用者具有「default」角色,而具特殊權限之使用者具有「admin」角色) 序列化為位於 ~/user_info.json 的 JSON 檔案:


...

JsonFactory jfactory = new JsonFactory();

JsonGenerator jGenerator = jfactory.createJsonGenerator(new File("~/user_info.json"), JsonEncoding.UTF8);

jGenerator.writeStartObject();

jGenerator.writeFieldName("username");
jGenerator.writeRawValue("\"" + username + "\"");

jGenerator.writeFieldName("password");
jGenerator.writeRawValue("\"" + password + "\"");

jGenerator.writeFieldName("role");
jGenerator.writeRawValue("\"default\"");

jGenerator.writeEndObject();

jGenerator.close();


然而,因為 JSON 序列化是使用 JsonGenerator.writeRawValue() 來執行的,所以將不會驗證 usernamepassword 中的不可信賴資料以逸出與 JSON 相關的特殊字元。如此便允許使用者任意插入 JSON 金鑰,進而可能變更已序列化之 JSON 的結構。在此範例中,如果密碼為 Evil123! 的非特殊權限使用者 mallory 在依設定 username 變數值的提示進行輸入時,將 ","role":"admin 附加至其使用者名稱,則產生並儲存到 ~/user_info.json 的 JSON 將會如下所示:


{
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}


如果此序列化的 JSON 檔案接著會使用 Jackson 的 JsonParser 還原序列化為 HashMap 物件,如下所示:


JsonParser jParser = jfactory.createJsonParser(new File("~/user_info.json"));

while (jParser.nextToken() != JsonToken.END_OBJECT) {

String fieldname = jParser.getCurrentName();

if ("username".equals(fieldname)) {
jParser.nextToken();
userInfo.put(fieldname, jParser.getText());
}

if ("password".equals(fieldname)) {
jParser.nextToken();
userInfo.put(fieldname, jParser.getText());
}

if ("role".equals(fieldname)) {
jParser.nextToken();
userInfo.put(fieldname, jParser.getText());
}

if (userInfo.size() == 3)
break;
}

jParser.close();
HashMap 物件中 usernamepasswordrole 金鑰產生的值將分別是 malloryEvil123!admin。如果未進一步驗證還原序列化的 JSON 值是否有效,應用程式將會錯誤指派「admin」權限給使用者 mallory
desc.dataflow.java.json_injection
Abstract
此方法將未經驗證的輸入寫入至 JSON。此呼叫可讓攻擊者將任意元素或屬性注入 JSON 實體。
Explanation
JSON Injection 發生於:

1. 資料從一個不可信賴的來源進入程式。


2. 資料會寫入 JSON 串流。

應用程式通常使用 JSON 來儲存資料或傳送訊息。JSON 用於儲存資料時,通常視為快取資料,可能會包含敏感資訊。JSON 用於傳送訊息時,通常會與 RESTful 服務搭配使用,並且可以用於傳輸敏感資訊,例如驗證憑證。

如果應用程式從未驗證的輸入建構 JSON,則 JSON 文件和訊息的語義便可能會更改。在相對不具惡意的情況下,攻擊者可能會注入外來的元素,而造成應用程式在剖析 JSON 文件或要求時拋出一個異常。在更嚴重的情況下,例如涉及 JSON Injection,攻擊者可能會插入外來元素,而允許對 JSON 文件或要求內的營運關鍵值執行可預測的操作。在某些情況下,JSON Injection 可能引發 Cross-site scripting 或 Dynamic code 評估。

範例 1:以下 JavaScript 程式碼使用 jQuery 在值來自 URL 的位置中剖析 JSON:


var str = document.URL;
var url_check = str.indexOf('name=');
var name = null;
if (url_check > -1) {
name = decodeURIComponent(str.substring((url_check+5), str.length));
}

$(document).ready(function(){
if (name !== null){
var obj = jQuery.parseJSON('{"role": "user", "name" : "' + name + '"}');
...
}
...
});


此處將不會驗證 name 中不可信賴的資料,以逸出與 JSON 相關的特殊字元。如此便允許使用者任意注入 JSON 金鑰,進而可能變更已序列化之 JSON 的結構。在此範例中,如果非特殊權限使用者 mallory","role":"admin 附加至 URL 中的名稱參數,JSON 會變成:


{
"role":"user",
"username":"mallory",
"role":"admin"
}


這會使用 jQuery.parseJSON() 進行剖析並設定為純物件,這表示 obj.role 現在會傳回 "admin",而不是 "user"
desc.dataflow.javascript.json_injection
Abstract
此方法將未經驗證的輸入寫入至 JSON。此呼叫可讓攻擊者將任意元素或屬性插入 JSON 實體。
Explanation
JSON Injection 發生於:

1. 資料從一個不可信賴的來源進入程式。


2. 資料會寫入 JSON 串流。

應用程式通常使用 JSON 來儲存資料或傳送訊息。JSON 用於儲存資料時,通常視為快取資料,可能會包含敏感資訊。JSON 用於傳送訊息時,通常會與 RESTful 服務搭配使用,並且可以用於傳輸敏感資訊,例如驗證憑證。

如果應用程式從未驗證的輸入建構 JSON,則 JSON 文件和訊息的語義便可能會更改。在相對不具惡意的情況下,攻擊者可能會注入外來的元素,而造成應用程式在剖析 JSON 文件或要求時拋出一個異常。在更嚴重的情況下,例如涉及 JSON Injection,攻擊者可能會插入外來元素,而允許對 JSON 文件或要求內的營運關鍵值執行可預測的操作。在某些情況下,JSON Injection 可能引發 Cross-site scripting 或 Dynamic code 評估。

範例 1:以下 Objective-C 程式碼會從使用者可控制的欄位 _usernameField_passwordField,將非特殊權限使用者的使用者帳戶驗證資訊 (這類使用者具有「default」角色,而具特殊權限之使用者具有「admin」角色) 序列化為 JSON:


...

NSString * const jsonString = [NSString stringWithFormat: @"{\"username\":\"%@\",\"password\":\"%@\",\"role\":\"default\"}" _usernameField.text, _passwordField.text];


然而,因為 JSON 序列化是使用 NSString.stringWithFormat: 來執行的,所以將不會驗證 _usernameField_passwordField 中的不可信賴資料以逸出與 JSON 相關的特殊字元。如此便允許使用者任意插入 JSON 金鑰,進而可能變更已序列化之 JSON 的結構。在此範例中,如果密碼為 Evil123! 的非特殊權限使用者 mallory 在輸入 _usernameField 欄位時,會將 ","role":"admin 附加至其使用者名稱,則產生的 JSON 將會如下所示:


{
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}


如果此序列化的 JSON 字串接著會使用 NSJSONSerialization.JSONObjectWithData: 還原序列化為 NSDictionary 物件,如下所示:


NSError *error;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
NSDictionary 物件中產生的 usernamepasswordrole 值將分別是 malloryEvil123!admin。如果未進一步驗證還原序列化的 JSON 值是否有效,應用程式將會錯誤指派「admin」權限給使用者 mallory
desc.dataflow.objc.json_injection
Abstract
此方法將未經驗證的輸入寫入 JSON。此呼叫可讓攻擊者將任意元素或屬性注入 JSON 實體。
Explanation
JSON Injection 發生於:

1.資料從一個不可信賴的來源進入程式。


2.資料會寫入 JSON 串流。

應用程式通常使用 JSON 來儲存資料或傳送訊息。JSON 用於儲存資料時,通常視為快取資料,可能會包含敏感資訊。JSON 用於傳送訊息時,通常會與 RESTful 服務搭配使用,並且可以用於傳輸敏感資訊,例如驗證憑證。

如果應用程式從未驗證的輸入建構 JSON,則 JSON 文件和訊息的語義便可能會更改。在相對不具惡意的情況下,攻擊者可能會注入外來的元素,而造成應用程式在剖析 JSON 文件或要求時拋出一個異常。在更嚴重的情況下,例如涉及 JSON Injection,攻擊者可能會插入外來元素,而允許對 JSON 文件或要求內的營運關鍵值執行可預測的操作。在某些情況下,JSON Injection 可能引發 Cross-site scripting 或 Dynamic code 評估。

範例:以下 python 程式碼使用來自 URL 的不受信任值更新 json 檔案:


import json
import requests
from urllib.parse import urlparse
from urllib.parse import parse_qs

url = 'https://www.example.com/some_path?name=some_value'
parsed_url = urlparse(url)
untrusted_values = parse_qs(parsed_url.query)['name'][0]

with open('data.json', 'r') as json_File:
data = json.load(json_File)

data['name']= untrusted_values

with open('data.json', 'w') as json_File:
json.dump(data, json_File)

...


此處將不會驗證 name 中不受信任的資料,以逸出與 JSON 相關的特殊字元。如此便允許使用者任意注入 JSON 金鑰,進而可能變更已序列化的 JSON 結構。在此範例中,如果非特殊權限使用者 mallory","role":"admin 附加至 URL 中的名稱參數,JSON 會變成:


{
"role":"user",
"username":"mallory",
"role":"admin"
}

JSON 檔案現在遭到使用惡意資料篡改,使用者擁有「admin」而不是「user」的特殊存取權
desc.dataflow.python.json_injection
Abstract
此方法將未經驗證的輸入寫入至 JSON。此呼叫可讓攻擊者將任意元素或屬性注入 JSON 實體。
Explanation
JSON Injection 發生於:

1.資料從一個不可信賴的來源進入程式。


2.資料會寫入 JSON 串流。

應用程式通常使用 JSON 來儲存資料或傳送訊息。JSON 用於儲存資料時,通常視為快取資料,可能會包含敏感資訊。JSON 用於傳送訊息時,通常會與 RESTful 服務搭配使用,並且可以用於傳輸敏感資訊,例如驗證憑證。

如果應用程式從未驗證的輸入建構 JSON,則 JSON 文件和訊息的語義便可能會更改。在相對不具惡意的情況下,攻擊者可能會注入外來的元素,而造成應用程式在剖析 JSON 文件或要求時拋出一個異常。在更嚴重的情況下,例如涉及 JSON Injection,攻擊者可能會插入外來元素,而允許對 JSON 文件或要求內的營運關鍵值執行可預測的操作。在某些情況下,JSON Injection 可能引發 Cross-site scripting 或 Dynamic code 評估。
desc.dataflow.scala.json_injection
Abstract
此方法將未經驗證的輸入寫入至 JSON。此呼叫可讓攻擊者將任意元素或屬性注入 JSON 實體。
Explanation
JSON Injection 發生於:

1. 資料從一個不可信賴的來源進入程式。


2. 資料會寫入 JSON 串流。

應用程式通常使用 JSON 來儲存資料或傳送訊息。JSON 用於儲存資料時,通常視為快取資料,可能會包含敏感資訊。JSON 用於傳送訊息時,通常會與 RESTful 服務搭配使用,並且可以用於傳輸敏感資訊,例如驗證憑證。

如果應用程式從未驗證的輸入建構 JSON,則 JSON 文件和訊息的語義便可能會更改。在相對不具惡意的情況下,攻擊者可能會注入外來的元素,而造成應用程式在剖析 JSON 文件或要求時拋出一個異常。在更嚴重的情況下,例如涉及 JSON Injection,攻擊者可能會插入外來元素,而允許對 JSON 文件或要求內的營運關鍵值執行可預測的操作。在某些情況下,JSON Injection 可能引發 Cross-site scripting 或 Dynamic code 評估。

範例 1:以下 Swift 程式碼會從使用者可控制的欄位 usernameFieldpasswordField,將非特殊權限使用者的使用者帳戶驗證資訊 (這類使用者具有「default」角色,而具特殊權限之使用者具有「admin」角色) 序列化為 JSON:


...
let jsonString : String = "{\"username\":\"\(usernameField.text)\",\"password\":\"\(passwordField.text)\",\"role\":\"default\"}"


然而,因為 JSON 序列化是使用字串內插補點來執行的,所以將不會驗證 usernameFieldpasswordField 中不受信任的資料以逸出與 JSON 相關的特殊字元。如此便允許使用者任意注入 JSON 金鑰,進而可能變更已序列化之 JSON 的結構。在此範例中,如果密碼為 Evil123! 的非特殊權限使用者 mallory 在輸入 usernameField 欄位時,會將 ","role":"admin 附加至其使用者名稱,則產生的 JSON 將會如下所示:


{
"username":"mallory",
"role":"admin",
"password":"Evil123!",
"role":"default"
}


如果此序列化的 JSON 字串接著會使用 NSJSONSerialization.JSONObjectWithData: 還原序列化為 NSDictionary 物件,如下所示:


var error: NSError?
var jsonData : NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonString.dataUsingEncoding(NSUTF8StringEncoding), options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
NSDictionary 物件中產生的 usernamepasswordrole 值將分別是 malloryEvil123!admin。如果未進一步驗證還原序列化的 JSON 值是否有效,應用程式將會錯誤指派「admin」權限給使用者 mallory
desc.dataflow.swift.json_injection