http://min-blog.tistory.com/1544

'Computer > Link..' 카테고리의 다른 글

W3 Schools  (0) 2014.08.29
안드로이드폰 서버  (0) 2014.08.29
디자인보드  (0) 2014.08.29
안드로이드 UI참고 JOA Soft  (0) 2014.08.29
부트스트렙  (0) 2014.08.29

http://www.designboard.net/dboard/files/main.php

'Computer > Link..' 카테고리의 다른 글

안드로이드폰 서버  (0) 2014.08.29
반응형 메뉴(CSS)  (0) 2014.08.29
안드로이드 UI참고 JOA Soft  (0) 2014.08.29
부트스트렙  (0) 2014.08.29
CodeLion 웹서비스 만들기  (0) 2014.08.14

http://joasoft.net/?r=home

'Computer > Link..' 카테고리의 다른 글

반응형 메뉴(CSS)  (0) 2014.08.29
디자인보드  (0) 2014.08.29
부트스트렙  (0) 2014.08.29
CodeLion 웹서비스 만들기  (0) 2014.08.14
프로그래밍 입문용 개발툴 HelloWorld  (0) 2014.08.14

http://getbootstrap.com/

'Computer > Link..' 카테고리의 다른 글

디자인보드  (0) 2014.08.29
안드로이드 UI참고 JOA Soft  (0) 2014.08.29
CodeLion 웹서비스 만들기  (0) 2014.08.14
프로그래밍 입문용 개발툴 HelloWorld  (0) 2014.08.14
안드로이드 Unity 게임만들기  (0) 2014.08.14
■ 보호 대책
 

(1) 일반 대책

-데이터베이스와 연동을 하는 스크립트의 모든 파라미터들을 점검하여 사용자의 입력 값이 SQL injection을 발생시키지 않도록 수정한다.
 

