JSON Injection解決方法


 

JSON Injection 解決:

加 JsonSanitizer.sanitize() 進行校驗(這個校驗貌似可以解決很多Json相關的Fortify Issue);

 

        <dependency>
            <groupId>com.mikesamuel</groupId>
            <artifactId>json-sanitizer</artifactId>
            <version>1.0</version>
        </dependency>

 

 

 

 

-----------------------------------------------------------------------------Issue 描述--------------------------------------------------------------------------------------------------

摘要

該方法將未經驗證的輸入寫入JSON。此調用可能允許攻擊者將任意元素或屬性注入JSON實體。

說明

JSON注入發生在以下情況下:
1.數據從不受信任的源進入程序。
2.數據被寫入JSON流。應用程序通常使用JSON來存儲數據或發送消息。當用於存儲數據時,JSON通常被視為緩存的數據,
並且可能包含敏感信息。當用於發送消息時,JSON通常與RESTful服務結合使用,並且可以用於傳輸敏感信息,例如身份驗
證憑據。如果應用程序從未經驗證的輸入構造JSON,則可以更改JSON文檔和消息的語義。在相對溫和的情況下,攻擊者可能
夠插入無關的元素,這些元素導致應用程序在解析JSON文檔或請求時引發異常。在更嚴重的情況下,例如涉及JSON注入的情
況,攻擊者可能能夠插入無關的元素,以允許對JSON文檔或請求中的業務關鍵值進行可預測的操縱。在某些情況下,JSON注入
可能導致跨站點腳本編寫或動態代碼評估。
示例1:
以下Java代碼使用Jackson來從用戶控制的輸入變量username和$中序列化非特權用戶(具有“默認”角色的用戶
,而不是具有“ admin”角色的特權用戶)的用戶帳戶身份驗證信息。 JSON文件的密碼位於 ~/user_info.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()執行的,因此不會驗證用戶名和密碼中不受信任的數
據來轉義與JSON相關的特殊字符。這允許用戶任意插入JSON密鑰,可能會更改序列化JSON的結構。在此示例中,如果非特權用戶
使用密碼Evil123!在設置用戶名變量值的提示符下輸入用戶名時,在用戶名后附加“,” 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對象中的用戶名,密碼和角色密鑰的結果值分別為Mallory,Evil123!和admin。如果不進一步驗證反序列化的JSON值是否有效,
該應用程序將錯誤地分配用戶Mallory的“ admin”特權。

建議:

將用戶提供的數據寫入JSON時,應遵循一些准則:
1.不要創建其名稱來自用戶輸入的JSON屬性。
2.確保使用安全的序列化功能執行對JSON的所有序列化,該函數在單引號或雙引號內定界不受信任的數據,並轉義任何特殊字符。
示例2:
以下Java代碼實現了與示例1中相同的功能,但是使用JsonGenerator.writeString()而不是JsonGenerator.writeRawValue()
來序列化數據,因此確保正確分隔和轉義了所有不受信任的數據:

...
JsonFactory jfactory = new JsonFactory();
JsonGenerator jGenerator = jfactory.createJsonGenerator(new File("~/ user_info.json"), JsonEncoding.UTF8);
jGenerator.writeStartObject();
jGenerator.writeFieldName("username");
jGenerator.writeString(username);
jGenerator.writeFieldName("password");
jGenerator.writeString(password);
jGenerator.writeFieldName("role"); 
jGenerator.writeString("default");
jGenerator.writeEndObject();
jGenerator.close();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM