日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java安全编码指南之:输入注入injection

發布時間:2024/2/28 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java安全编码指南之:输入注入injection 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 簡介
  • SQL注入
  • java中的SQL注入
  • 使用PreparedStatement
  • XML中的SQL注入
  • XML注入的java代碼

簡介

注入問題是安全中一個非常常見的問題,今天我們來探討一下java中的SQL注入和XML注入的防范。

SQL注入

什么是SQL注入呢?

SQL注入的意思是,用戶輸入了某些參數,最終導致SQL的執行偏離了程序設計者的本意,從而導致越權或者其他類型的錯誤。

也就是說因為用戶輸入的原因,導致SQL的涵義發送了變化。

拿我們最常用的登錄的SQL語句來說,我們可能會寫下面的SQL語句:

select * from user where username='<username>' and password='<password>'

我們需要用戶傳入username和password。

怎么對這個SQL語句進行注入呢?

很簡單,當用戶的username輸入是下面的情況時:

somebody' or '1'='1

那么整個SQL語句將會變成:

select * from user where username='somebody' or '1'='1' and password='<password>'

如果somebody是一個有效的用戶,那么or后面的語言完全不會執行,最終導致不校驗密碼就返回了用戶的信息。

同樣的,惡意攻擊者可以給password輸入下面的內容可以得到同樣的結果:

' or '1'='1

整個SQL解析為:

select * from user where username='somebody' and password='' or '1'='1'

這條語句將會返回所有的用戶信息,這樣即使不知道確定存在的用戶名也可以通過SQL語句的判斷。

這就是SQL注入。

java中的SQL注入

java中最常用的就是通過JDBC來操作數據庫,我們使用JDBC創建好連接之后,就可以執行SQL語句了。

下面我們看一個java中使用JDBC SQL注入的例子。

先創建一個通用的JDBC連接:

public Connection getConnection() throws ClassNotFoundException, SQLException {Connection con = null;Class.forName("com.mysql.jdbc.Driver");System.out.println("數據庫驅動加載成功");con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mysql?characterEncoding=UTF-8", "root", "");System.out.println("數據庫連接成功");return con;}

然后再自己拼裝SQL語句然后調用:

public void jdbcWithInjection(String username,char[] password) throws SQLException, ClassNotFoundException {Connection connection = getConnection();if (connection == null) {// Handle error}try {String pwd = encodePassword(password);String sqlString = "SELECT * FROM user WHERE username = '"+ username +"' AND password = '" + pwd + "'";Statement stmt = connection.createStatement();ResultSet rs = stmt.executeQuery(sqlString);if (!rs.next()) {throw new SecurityException("User name or password incorrect");}} finally {try {connection.close();} catch (SQLException x) {}}}

上面的例子中,只有username會發生注入,password不會,因為我們使用了encodePassword方法對password進行了轉換:

public String encodePassword(char[] password){return Base64.getEncoder().encodeToString(new String(password).getBytes());}

使用PreparedStatement

為了防止SQL注入,我們一般推薦的是使用PreparedStatement,java.sql.PreparedStatement可對輸入參數進行轉義,從而防止SQL注入。

注意,一定要正確的使用PreparedStatement,如果是不正確的使用,同樣會造成SQL注入的結果。

下面看一個不正確使用的例子:

String sqlString = "SELECT * FROM user WHERE username = '"+ username +"' AND password = '" + pwd + "'";PreparedStatement stmt = connection.prepareStatement(sqlString);ResultSet rs = stmt.executeQuery();

上面的代碼中,我們還是自己進行了SQL的拼裝,雖然最后我們使用了preparedStatement,但是沒有達到效果。

正確使用的例子如下:

String sqlString ="select * from user where username=? and password=?";PreparedStatement stmt = connection.prepareStatement(sqlString);stmt.setString(1, username);stmt.setString(2, pwd);ResultSet rs = stmt.executeQuery();

我們需要將用戶輸入作為參數set到PreparedStatement中去,這樣才會進行轉義。

XML中的SQL注入

可擴展標記語言(XML)旨在幫助存儲,結構化和傳輸數據。 由于其平臺獨立性,靈活性和相對簡單性,XML已在許多應用程序中得到使用。 但是,由于XML的多功能性,它容易受到包括XML注入在內的各種攻擊的攻擊。

那么什么是XML注入呢?我們舉個例子:

<item><name>Iphone20</name><price>5000.0</price><quantity>1</quantity> </item>

上面的例子中,我們使用了XML定義了一個iphone20的價格和數量。一個iphone20 5000塊。

上面的XML中,如果quantity是用戶輸入的數據的話,那么用戶可以這樣輸入:

1</quantity><price>20.0</price><quantity>1

最后得出的XML文件如下:

<item><name>Iphone20</name><price>5000.0</price><quantity>1</quantity><price>20.0</price><quantity>1</quantity> </item>

一般來說,我們在解析XML的過程中,如果發現有重復的tag,那么后面的tag會覆蓋前面的tag。

結果就是1個iphone20現在的價格是20塊,非常劃算。

XML注入的java代碼

我們看下XML的注入在java代碼中是怎么實現的:

public String createXMLInjection(String quantity){String xmlString = "<item>\n<name>Iphone20</name>\n"+ "<price>5000.0</price>\n" + "<quantity>" + quantity+ "</quantity></item>";return xmlString;}

可以看到我們直接使用用戶輸入的quantity作為XML的拼接,這樣做很明顯是有問題的。

怎么解決呢?有兩種方法。

  • 第一種方法

第一種方法就是對用戶輸入的quantity進行校驗:

public String createXML(String quantity){int count = Integer.parseUnsignedInt(quantity);String xmlString = "<item>\n<name>Iphone20</name>\n"+ "<price>5000.0</price>\n" + "<quantity>" + count+ "</quantity></item>";return xmlString;}

上面代碼中,我們對quantity進行了Integer的轉換,從而避免了用戶的非法輸入。

  • 第二種方法

第二種方法是使用XML Schema,來對生成的XML進行格式校驗。

先看一下我們改怎么定義這個XML Schema:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="item"><xs:complexType><xs:sequence><xs:element name="name" type="xs:string"/><xs:element name="price" type="xs:decimal"/><xs:element name="quantity" type="xs:nonNegativeInteger"/></xs:sequence></xs:complexType> </xs:element> </xs:schema>

上面我們定義了一個XML element的序列sequence。如果用戶輸入了非定義格式的其他XML,就會報錯。

我們看下相對應的java代碼該怎么寫:

StreamSource ss = new StreamSource(new File("schema.xsd"));Schema schema = sf.newSchema(ss);SAXParserFactory spf = SAXParserFactory.newInstance();spf.setSchema(schema);SAXParser saxParser = spf.newSAXParser();XMLReader reader = saxParser.getXMLReader();reader.setContentHandler(defHandler);reader.parse(xmlStream);

上面我們列出了XML驗證的代碼,完整的代碼可以參考文末的代碼鏈接,這里就不一一貼出來了。

本文的代碼:

learn-java-base-9-to-20/tree/master/security

本文已收錄于 http://www.flydean.com/java-security-code-line-injection/

最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!

總結

以上是生活随笔為你收集整理的java安全编码指南之:输入注入injection的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。