-사용자 입력이 SQL injection을 발생시키지 않도록 사용자 입력 시 특수문자(' " / \ ; : Space -- +등)가 포함되어 있는지 검사하여 허용되지 않은 문자열이나 문자가 포함된 경우에는 에러로 처리한다.
 

-SQL 서버의 에러 메시지를 사용자에게 보여주지 않도록 설정한다. 공격자는 리턴 되는 에러 메시지에 대한 분석을 통하여 공격에 성공할 수 있는 SQL Injection 스트링을 알아낼 수 있다. 따라서 SQL 서버의 에러 메시지를 외부에 제공하지 않도록 한다.
 

-웹 애플리케이션이 사용하는 데이터베이스 사용자의 권한을 제한한다. 가능하면 일반 사용자 권한으로는 모든 system stored procedures에 접근하지 못하도록 하여 웹 애플리케이션의 SQL Injection 취약점을 이용하여 데이터베이스 전체에 대한 제어권을 얻거나 데이터베이스를 운용중인 서버에 대한 접근이 불가능하도록 한다.
 

-php.ini 설정 변경
  : php.ini 설정 중 magic_quotes_gpc 값을 On으로 설정한다.

; Magic quotes
;

; Magic quotes for incoming GET/POST/Cookie data.
magic_quotes_gpc = On  ; Off에서 On으로 변경한다.

; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
magic_quotes_runtime = Off

; Use Sybase-style magic quotes (escape ' with '' instead of \').
magic_quotes_sybase = Off
 
 
 

■ 개발 언어별 대책
-사용자로부터 입력받은 변수로 SQL 쿼리 구문을 생성하는 CGI는 입력받은 변수를 체크하거나 변경하는 로직을 포함하고 있어야 한다.
-입력받은 변수와 데이터 베이스 필드의 데이터형을 일치 시켜야 하고, 사용 중인 SQL 구문을 변경시킬 수 있는 특수문자가 포함되어 있는지 체크해야 한다.
-검색 부분과 같이 클라이언트로부터 생성된 SQL 구문을 받는 부분이 있다면 이를 제거해야 한다.
 
□ ASP
-취약한 SQL Injection 예제
prodId = Request.QueryString("productId")
Set conn = server.createObject("ADODB.Connection")
Set rs = server.createObject("ADODB.Recordset")

query = "select prodName from products where id = " & prodId

conn.Open "Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=productDB; User Id=dbid; Password="
rs.activeConnection = conn
rs.open query

If not rs.eof Then
response.write "제품명" & rs.fields("prodName").value
Else
response.write "제품이 없습니다"
End If
 
 

-안전한 SQL Injection 예제

prodId = Request.QueryString("productId")
prodId = replace(prodId, "'", "''")' 특수문자 제거
prodId = replace(prodId, ";", "")
set conn = server.createObject("ADODB.Connection")
set rs = server.createObject("ADODB.Recordset")
query = "select prodName from products where id = " & prodId
conn.Open "Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=productDB; User Id=dbid; Password="
rs.activeConnection = conn
rs.open query
If not rs.eof Then
response.write "제품명" & rs.fields("prodName").value
Else
response.write "제품이 없습니다"
End If
 
 

□ PHP
-addslashes() 함수 사용
  : 사용자가 입력하는 값들($_GET, $_POST)을 모두 addslashes() 함수를 이용하여 처리하여 준다.

addslashes()
용도 : DB Query와 같이 인용된 부분앞에 역슬래쉬를 붙여서 반환한다. 해당 문자에는 작은 따옴표, 큰 따옴표, 역슬래쉬, NULL이 있다. SQL Injection 공격을 위해서 사용한다.
- 적용 가능한 PHP : PHP 3 이상
 
 

-취약한 SQL Injection 예제

$query = "SELECT id, password, username FROM user_table WHERE id='$id'";// 사용자로부터 입력받은 id 값을 사용자 table에서 조회
$result = OCIParse($conn, $query);
if (!OCIExecute($result)) 
echo "<META http-equiv=\"refresh\" content=\"0;URL=http://victim.com\">";// 메인 페이지로 redirect

OCIFetchInto($result, &$rows);
... 중략 ...
 
 
-안전한 SQL Injection 예제

$query = sprintf("SELECT id,password,username FROM user_table WHERE id='%s';",addslashes($id));
// id변수를 문자형으로 받고, id변수의 특수문자를 일반문자로 변환한다.

// @ 로 php 에러 메시지를 막는다.
$result = @OCIParse($conn, $query);
if (!@OCIExecute($result)) 
error("SQL 구문 에러");
exit;

@OCIFetchInto($result,&$rows);
... 중략 ...
 
 

□ JSP
-취약한 SQL Injection 예제

String sql="SELECT*FROM user_table"+"WHERE id=" + response.getParameter("id")
+ " AND password = " + response.getParameter("password");

Class.forName("org.gjt.mm.mysql.Driver");
conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);

stmt = conn.createStatement();
rs = stmt.executeQuery(query);

while(rs.next()) 
 
 

-안전한 SQL Injection 예제

String sql = "SELECT*FROM user_table"+"WHERE id = ?"+"AND password = ?";
ResultSet rs = null;
PreparedStatement pstmt = null;
try 
conn = DBManager.getConnection();
pstmt = conn.prepareStatement(sql);

pstmt.setString(1, request.getParameter("id"));
pstmt.setString(2, request.getParameter("password"));

rs = pstmt.executeQuery();


'Computer > DB' 카테고리의 다른 글

SQL Insert select update delete  (0) 2014.09.01
SQL hr 계정 풀기  (0) 2014.09.01
SQL Date 관련 함수  (0) 2014.09.01
SQL 원격 데이터베이스 접속  (0) 2014.08.13
SQL Group by  (0) 2014.08.13

SQL Injection 은 사용자가 요상한 문자열을 입력해서 쿼리를 요상하게 바꿔 버려서 아무 아이디로나 로그인이 훅 되버린다던지 하는 쪼금은 싱거운 해킹방법중의 하나라고 나는 알고 있다.


뭐 예를들어 아이디 비번을 입력하고 로그인 할때

아이디로  
admin' OR '1'='1 요런걸 입력하고 로그인을 했을때 admin 으로 싹 로그인 되 버리는 어처구니 없는 일이 발생하는 것이 SQL Injection 처리를 쪽바로 해주지 않았을때 일어나는 참혹한 일이다.


SQL Injection 이 발생하는 전형적인 코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
String userid=request.getParameter("userid");
String password=request.getParameter("password");
 
....
....
 
Statement stmt = conn.createStatement();
ResultSet rs =
   stmt.executeQuery("select count(*) as cnt from member where userid='"+userid+"' and password='"+password+"'");
 
....
....




위 코드처럼 사용자 정보를 받아서 쿼리를 실행하고 실행결과가 1 이면 로그인 시켜주는 코드가 있다.

그런데 사용자가 아디디로 admin' OR '1'='1  을 입력하고 비밀번호로 abcd 를 입력한 후 로그인 시켜주셈~ 이라고 하면 우째될까?

위 코드대로라면  select count(*) from member where userid='amdin' OR '1'='1' and password = 'abcd'   이 쿼리가 실행되 버린다 -_-;;;

무섭다. 만약 사용자 테이블에 userid 가 admin 이라는 레코드가 있다면 admin 으로 로그인 되버리는 것이다. 

이런 어처구니 없는일이 놀랍게도 몇몇 허접한 사이트에서는 더러 통하는데도 있다 . -_-



아무튼 헛소리는 고만하고 본론으로 들어가서 SQL Injection 을 방지하려면 우째해야 될까? 

Statement 대신  PreparedStatement 를 쓰면 된다. 요렇게.

1
2
3
4
5
6
7
8
9
10
11
....
....
 
PreparedStatement stmt = conn.prepareStatement("select count(*) from member where userid=? and password=?");
stmt.setString(1, userid);
stmt.setString(2, password);
 
ResultSet rs = stmt.executeQuery();
 
....
....




PreparedStatement 만 쓰면 해결된다고 해서 또 요렇게는 쓰지 말길 -.-;

1
2
PreparedStatement stmt =
   conn.prepareStatement("select count(*) from member where userid='" + userid + "'" and password='" + password + "'");




※ 하이버네이트는 한번도 안써봐서 잘 모르겠는데 mybatis 나 ibatis 같은 경우는 무난하게 #{xxxx} 요런것만 썼다면 SQL Injection 이 방지된다. 

그런데 WHERE 절에 ${xxxx} 이렇게 있다면 다시 한번 생각해 보기 바란다. 

${xxxx} 이거는 문자열 더하는것과 똑같기 때문에 위험하다. ${xxxx} 요런건 ORDER BY 절 같은데만 사용하자.

'Computer > JSP Servlet JavaScript' 카테고리의 다른 글

JavaScript 예제  (0) 2015.01.15
JSP navigation 마우스오버 Script  (0) 2015.01.14
JSP 버튼이벤트  (0) 2014.08.19
JQUERY 화면전환 없이 비동기 업로드  (0) 2014.08.18
JSP Modal 사용하기  (0) 2014.08.14

XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/그림파일이름"> 


<div class="row row-form">

<div class="col-md-12">

<a

onclick="mqigoWritePage('mainQnA.do?nowpage=1&start_row=1&finish_row=10');"

class="btn btn-success pull-right">목록으로</a> <a

onclick="delqnaPage('mainQnaDelete.do?qna_id=${qna.qna_id}');"

class="btn btn-success pull-right">질문삭제</a>

</div>

</div>


<!-- 코멘트삭제 -->


<script type="text/javascript">

function delCommentPage(updateurl) {

$.ajax({

url : updateurl,

success : function(resultData) {

qloadtabpage('mainQnAInner.do?qna_id=${qna.qna_id}');

}

});


}

</script>


<!-- 질문삭제 -->


<script type="text/javascript">

function delqnaPage(updateurl) {

$.ajax({

url : updateurl,

success : function(resultData) {

qloadtabpage('mainQnA.do?nowpage=1&start_row=1&finish_row=10');

}

});


}

</script>




<script type="text/javascript">

function qloadtabpage(loadingurl) {

$.ajax({

url : loadingurl,

type : 'get',//'post',

timeout : 1000,

traditional : true,

async : false,

error : function() {

alert('네트워크가 불안정합니다.');

},

success : function(resultData) {

$("#mainqnainnerview").html(resultData);

}

});

}

</script>

'Computer > JSP Servlet JavaScript' 카테고리의 다른 글

JSP navigation 마우스오버 Script  (0) 2015.01.14
JSP SQL Injection 방어 기법  (0) 2014.08.21
JQUERY 화면전환 없이 비동기 업로드  (0) 2014.08.18
JSP Modal 사용하기  (0) 2014.08.14
JSP c:choose  (0) 2014.08.14

맵퍼

<select id="selectByLecIdwithRownums" parameterType="map"

resultType="databoardvo">

select databoard_id, databoard_title,

databoard_regid,databoard_content,databoard_filename, databoard_uploaddate, lecture_id,

databoard_regname,category

from

(

select rownum rn, ln.*

from

(select *

from databoard

where lecture_id=#{lecture_id}

order by databoard_id desc) ln

)

where rn between #{start_row} and #{finish_row}

order by databoard_id desc

</select>




컨트롤러


@RequestMapping(value = "databoard.do", method = RequestMethod.GET)

public ModelAndView dataBoard(HttpServletRequest request,

HttpSession session) {

ModelAndView mv = new ModelAndView();

int start_row = Integer.parseInt(request.getParameter("start_row"));

int finish_row = Integer.parseInt(request.getParameter("finish_row"));

int nowpage = Integer.parseInt(request.getParameter("nowpage"));


LectureVO lecture = (LectureVO) session.getAttribute("lecture");


int lecture_id = 0;

lecture_id = lecture.getLecture_id();


System.out.println(lecture_id);


System.out.println(start_row + "~~~~" + finish_row + "~~~~"

+ lecture_id);


ArrayList<DataBoardVO> datalist = dataBoardService

.selectByLecIdwithRownums(lecture_id, start_row, finish_row);


// System.out.println(dataBoardService.selectByLecId(lecture_id));

for (DataBoardVO aa : datalist) {

System.out.println(aa);

}


// 게시글 총합 구하기

int boardcount = dataBoardService.countBoardByLecId(lecture_id);

mv.addObject("databoardtotal", boardcount);

mv.addObject("datalist", datalist);

mv.addObject("nowpage", nowpage);

mv.setViewName("lecture/dataBoard");


return mv;

}


JSP



  <c:set var="previous" value=""></c:set>

<c:set var="next" value=""></c:set>

<c:set var="pid" value='id="previous"'></c:set>

<c:set var="nid" value='id="next"'></c:set>

<c:set var="pages" value="${databoardtotal/10}"></c:set>

<c:if test="${nowpage<=1}">

<c:set var="previous" value='class="disabled"'></c:set>

<c:set var="pid" value=""></c:set>

</c:if>

<c:if test="${pages<nowpage}">

<c:set var="next" value='class="disabled"'></c:set>

<c:set var="nid" value=""></c:set>

</c:if>

<div class="row">

<ul class="pager">

<li ${previous }><a ${pid } >Previous</a></li>

<li>${nowpage}</li>

<li ${next }><a ${nid } >Next</a></li>

</ul>

</div>

   

 

<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->

<script

src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

  <script type="text/javascript">

var nowpage =${nowpage};

var start_row ;

var finish_row ;

$(document).ready(function() {


$("#previous").on("click", function() {

--nowpage;

start_row = nowpage * 10 - 9;

finish_row = nowpage * 10;

loadtabpage('databoard.do?start_row='+start_row+'&finish_row='+finish_row+'&nowpage='+nowpage);

});

$("#next").on("click", function() {

++nowpage;

start_row = nowpage * 10 - 9;

finish_row = nowpage * 10;

loadtabpage('databoard.do?start_row='+start_row+'&finish_row='+finish_row+'&nowpage='+nowpage);

});


});



</script> 



'Computer > Spring Maven MyBatis' 카테고리의 다른 글

MyBatis <> 사용 & 기간검색  (0) 2015.05.30
Spring Mybatis 기본설정  (0) 2014.09.26
Spring GET방식 한글 깨짐  (0) 2014.08.18
Spring 파일 다운로드  (0) 2014.08.18
Spring 파일 업로드  (0) 2014.08.18

Server.xml line 65    


<Connector URIEncoding = "UTF-8" connectionTimeout="20000" port="8088" protocol="HTTP/1.1" redirectPort="8443"/>

'Computer > Spring Maven MyBatis' 카테고리의 다른 글

Spring Mybatis 기본설정  (0) 2014.09.26
Spring 게시판 페이지  (0) 2014.08.18
Spring 파일 다운로드  (0) 2014.08.18
Spring 파일 업로드  (0) 2014.08.18
Mybatis ResultMap con  (0) 2014.08.13

+ Recent posts