java 防止JS注入(使用ESAPI進行編碼)

今天在作報表導入的時候遇到測試在excel數據裏面填了一段js代碼,致使數據回顯到頁面的時候彈一個框出來,這個框我想你們都懂了,又剛好逢項目在作代碼安全掃描,
掃描工具使用的是Fortifyhtml

關於ESAPI的介紹可查看:
https://blog.csdn.net/qq_35623773/article/details/100126615java

安全工具推薦使用ESAPI.encoder().encodeForHTML來對html字符串進行編碼,那咱們就來開始嘗試吧。
1. 引入esapi依賴git

<!-- https://mvnrepository.com/artifact/org.owasp.esapi/esapi -->
<dependency>
    <groupId>org.owasp.esapi</groupId>
    <artifactId>esapi</artifactId>
    <version>2.2.0.0</version>
</dependency>
<!--   必須引入log4j依賴,否則初始化 esapi時會報錯    -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2. 引入esapi配置文件
配置文件可從github上獲取 https://github.com/ESAPI/esapi-java-legacy
找到對應版本的分支,以zip形式下載源碼到本地,解壓
找到如下倆個文件複製到項目的resource目錄下,具體配置可查看配置文件的註釋
在這裏插入圖片描述
這倆個文件在源碼中路徑: esapi-java-legacy-2.2.0.0\configuration\esapigithub

3. 編寫代碼api

若是咱們返回的字符串是一段html,但只解析js,能夠參考如下方式:安全

@GetMapping("/hi")
public String hi() {
    StringBuilder sb = new StringBuilder();
    sb.append("<div style=\"color:red;\">aaaaa</div>")
      .append(ESAPI.encoder().encodeForHTML("<script>alert(1)</script>"));
    
    //String jsCode = "<div style=\"color:red;\">aaaaa</div><script>alert(1)</script>";
    //String jsEncoder = ESAPI.encoder().encodeForHTML(jsCode);
    return sb.toString();
}

頁面展現效果:
在這裏插入圖片描述
中間的js代碼就會以文本的形式展現。app

4. encodeForHTML()源碼解析:
在這裏插入圖片描述
該方法執行最終會根據unicode編碼從map對象中獲取對應的替代字符來替換js中的特定字符。
該map中包含如下數據:ide

private static synchronized Map<Integer, String>
mkCharacterToEntityMap() {
Map<Integer, String> map = new HashMap(252);
map.put(34, 「quot」);
map.put(38, 「amp」);
map.put(60, 「lt」);
map.put(62, 「gt」);
map.put(160, 「nbsp」);
map.put(161, 「iexcl」);
map.put(162, 「cent」);
map.put(163, 「pound」);
map.put(164, 「curren」);
map.put(165, 「yen」);
map.put(166, 「brvbar」);
map.put(167, 「sect」);
map.put(168, 「uml」);
map.put(169, 「copy」);
map.put(170, 「ordf」);
map.put(171, 「laquo」);
map.put(172, 「not」);
map.put(173, 「shy」);
map.put(174, 「reg」);
map.put(175, 「macr」);
map.put(176, 「deg」);
map.put(177, 「plusmn」);
map.put(178, 「sup2」);
map.put(179, 「sup3」);
map.put(180, 「acute」);
map.put(181, 「micro」);
map.put(182, 「para」);
map.put(183, 「middot」);
map.put(184, 「cedil」);
map.put(185, 「sup1」);
map.put(186, 「ordm」);
map.put(187, 「raquo」);
map.put(188, 「frac14」);
map.put(189, 「frac12」);
map.put(190, 「frac34」);
map.put(191, 「iquest」);
map.put(192, 「Agrave」);
map.put(193, 「Aacute」);
map.put(194, 「Acirc」);
map.put(195, 「Atilde」);
map.put(196, 「Auml」);
map.put(197, 「Aring」);
map.put(198, 「AElig」);
map.put(199, 「Ccedil」);
map.put(200, 「Egrave」);
map.put(201, 「Eacute」);
map.put(202, 「Ecirc」);
map.put(203, 「Euml」);
map.put(204, 「Igrave」);
map.put(205, 「Iacute」);
map.put(206, 「Icirc」);
map.put(207, 「Iuml」);
map.put(208, 「ETH」);
map.put(209, 「Ntilde」);
map.put(210, 「Ograve」);
map.put(211, 「Oacute」);
map.put(212, 「Ocirc」);
map.put(213, 「Otilde」);
map.put(214, 「Ouml」);
map.put(215, 「times」);
map.put(216, 「Oslash」);
map.put(217, 「Ugrave」);
map.put(218, 「Uacute」);
map.put(219, 「Ucirc」);
map.put(220, 「Uuml」);
map.put(221, 「Yacute」);
map.put(222, 「THORN」);
map.put(223, 「szlig」);
map.put(224, 「agrave」);
map.put(225, 「aacute」);
map.put(226, 「acirc」);
map.put(227, 「atilde」);
map.put(228, 「auml」);
map.put(229, 「aring」);
map.put(230, 「aelig」);
map.put(231, 「ccedil」);
map.put(232, 「egrave」);
map.put(233, 「eacute」);
map.put(234, 「ecirc」);
map.put(235, 「euml」);
map.put(236, 「igrave」);
map.put(237, 「iacute」);
map.put(238, 「icirc」);
map.put(239, 「iuml」);
map.put(240, 「eth」);
map.put(241, 「ntilde」);
map.put(242, 「ograve」);
map.put(243, 「oacute」);
map.put(244, 「ocirc」);
map.put(245, 「otilde」);
map.put(246, 「ouml」);
map.put(247, 「divide」);
map.put(248, 「oslash」);
map.put(249, 「ugrave」);
map.put(250, 「uacute」);
map.put(251, 「ucirc」);
map.put(252, 「uuml」);
map.put(253, 「yacute」);
map.put(254, 「thorn」);
map.put(255, 「yuml」);
map.put(338, 「OElig」);
map.put(339, 「oelig」);
map.put(352, 「Scaron」);
map.put(353, 「scaron」);
map.put(376, 「Yuml」);
map.put(402, 「fnof」);
map.put(710, 「circ」);
map.put(732, 「tilde」);
map.put(913, 「Alpha」);
map.put(914, 「Beta」);
map.put(915, 「Gamma」);
map.put(916, 「Delta」);
map.put(917, 「Epsilon」);
map.put(918, 「Zeta」);
map.put(919, 「Eta」);
map.put(920, 「Theta」);
map.put(921, 「Iota」);
map.put(922, 「Kappa」);
map.put(923, 「Lambda」);
map.put(924, 「Mu」);
map.put(925, 「Nu」);
map.put(926, 「Xi」);
map.put(927, 「Omicron」);
map.put(928, 「Pi」);
map.put(929, 「Rho」);
map.put(931, 「Sigma」);
map.put(932, 「Tau」);
map.put(933, 「Upsilon」);
map.put(934, 「Phi」);
map.put(935, 「Chi」);
map.put(936, 「Psi」);
map.put(937, 「Omega」);
map.put(945, 「alpha」);
map.put(946, 「beta」);
map.put(947, 「gamma」);
map.put(948, 「delta」);
map.put(949, 「epsilon」);
map.put(950, 「zeta」);
map.put(951, 「eta」);
map.put(952, 「theta」);
map.put(953, 「iota」);
map.put(954, 「kappa」);
map.put(955, 「lambda」);
map.put(956, 「mu」);
map.put(957, 「nu」);
map.put(958, 「xi」);
map.put(959, 「omicron」);
map.put(960, 「pi」);
map.put(961, 「rho」);
map.put(962, 「sigmaf」);
map.put(963, 「sigma」);
map.put(964, 「tau」);
map.put(965, 「upsilon」);
map.put(966, 「phi」);
map.put(967, 「chi」);
map.put(968, 「psi」);
map.put(969, 「omega」);
map.put(977, 「thetasym」);
map.put(978, 「upsih」);
map.put(982, 「piv」);
map.put(8194, 「ensp」);
map.put(8195, 「emsp」);
map.put(8201, 「thinsp」);
map.put(8204, 「zwnj」);
map.put(8205, 「zwj」);
map.put(8206, 「lrm」);
map.put(8207, 「rlm」);
map.put(8211, 「ndash」);
map.put(8212, 「mdash」);
map.put(8216, 「lsquo」);
map.put(8217, 「rsquo」);
map.put(8218, 「sbquo」);
map.put(8220, 「ldquo」);
map.put(8221, 「rdquo」);
map.put(8222, 「bdquo」);
map.put(8224, 「dagger」);
map.put(8225, 「Dagger」);
map.put(8226, 「bull」);
map.put(8230, 「hellip」);
map.put(8240, 「permil」);
map.put(8242, 「prime」);
map.put(8243, 「Prime」);
map.put(8249, 「lsaquo」);
map.put(8250, 「rsaquo」);
map.put(8254, 「oline」);
map.put(8260, 「frasl」);
map.put(8364, 「euro」);
map.put(8465, 「image」);
map.put(8472, 「weierp」);
map.put(8476, 「real」);
map.put(8482, 「trade」);
map.put(8501, 「alefsym」);
map.put(8592, 「larr」);
map.put(8593, 「uarr」);
map.put(8594, 「rarr」);
map.put(8595, 「darr」);
map.put(8596, 「harr」);
map.put(8629, 「crarr」);
map.put(8656, 「lArr」);
map.put(8657, 「uArr」);
map.put(8658, 「rArr」);
map.put(8659, 「dArr」);
map.put(8660, 「hArr」);
map.put(8704, 「forall」);
map.put(8706, 「part」);
map.put(8707, 「exist」);
map.put(8709, 「empty」);
map.put(8711, 「nabla」);
map.put(8712, 「isin」);
map.put(8713, 「notin」);
map.put(8715, 「ni」);
map.put(8719, 「prod」);
map.put(8721, 「sum」);
map.put(8722, 「minus」);
map.put(8727, 「lowast」);
map.put(8730, 「radic」);
map.put(8733, 「prop」);
map.put(8734, 「infin」);
map.put(8736, 「ang」);
map.put(8743, 「and」);
map.put(8744, 「or」);
map.put(8745, 「cap」);
map.put(8746, 「cup」);
map.put(8747, 「int」);
map.put(8756, 「there4」);
map.put(8764, 「sim」);
map.put(8773, 「cong」);
map.put(8776, 「asymp」);
map.put(8800, 「ne」);
map.put(8801, 「equiv」);
map.put(8804, 「le」);
map.put(8805, 「ge」);
map.put(8834, 「sub」);
map.put(8835, 「sup」);
map.put(8836, 「nsub」);
map.put(8838, 「sube」);
map.put(8839, 「supe」);
map.put(8853, 「oplus」);
map.put(8855, 「otimes」);
map.put(8869, 「perp」);
map.put(8901, 「sdot」);
map.put(8968, 「lceil」);
map.put(8969, 「rceil」);
map.put(8970, 「lfloor」);
map.put(8971, 「rfloor」);
map.put(9001, 「lang」);
map.put(9002, 「rang」);
map.put(9674, 「loz」);
map.put(9824, 「spades」);
map.put(9827, 「clubs」);
map.put(9829, 「hearts」);
map.put(9830, 「diams」);
return Collections.unmodifiableMap(map);
}工具

今天暫時就到這裏了,後續有問題再繼續更新測試

相關文章
相關標籤/搜索