무제

Size: px
Start display at page:

Download "무제"

Transcription

1 v 년월4

2

3 목차 제1 장개요 0 제1절배경 0 제2 절가이드목적및구성 0 제2 장소프트웨어개발보안 0 제1 절개요 0 제2 절개발보안체계 0 제3 절보안약점진단제거 0 제3 장보안약점진단방법 0 제1 절입력데이터검증및표현 0 제2 절보안기능 0 제3 절시간및상태 0 제4 절에러처리 0 제5 절코드오류 0 제6 절캡슐화 0 제7절 API 악용 0 3

4 부록 0 제1 절용어정의 0 제2절 SW 보안약점항목 0 제3 절참고자료 0 4

5 제1장개요 제1절배경 최근의사이버공격은침입차단시스템등보안장비를우회하거나, 보안패치 가발표되기이전의보안취약점을악용하는제로데이공격, 웹사이트해킹등 이많은부분을차지하고있으며, 이러한공격은 SW 자체의보안취약점을이 용하는경우가대부분 1) 이다. 웹사이트의경우, 불특정다수가쉽게접근할수있고, 사용자가입력한정 보를처리하는프로그램의특성상외부공격에항상노출되어있어사이버침 해사고가발생할가능성이높다. 특히, 웹서버, 웹어플리케이션서버등웹 관련 SW 자체의보안취약점을이용한공격은침입차단시스템등보안장비로 대응하기가쉽지않다. 최근 SQL 삽입공격등 SW 자체보안취약점을이용하 여개인정보등의중요정보가유출된웹서버공격인 Sony 社 플레이스테이션 사이트공격, 페이팔(PayPal) 웹사이트공격, 홍콩증권거래소공격이대표적 인예라고할수있다. 또한, 최근증가추세에있는 APT(Advance Persistent Threat) 2) 공격의경 우, 기업이나기관의내부기밀자료를목표로내부에서구축 운영되고있는 특정의 SW 보안취약점을대상으로지능화된방법을통해지속적으로공격하 기때문에이에대한근본적인대책이필요하다. APT 공격의대표적인예로 는이란핵시설대상스턱스넷, 글로벌에너지기업대상나이트드래곤(Night Dragon) 3), 국내 OO 전산망해킹등이있다. 1) 가트너社 ( 05.5 월) 에따르면, 사이버공격의약가 75% 응용프로그램의취약점을악용한것이라고함 2) 다양한 IT 기술과방식들을이용해조직적으로특정기업이나조직네트워크에침투해활동거점을마련한뒤정보를외부로빼돌리는형태의공격들을총칭. 공격방법은내부자에게악성코드가포함된이메일을오랜기간동안꾸준히발송해한번이라도클릭되길기다리는형태나, 스턱스넷(Stuxnet) 과같이악성코드가담긴이동식디스크(USB) 등으로전파하는형태, 악성코드에감염된 P2 P 사이트에접속하면악성코드에감염되는형태등이있음 [ 출처:TT A 용어사전] 3) APT 형태의공격의한형태로년 2011 맥아피(macafee) 에서발표한공격방법임 [ 참고: -night-dragon.pdf] 5

6 사이버침해사고에근본적으로대응및예방하기위해서는 SW 개발단계부 터 SW 보안취약점을진단하여제거하여안전한 SW를개발하는체계도입이 필수적이다. 미국의경우, 국토안전부(DHS) 를중심으로시큐어코딩을포함한 SW 개발전과정( 설계 구현 시험등) 보안활동에대해활발히연구하고있으 며, 이는 2011년 11 월발표한 안전한사이버미래를위한청사진(Blueprint for a Secure Cyber Future) 4) 에도나타나있다. 미국의 Microsoft 社사례를살펴보면자사의제품출시후보안패치횟수를 분석한결과, 개발과정에서 MS-SDL 5) 을적용한운영체제는보안취약점이 45% 감소하였으며, DB 서버의경우보안취약점이 91% 감소하였다. [ 출처 : 마이크로소프트홈페이지( < 그림 1-3> SDL 적용와 SW 미적용 SW의취약점수 다음의표는 SW 설계단계에서제품출시까지보안취약점등결함을제거하 는시점에따른비용차이를분석한결과로서, 보안취약점제거비용이최대 4) 참고 : 5) MS-SDL(Microsoft Software Development Lifec-ycle) : MS 사의안전한개발생명주기( 개발보안생명주기) 6

7 30 배까지차이가발생할수있음을나타내고있다. 즉, 설계과정에서발생한 결함이개발완료후에발견 조치되는경우엔설계단계에서결함을수정하는 비용대비배30 의비용이발생한다. 또한, 통합과정에발생한결함의경우엔 20 배의수정비용이발생하는등개발완료이전의보안취약점진단및제거 활동이무엇보다중요함을나타내고있다. < 표 1-1> SW 개발단계별결함수정비용분석 구분설계단계코딩단계통합단계베타제품제품출시 설계과정 1배 5배 10배 15배 30배 코딩과정 - 1배 10배 20배 30배 통합과정 - - 1배 10배 20배 [ 출처년 : NIST, The Economic Impacts of Inadequate Infrasturcture for Software Testing, 2002 월5 ] 이는 SW 개발단계에서의보안취약점제거가 SW 보안품질제고를위한근 본적인접근으로운영단계에서수행하는것보다비용대비효과가훨씬우수 하고볼수있다. 따라서, SW 개발단계에서부터 SW 보안취약점을진단하여 제거하는등 SW 개발보안( 시큐어코딩) 체계를도입 운영하면신뢰할수있는 전자정부서비스를구현하여안전한서비스를제공할수있다. 또한, 개발보안 의실효성제고를위해개발자가보안취약점을이해하고보안조치를할수있 도록개발보안사전교육을강화하고검, 수과정에서보안취약점잔존여부를 확인해야한다. 7

8 제2절가이드목적및구성 목적 정보화사업수행시시큐어코딩을준수하여를 SW 개발했는지 여부를진단하기위해 SW 보안약점진단기법제시 대상 전자정부 SW 보안약점진단원 범위 행정기관등이추진하는정보화사업 유지보수로변경되거나신규로개발되는소스코드전체 (2 장) SW 개발보안의무화대상 범위 기준과정보화사업단 계별 기관별 주체별개발보안활동소개 구성 (3 장) SW 보안약점에대한설명및보안대책과 JAVA 언어로 작성된시큐어코딩예제기반의구체적인진단방법소개 ( 부록) 용어정리, SW 보안약점항목, 참고자료 ( 발주자) SW 보안약점진단 제거요구사항도출시활용 활용 ( 사업자) 자체적으로 SW 보안약점을진단 제거시활용 ( 진단원) 사업자가수행한 SW 보안약점제거결과진단시활용 ( 기타) SW 개발보안체계및보안약점진단 제거방법에대한이해 8

9 제2장소프트웨어개발보안 본장에서는 SW 개발보안전반을살펴본후, 보안약점진단 제거를중심으 로살펴본다. 제1절개요 SW 개발보안은해킹등사이버공격의원인인보안약점을 SW 개발단계에서 사전에제거하여안전한를 SW 개발하기위한목적으로추진하는 SW 개발체계이다. SW 개발보안의무화는년 월정보시스템감리대상정보화사업억(40 원이상) 을대상으로시행하여, 2014년까지감리대상전체정보화사업으로 SW 개발보안의무화대상을확대해나갈예정이다. SW 개발보안적용대상및 범위, 기준등을요약하면다음과같다. 구분내용비고 대상 정보시스템감리대상정보화사업 ( 월) 40 억원이상 ( 13.7 월) 20 억원이상 ( 14.7 월) 감리대상전사업 단계적확대 범위 소스코드신규개발 ( 전체, 유지보수로변경된부분 ) 상용SW 제외 기준 SW 보안약점기준(SQL 삽입등개 41 항목) 정보시스템구축운영지침 별표3 정보시스템감리기준( 제10조제1 항세부검사항목) 에포함 공통평가기준 (Common Criteria, CC) 정보보호시스템평가인증지침 진단원자격기준 정보시스템구축운영지침 별표4 SW 보안약점진단 진단도구 평가 인증 진단원 자격부여 9

10 제2절 SW 개발보안체계 전자정부법에따른정보시스템을기획 구축 운영 유지보수하기위한사업인 정보화사업은정보화사업발주, 계약( 사업자선정 ), SW 개발( 사업수행), 검사및 인수( 운영) 단계로구분할수있다. 정보화사업단계별 SW 개발보안관련보 안활동은다음과같이요약할수있다. 구분내용비고 발주 제안요청서에 SW 개발보안적용 명시 행정기관등 계약 SW 개발보안을위한적절한개발절차 방법, SW 약점진단도구사용여부등확인 보안 행정기관등 개발인력대상 SW 개발보안관련교육실시 개발 SW 개발보안가이드를참조하여개발 자체적으로보안약점진단및제거 사업자 SW 보안약점의부적합사항( 감리수행결과보고서) 조치 검사/ 인수 SW 보안약점제거여부진단 SW 보안약점의부적합사항( 감리수행결과보고서) 조치여부확인 감리법인 10

11 SW 개발보안관련보안활동을행안부, 한국인터넷진흥원(KISA) 등참여기 관별역할로구분하면다음과같이요약할수있다. 구분내용비고 국정원과협의하여 SW 개발보안가이드 공지 행안부 보안약점진단과관련된기술지원 진단원양성과관련된업무수행 교육및자격부여, 자격유무확인등 KISA 진단원양성과관련된위탁업무수행및세부사항공지 교육자격부여, 자격유무확인등 제안요청서에 SW 개발보안적용 명시 행정기관등 SW 보안약점진단 제거결과확인 감리법인( 감리대상사업) 또는자체적( 감리대상外사업) 으로수행 보안약점진단과관련한기술지원( 행안부) 요청 개발인력대상 SW 개발보안관련교육실시 사업자 SW 개발보안가이드를참조하여개발 자체적으로보안약점진단및제거 SW 보안약점의부적합사항( 감리수행결과보고서) 조치 감리법인 SW 보안약점진단시, 진단원우선배치 SW 보안약점제거여부진단및조치결과확인 11

12 SW 개발보안관련보안활동을발주자, 개발자, 진단원등 SW 개발보안참 여인력별역할로구분하면다음과같이요약할수있다. 구분내용비고 제안요청서에 SW 개발보안적용 명시 발주자 감리법인을통해 SW 정보화사업감리수행대상사업 보안약점제거여부확인 사업자에의한보안약점진단 제거결과확인 정보화사업감리수행대상에해당하지않는사업 보안약점진단과관련한기술지원( 행안부) 요청 개발인력대상 SW 개발보안관련교육실시 개발자 SW 개발보안가이드를참조하여개발 자체적으로보안약점진단및제거 SW 보안약점의부적합사항( 감리수행결과보고서) 조치 진단원 SW 보안약점제거여부진단및조치결과확인 12

13 제3 절보안약점진단 제거 본절에서는 SW 개발보안준수여부검증을수행하는진단원에대한역할을 정의하는한편, 구체적인업무지침을제시한다. SW 보안약점을진단하는방법은다음과같이정적분석과동적분석으로구분 할수있으며, 서로상호보완적이라고할수있다. 구분내용특징 정적분석 SW 를실행하지않고, 소스코드 수준으로보안약점분석 SW 개발과정에서주로사용 SW 개발초기에보안약점발견으로 수정비용절감 컴포넌트간발생할수있는통합된 보안약점발견은제한적임 설계 구조관점의보안약점은 발견할수없음 동적분석 SW 실행환경에서보안약점분석 SW 시험단계에서주로사용 소스코드필요없음 정확도와커버리지향상 도구사용자의수준에영향을받음 구조관점의보안약점은발견할수없음 본가이드는동적분석에비해상대적으로 SW 개발초기에보안약점을발견 하여제거할수있어비용절감효과가높은정적분석기반의 단기법을소개한다. SW 보안약점진 SW 보안약점진단원은본가이드를참고하여사업자가자체적으로수행한 SW 보안약점진단 제거결과의적합성여부를확인하여야한다. 참고로사 업자는 SW 보안약점진단 제거를위해행정안전부장관이고시한 정보보호 13

14 시스템평가 인증지침 에따라국가정보원장이인증한보안약점진단도구를 구매하여사용하여야하며, 진단원은사업자가사용한진단도구를이용하여 SW 보안약점진단 제거결과를확인하여야한다. 정적분석을기반으로 SW 보안약점을진단하는구체적인기법은제3장에서 설명한다. 정보화사업에따른정보시스템구축시활용되는전자정부프레임워 크는언JAVA 어로구현되었으며, 실제 JAVA 언어가많이활용되기때문에 SW 보안약점진단기법설명의이해를돕기위해사용된예제소스코드는 JAVA 언어를기반으로작성하였다. 14

15 제3장보안약점진단방법 제1절입력데이터검증및표현 프로그램입력값에대한검증누락또는부적절한검증, 데이터의잘못된 형식지정등으로인해발생되는보안약점으로 SQL 삽입, 크로스사이트스크립 트등의공격을유발할수있다. 1. SQL 삽입 가. 개요 데이터베이스와 (DB) 연동된웹어플리케이션의입력폼및 URL 파라미터에 SQL 문을삽입하여 DB로부터정보를열람하거나조작할수있는취약점을유 발할수있다. < 그림삽입 3-1> SQL 예를들어, < 그림 3-1> 에서나타낸것처럼취약한웹어플리케이션에서는사 용자로부터입력된값을필터링과정없이넘겨받아동적쿼리 (Dynamic Query) 6) 를 6) 동적쿼리(Dynamic Query) : DB 에서실시간으로받는쿼리. parameterized statement가동적쿼리가됨 15

16 생성하기때문에개발자가의도하지않은쿼리가생성되어정보유출에악용될 수있다. 나. 보안대책 prepared statement 7) 객체등을이용하여 DB에컴파일된쿼리문 ( 상수) 를전달 하는방법을사용한다. parameterized statement 를사용하는경우에는 DB 쿼리 에사용되는외부입력데이터에대하여특수문자및쿼리예약어를필터링하 고, Struts, Spring 등과같은프레임워크를사용하는경우에는외부입력값 검증모듈및보안모듈을상황에맞추어적절하게사용한다. 다. 코드예제 다음의예제는안전하지않은코드의예를나타낸것이다. 외부입력으로부터 tablename과 name을받아서쿼리를 SQL 생성하고있으며, name 의값으로 "name' OR 'a'='a" 를할당하여조작된쿼리를생성하는문자열전달이가능하 다. 안전하지않은코드의예 JAVA 1: try { 2: String tablename = props.getproperty("jdbc.tablename"); 3: String name = props.getproperty("jdbc.name"); 4: String query = "SELECT * FROM " + tablename + " WHERE Name =" + name; 5: stmt = con.preparestatement(query); 6: rs = stmt.executequery(); 7: : catch (SQLException sqle) { 9: finally { 이를안전한코드로변환하면다음과같다. 인자를받는 preparedstatement 객체를상수스트링으로생성하고, 인자부분을 setxxx() 메소드로설정하여, 7) Prepared Statement : 사전에를 Compiled Query 만드는객체로등에서 MySQL, Oracle, DB2, SQL Server 지원하며, Java의의 JDBC, Perl 의 DBI, PHP 의 PDO, ASP 를 ADO 이용하여사용가능 16

17 외부의입력이쿼리문의구조를바꾸는것을방지하는것이필요하다. 안전한코드의예 JAVA 1: try { 2: String tablename = props.getproperty("jdbc.tablename"); 3: String name = props.getproperty("jdbc.name"); 4: String query = "SELECT * FROM? WHERE Name =? "; 5: stmt = con.preparestatement(query); 6: stmt.setstring(1, tablename); 7: stmt.setstring(2, name); 8: rs = stmt.executequery(); 9: : catch (SQLException sqle) { 11: finally { 라. 진단방법 statement 8) 객체를통해서쿼리가실행되는부분을확인하고 ( ➀), statement 객체가객Prepared Statement 체인지확인한다( ➁). Prepared Statement 객체를 사용하는경우엔기본적으로안전하다고판정한다. 이후쿼리문에사용되는변수가외부입력값인지확인하고( ➂), 인경우엔해당변수에대한필터링모듈이존재하는지확인한다. 외부입력값 필터링모듈 이존재하거나관련프레임워크에서적절히조치할경우에도안전하고판정하고, 그외에는취약하다고판정한다. class Login { public Connection getconnection() throws SQLException { DriverManager.registerDriver(new com.microsoft.sqlserver.jdbc.sqlserverdriver()); String dbconnection = PropertyManager.getProperty("db.connection"); return DriverManager.getConnection(dbConnection); String hashpassword(char[] password) { // create hash of password // 외부입력값을 (username, password) 제공받음 8) statement : 자바에서사용하는객체중하나 17

18 public void doprivilegedaction(string username, char[] password) throws SQLException { Connection connection = getconnection(); if (connection == null) { // handle error try { String pwd = hashpassword(password); String sqlstring = "SELECT * FROM db_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" ); // Authenticated; proceed finally {... 다음의예제를살펴보면, 15라인에서사용자의입력값이변수 pid에저장되 고 19라인에서 commentdao.getprojectcommenttblbywhere 함수의파라미터로 사용된다. 해당함수에서 134 라인에서문자열을만들게되고, 138번라인에서 해당문자열을이용해서쿼리를실행하므로취약하다고판정한다. 1C : projectdetail.jsp <% 15: String pid = request.getparameter("projectid") == null? "" : request.getparameter("projectid"); MashupProjectDao mashupdao = (MashupProjectDao)DAOHelper.getMashupProjectDao(applicatio n); ProjectCommentDao commentdao = 18

19 (ProjectCommentDao)DAOHelper.getProjectCommentDao(application); MashupProjectTbl prjtbl = mas hupdao.getmashupprojecttbl(pid); 19: ArrayList commentlist = commentdao.getprojectcommenttblbywhere("where projectid="+pid+" order by writedate desc"); String loginid = session.getattribute("userid") == null? "" : (String)session.getAttribute("userid"); int category = prjtbl.getcategory(); String categorystr = ""; 1C : ProjectCommentDAO.java public ArrayList getprojectcommenttblbywhere(string where) { String sql_ = this.getmessagesourceaccessor().getmessage("proj ectcommentdao.getprojectcommenttbl"); ArrayList ret = new ArrayList(); 134: sql_ += " "+where; try { JdbcTemplate template_ = this.getjdbctemplate(); 138: List tmp = template_.query( sql_, new ProjectCommentRowMapper()); ret = Util.trimToResize(tmp); catch(dataaccessexception e) <SQL 삽입 : JDO> 외부의신뢰할수없는입력을적절한검사과정을거치지않고, JDO(Java Data Objects) API의 SQL 또는쿼JDOQL 리생성을위한문자열로사용하면, 공격자가프로그래머가의도하지않았던문자열을전달함으로써쿼리의의미를 왜곡시키거나그구조를변경하여임의의쿼리명령어를수행할수있다. 19

20 다음의예제에서는공격자가외부의입력값(name) 을 "name'; DELETE FROM MYTABLE; --" 로주게되면, 다음과같은쿼리가실행되어테이블이삭 제될수있으므로취약하다고판정한다. (SELECT col1 FROM MYTABLE WHERE name = 'name' ; DELETE FROM MYTABLE; --') 1: 2: public class U9102 implements ContactDAO { 3: public List<Contact> listcontacts() { 4: PersistenceManager pm = getpersistencemanagerfactory().getpersistencemanager(); 5: String query = "select from " + Contact.class.getName(); 6: try { 7: Properties props = new Properties(); 8: String filename = "contacts.txt"; 9: FileInputStream in = new FileInputStream(fileName); 10: if( in!= null ) { props.load(in); 11: in.close(); 12: // 외부로부터입력을받는다 13: String name = props.getprop erty("name"); 14: if( name!= null ) { 15: query += " where name = '" + name + "'"; 16: 17: catch (IOException e) { 18: 19: // 와부입력값이객JDO 체의인자로사용된다. 20: return (List<Contact>) pm.newquery(query).execute(); 21: 22: 20

21 <SQL 삽입 : Persistence> J2EE Persistence API 를사용하는응용프로그램에서외부의입력을아무검 증없이쿼리에그대로사용하면, 쿼리의의미를왜곡시키거나그구조를변경 하여임의의쿼리명령어가수행될수있다. 공격자가외부의입력(id) 의값으 로을 "foo'; DELETE FROM MYTABLE; --" 주게되면, 다음과같은쿼리가실 행되어테이블이삭제될수있으므로취약하다고판정한다. (SELECT col1 FROM MYTABLE WHERE name = 'foo' ; DELETE FROM MYTABLE; --') 1: 2: public class U9103 implements ServletContextListener { 3: public List<?> getallitemsinwildcardcollection() { 4: EntityManager em = getentitymanager(); 5: List<U9103> r_type = null; 6: try { 7: Properties props = new Properties(); 8: String filename = "conditions.txt"; 9: FileInputStream in = new FileInputStream(fileName); 10: props.load(in); 11: 12: // 외부로부터입력을받는다. 13: String id = props.getproperty("id"); 14: // 외부입력값이의 query 인자로사용이된다. 15: Query query = 16: em.createnativequery("select OBJECT(i) FROM Item i WHERE i.itemid > " + id); 17: List<U9103> items = query.getresultlist(); 18: 19: return r_type; 20: 21

22 21: <SQL 삽입 : mybatis Data Map> 외부에서입력된값이쿼리의인자값으로만사용되지않고쿼, 리명령어에 연결되는문자열로사용되면, 공격자가의도하지않았던문자열을전달함으로 써쿼리의의미를왜곡시키거나, 그구조를변경하여임의의 DB 명령어를수 행할수있다. 다음의예제는 mybatis Data Map 에서사용하는쿼리설정파일(XML) 이다. 정의된쿼리중 delstudent 명령어선언에서쿼리에삽입되는인자들중 $name$ 으로전달되는문자열값은그대로연결되어쿼리가만들어진다. 따라 서만약 name 의값으로을 "' OR 'x'='x'" 전달하면다음과같은쿼리가실행되 어테이블의모든원소를삭제할수있으므로취약하다고판정한다. (DELETE STUDENTS WHERE NUM = #num# and Name = '' OR 'x'='x') 1: <?xml version="1.0" encoding="utf-8"?> 2: <!DOCTYPE sqlmap PUBLIC "-//ibatis.com//dtd SQL Map 2.0//EN" " 3: <sqlmap namespace="student"> 4: <resultmap id="studentresult" class="student"> 5: <result column="id" property="id" /> 6: <result column="name" property="name" /> 7: </resultmap> 8: <select id="liststudents" resultmap="studentresult"> 9: SELECT NUM, NAME 10: FROM STUDENTS 11: ORDER BY NUM 12: </select> 13: <select id="namestudent" parameterclass="integer" resultclass="student"> 22

23 14: SELECT NUM, NAME 15: FROM STUDENTS 16: WHERE NUM = #num# 17: </select> 18: <!-- dynamic SQL 사용 --> 19: <delete id="delstudent" parameterclass="student"> 20: DELETE STUDENTS 21: WHERE NUM = #num# AND Name = '$name$' 22: </delete> 23: </sqlmap> <SQL 삽입 : Hibernate> 외부의신뢰할수없는입력을적절한검사과정을거치지않고 Hibernate API의쿼SQL 리생성을위한문자열로사용하면, 공격자가프로그래머가의도 하지않았던문자열을전달함으로써쿼리의의미를왜곡시키거나그구조를변 경하여임의의 DB 명령어가수행되도록할수있다. 다음의예제에서는외부의입력(idValue) 을아무검증과정없이쿼리에그대 로사용하고있다. 만일, 외부의입력으로과 "n' or '1'='1" 같은문자열이입력 되면, 다음과같은쿼리가실행되어테이블내의모든레코드가반환될수있 으므로취약하다고판정한다. ("from Address a where a.name='n' or '1'='1'") 1: 2: public void listhoney() { 3: Session sessio n = new Configuratio n().configure().buildsessio nfactor y().opensession(); 4: try { 5: Properties props = new Properties(); 6: String filename = "Hibernate.properties"; 23

24 7: FileInputStream in = new FileInputStream(fileName); 8: props.load(in); 9: 10: // 외부로부터입력을받음 11: String idvalue = props.getproperty("idlo w"); 12: // 외부입력을검증없이 SQL qeuery 문의인자로사용한다. 13: Query query = session.createquery("from Address a where a.name='" + idvalue); 14: query.list(); 15: catch (IOException e) { 16: 마. 참고문헌 [1] CWE-89 SQL Injection - [2] OWASP Top (OWASP 2010) A1 Injection [3] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Insecure Interaction Between Components, RANK 1 CWE-89 Improper Neutralization of Special Elements used in an SQL Command('SQL Injection') 24

25 2. 자원삽입 가. 개요 외부입력값을검증하지않고시스템자원 (resource) 에대한식별자로사용하는 경우, 공격자는입력값조작을통해시스템이보호하는자원에접근하거나수 정할수있다. < 그림자3-2> 원삽입 나. 보안대책 외부의입력을자원 ( 파일, 소켓의포트등 ) 식별자로사용하는경우, 식별자가적절 한검증을거치거나사전에정의된적합한리스트에서선택되도록작성한다. 외부의입력이파일명인경우에는경로순회 (directory traversal) 9) 를수행하는위험한 문자를제거한다. 9) 경로순회등을 :./,../ 사용하여상대경로참조방식을이용해웹루트디렉토리를벗어나다른디렉토리의중요파일에접근하는공격법. 경로추적이라고도함 25

26 다. 코드예제 다음의예제는안전하지않은코드의예를나타낸것으로, 외부의입력 (service) 을포트번호로그대로사용하고있다만. 일, 공격자가 Service No 의 값으로 과같은값을지정하면기존의 80 포트에서구동되는서비스와 충돌되어에러를야기할수있다. 안전하지않은코드의예 - JAVA 1: 2: public void f() throws IOException { 3: int def = 1000; 4: ServerSocket serversocket; 5: Properties props = new Properties(); 6: String filename = "file_list"; 7: FileInputStream in = new FileInputStream(fileName); 8: props.load(in); 9: 10: // 외부에서입력한데이터를받는다. 11: String service = props.getproperty("service No"); 12: int port = Integer.parseInt(service); 13: 14: // 외부에서입력받은값으로소켓을생성한다. 15: if (port!= 0) 16: serversocket = new ServerSocket(port ); 17: else 18: serversocket = new ServerSocket(def ); 19: 20: 21: 다음은안전한코드예제를나타낸것이다. 내부자원에접근할때외부입력 값을포트번호와같은식별자로직접사용하는것은바람직하지않으며꼭, 필 요한경우엔가능한리스트를설정하고, 해당범위내에서할당되도록작성한 다. 26

27 안전한코드의예 - JAVA 1: 2: public void f() throws IOException { 3: ServerSocket serversocket; 4: Properties props = new Properties(); 5: String filename = "file_list"; 6: FileInputStream in = new FileInputStream(fileName); 7: String service = ""; 8: 9: if (in!= null && in.available() > 0) { 10: props.load(in); 11: // 외부로부터데이터를입력받는다. 12: service = props.getproperty("service No"); 13: 14: // 외부의입력을기본적인내용검사를한다. 15: if ("".equals(service)) service = "8080"; 16: 17: int port = Integer.parseInt(service); 18: // 외부입력에서포트번호를검사한후리스트에서적합한값을할당한다. 19: switch (port) { 20: case 1: 21: port = 3001; break; 22: case 2: 23: port = 3002; break; 24: case 3: 25: port = 3003; break; 26: default: 27: port = 3000; 28: 29: // 서버소켓에검사완료된포트를할당한다. 30: serversocket = new ServerSocket(port); 31: 32: 33: 라. 진단방법 파일명, 소켓의포트등과같은자원을사용하는지확인하고( ➀), 해당자원 에대한접근이외부에서직접접근하는지확인한다( ➁). 직접접근하지않고 매핑표나리스트를가질경우엔기본적으로안전하다고판단하고, 그외의경우 27

28 엔취약하다고판정한다. public class U99 { public void f() throws IOException { int def = 1000; ServerSocket serversocket; Properties props = new Properties(); String filename = "file_list"; FileInputStream in = new FileInputStream(fileName); props.load(in); String service = props.getproperty("service No"); int port = Integer.parseInt(service); ➁ if (port!= 0) serversocket = new ServerSocket(port ); ➀ else serversocket = new ServerSocket(def ); ➀ serversocket.close(); 중요자원( 파일, 소켓등) 을사용할때, 식별자를구성하는외부입력값에대한 검증프로세스가존재하지않으면취약한것으로판정한다. 다음의예제를살펴보면, EgovFileCmprs.jsp 에서 70라인에외부입력값인 source를받아서 74라인에서 static 함수인 EgovFileCmprs.cmprsFile를호출하 고있다. 이함수내에서 48라인에서 source 파라미터를 source1 변수에저장하 고, 50라인에서그변수를사용하여파일을생성하고있어취약하다고판정한 다. T2 : EgovFil ecmprs.jsp else if(execflag.equals("cmprs_action")){ boolean iscompressed = false; 70: String source = request.getparameter("so urce"); String target = r equest.getparameter("target"); 28

29 if (source!= null && source.length() > 0 && target!= null && target.length() > 0) { 74: iscompressed = EgovFileCmprs.cmprsFile(source, target); %> T2 : EgovFil ecmprs.java public static boolean cmprsfile(string source, String target) throwsexception { // boolean result = false int cnt = 0; // byte[] buffer = new byte[buffer_size]; FileInputStream finput = null FileOutputStream foutput = null ZipOutputStream zoutput = null 48: String source1 = source.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR); String target1 = target.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR); 50: File srcfile = new File(source1); 다음의예제에서사용되는 스가안전하므로취약하지않다고판정한다. getrealpath(), getcontextpath() 등내부함수는소 File file = new File(getServletConfig().getServl etcontext().getrealpath("/")+ "/jsp/gis/gcc/cmm/xml/"+(string)tempchartimglist.get(k)); 다음의예제는파일명에사용자입력값이나가 property 들어가는것이아니 고, 파일의필터에적용되는것이므로자원삽입이취약하지않다고판정한다. 29

30 File[] f_list = f.listfiles( new FilenameFilter() { public boolean accept(file dir, String name) { // TODOAuto-generated method stub String org_code = SystemierConfig.getPropertiesBean().getProperty("is.OrgCode"); if(name.matches( org_code + ".*CVDTST.*" + ".txt") ) { return true return false ); BufferedReader in = new BufferedReader( new FileReader( f_list[0].getpath() )); 일반적으로프레임워크를사용하면서시스템 Property에서가져오는명령어 는취약하지않다. 하지만시스템프로퍼티등공용으로사용하는프로퍼티가 아닌개별사용프로퍼티일경우는정탐, 시스템프로퍼티사용은오탐으로처 리한다. 마. 참고문헌 [1] CWE-99 자원삽입 - [2] OWASP Top (OWASP 2010) A1 Injection [3] SANS Top (SANS 2010) Insecure Interaction 30

31 3. 크로스사이트스크립트 가. 개요 웹페이지에악의적인스크립트를포함시켜사용자측에서실행되게유도할 수있다. 예를들어, < 그림과 3-3> 같이검증되지않은외부입력이동적웹페 이지생성에사용될경우, 전송된동적웹페이지를열람하는접속자의권한으 로부적절한스크립트가수행되어정보유출등의공격을유발할수있다. < 그림 3-3> 크로스사이트스크립트 나. 보안대책 일반적인경우에는사용자가문자열에스크립트를삽입하여실행하는것을 막기위해사용자가입력한문자열에서 <, >, &,, 등을 replace등의문자변 환함수나메소드를사용하여로 &lt, &gt, &amp, &quot 치환한다. HTML 태 그를허용하는게시판에서는게시판에서지원하는 HTML 태그의리스트(White List) 를선정한후, 해당태그만허용하는방식을적용한다. 31

32 다. 코드예제 파라미터 (name) 에 <script>alert (document.cookie);</script> 와같은스크립트 코드가입력되고, 이값이그대로사용되면공격자에게피해자의쿠키정보가 전송될수있다. 안전하지않은코드의예 JAVA 1: <h1>xss Sample</h1> 2: <% 3: String name = request.getparameter("name "); 4: %> 5: <p>name:<%=name%></p> 외부입력문자열에서 replaceall() 메소드를사용하여 <, >, &, " " 같이스크 립트생성에사용되는문자열을 &lt, &gt, &amp, &quot 등으로변경하면, 파라 미터 name 에악성코드가포함되더라도스크립트가실행되지않는다. 안전한코드의예 JAVA 1: <% 2: String name = request.getparameter("name"); 3: if ( name!= null ) { 4: name = name.replaceall("<","<"); 5: name = name.replaceall(">",">"); 6: name = name.replaceall("&","&"); 7: name = name.replaceall(" ","""); 8: else { return; 9: %> 라. 진단방법 웹페이지로출력하는변수값이존재하는지확인하고( ➀), 해당변수값이외 부입력값인지확인한( ➁) 후변수값이적절하게필터를거치는지확인한다. 적절한필터를거친후출력되는경우나프레임워크등을사용하여자체적인검증기능이존재하면안전하지만그외에는취약하다. 32

33 contenttype="text/html" pageencoding="utf-8"%> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> </head> <body> <h1>xss Sample</h1> <% // 외부로부터이름을받음 String name = request.getparameter("name"); ➁ %> <!-- 외부로부터받은 name이적절한필터없이그대로출력 --> <p>name:<%=name%></p> ➀ </body> </html> 다음의예제에서는번17 째라인에서사용자의입력값인파라미터 prptnames 값을자바스크립트안에직접사용하고있기때문에취약하다. L1 : RexViewer.jsp <script language="javascript"> <!--// function fnopen(){ var oreport = GetfnParamSet(); //oreport.rptname = "testserver"; 17: oreport.rptname = "<%=request.getparameter("prptnames")%>"; 다음의예제에서는 13라인에서외부입력값으로를 password 입력받아저장 하고 54 라인에서저장한변password 수를출력하고있어취약하다. 33

34 C1 : loginpass.jsp String logintype =(String)gpkirequest.getParameter("loginType"); String loginid =(String)gpkirequest.getParameter("loginId"); 13: String password =(String)gpkirequest.getParameter("password");... <form id="loginform" name="loginform" method="post" action="<c:url value='/afapplogin.do'/>"> <input type="hidden" name="forward" id="forward" value="cmm/access/amcmmaccess020"/> <input type="hidden" name="logintype" id="logintype" value="<%=logint ype%>"/> <input type="hidden" name="afapplogindvo_loginid" id="afapplogindvo_loginid" value="<%=loginid%>"/> 54: <input type="hidden" name="afapplogindvo_password" id="afapplogindvo_password" value="<%=password%>"/> <input type="hidden" name="afapplogindvo_dn" id="afapplogindvo_dn" value="<%=subdn%>"/> </form> 아래소스는의 Sprin g Framework 을 Ann otation 사용한소스이다. 이소스에서 ApApsCommonCodeVO apapscommoncodevo 어노테이션에따라 apsapscommoncodevo 는외부입력값이다. 154라인에서외부입력값의 target값을저장하고번162 째라인에서외부입력값을 response 의 output stream 에출력하고있다. 그과정에서입력값에대한필터링이없으므로취약 한것으로판정한다. 34

35 C1 : n/makecommoncode.do") public void makecommoncode(httpsession ApApsCommonCodeVO apapscommoncodevo, HttpServletRequest request,httpservletresponse respo nse, ModelMap model) throws Exception { 154: String target = apapscommoncodevo.gettarget(); List resultlist = apapsexcelservice.selectcommoncode(apapscommoncodevo); JSONArray jsonarray = new JSONArray(); jsonarray = JSONArray.fromObject(resultList); response.setcontenttype("text/xml;charset=utf-8"); PrintWriter printwriter = response.getwriter(); 162: printwriter.print(target); printwriter.print(jsonarra y.tostring()); printwriter.flush(); printwriter.close(); < 크로스사이트스크립트 : DOM> 다음의예제에서는 request.getparameter() 에서전달된외부의입력(name) 이 document.write() 의인자값생성에그대로사용되어취약한것으로판정한다. 1: 2: <% 3: // 외부로부터입력을받는다. 35

36 4: String name = request.getparameter("name"); 5: %> 6: <SCRIPT language="javascript"> 7: // 외부의입력을그대로출력한다. 8: document.write("name:" + <%=name%> ); 다음의예제처럼 paget.getcontextpath(), request.getserverport() 등의내부 함수를사용한경우에는 XSS 취약성이없는것으로판정한다. <%@ page language="java" import="java.io.*,java.text.*,java.util.*,java.net.*,com.inswave.system.config.*,com.inswave.system.except ion.*"%> AC_FL_RunContent("src", "<%=request.getcontextpath()%>/mashup/block_editor", <div id="map" class="mapstyle">server port: <%=request.getserverport()%></div></div> document.location = " 다음의코드와같이 out 결과가숫자형인경우는안전한것으로판정한다. <%=PageIndex.PageNumber(pageNo, tot_pg, action_url, imageroot, add_tag)%> 다음의예제와같이 out 결과가날자형인경우에는안전한것으로판정한다. String today = Util.getNowDateStri ng("yyyy-mm-dd"); String start = today; <input type=text size=10 name="start" value='<%=start%>' readonly> 다음의예제와같이 것으로판정한다. out 결과가프로그램내부에서정해진경우에는안전한 g1 = new WKTRead er().read(geometryparam); p1 = (Polygon) g1.buffer(double.parsedouble(buffersizeparam)); 36

37 response.setcontenttype("text/plain;charset=euc-kr"); response.setheader("cache-control", "no-cache"); response.getwriter().write(p1.totext()); 다음의예제와같이 response 가아닌에 System write하는경우에는안전한 것으로판정한다. // 파라메터설정 String exam_tgt_se = request.getparameter("exam_tgt_se"); String mw_take_no = request.getparameter("mw_take_no"); String apv_perm_reg_mgt_no = request.getparameter("apv_perm_reg_mgt_no"); String mw_afr_no = request.getparameter("mw_afr_no"); System.out.println("exam_tgt_se : " + exam_tgt_se); System.out.println("mw_take_no : " + mw_take_no); System.out.println("apv_perm_reg_mgt_no : " + apv_perm_reg_mgt_no); 다음의예제와같이 property가 Source 인경우 : Output String의소스가 Property인경우엔 정한다. XSS 취약점을일으킬가능성이낮으므로안전한것으로판 String swebhome = " + request.getservername() + PropLoader.getWEBLOCATION() String SFTP_CabFile = swebhome +"commo n/cabfiles/filewiz.cab#version=1,0,1,161"; <OBJECT id="filewizard" style="width: 0px; HEIGHT: 0px" name="filewizard" classid="clsid:317642dd-af52-11d4-bc2a-0050da8aee6f" codebase="<%=sftp_cabfile%>"> 다음의예제와같이사용자입력값이아닌경우에는안전한것으로판정한 37

38 다. L1 : cmc.jsp var CompPath = "%XPLATFORM%\\" + skey + "\\component"; //XLauncher.componentpath = CompPath; XLauncher.o nlyone = "fals e"; var iconstr = "<%= req uest.getrequesturl() %>"; 마. 참고문헌 [1] CWE-80 XSS - [2] OWASP Top (OWASP 2010) A2 Cross-Site Scripting(XSS) [3] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Insecure Interaction Between Components, RANK 4 CWE-79 Improper Neutralization of Input During Web Page Generation('Cross-site Scripting') 38

39 4. 운영체제명령어삽입 가. 개요 적절한검증절차를거치지않은사용자입력값이운영체제명령어의일부 또는전부로구성되어실행되는경우, 의도하지않은시스템명령어가실행되 어부적절하게권한이변경되거나시스템동작및운영에악영향을미칠수있 다. 일반적으로명령어라인의인수나스트림입력등외부입력을사용하여시 스템명령어를생성하는프로그램이많이있다. 하지만이러한경우외부입 력문자열은신뢰할수없기때문에적절한처리를해주지않으면, 공격자가 원하는명령어실행이가능하게된다. < 그림 3-4> 운영체제명령어삽입 나. 보안대책 웹인터페이스를통해서버내부로시스템명령어를전달시키지않도록어플 리케이션을구성하고외부에서전달되는값을그대로시스템내부명령어로사 용하지않는다. 외부입력에따라명령어를생성하거나선택이필요한경우에는 명령어생성에필요한값들을미리지정해놓고외부입력에따라선택하여사 39

40 용한다. 다. 코드예제 다음의예제는 cmd.exe 명령어를사용하여 rmandb.bat 배치명령어를수행 하며, 외부에서전달되는값dir_type 이 mandb.bat의인자값으로서명령어스 트링의생성에사용된다만. 약, 외부의공격자가의도하지되지않은문자열을 전달할시, dir_type 이의도했던인자값이아닐경우, 비정상적인업무를수행 할수있다. 안전하지않은코드의예 JAVA 1: 2: props.load(in); 3: String version = props.getproperty("dir_type"); 4: String cmd = new String("cmd.exe /K \"rmandb.bat \""); 5: Runtime.getRuntime().exec(cmd + " c:\\prog_cmd\\" + version); 6: 7: 다음의예제와같이미리정의된인자값의배열을만들어놓고, 외부의입력 에따라적절한인자값을선택하도록하여, 외부의부적절한입력이명령어로 사용될가능성을배제하여야한다. 안전한코드의예 JAVA 1: 2: props.load(in); 3: String version[] = {"1.0", "1.1"; 4: int versionselection = Integer.parseInt(props.getProperty("version")); 5: String cmd = new String("cmd.exe /K \"rmandb.bat \""); 6: String vs = ""; 7: if (versionselection == 0) 8: vs = version[0]; 9: else if (versionselection == 1) 10: vs = version[1]; 40

41 11: else 12: vs = version[1]; 13: Runtime.getRuntime().exec(cmd + " c:\\prog_cmd\\" + vs); 14: 라. 진단방법 운영체제명령어(exec(), system(), Runtime.getRuntime().exec 등) 를실행할 수있는함수가호출되는지확인하고( ➀) 외부에서전달되는값이시스템내부 명령어의일부또는전부로사용되는지확인한다( ➁). 정해진후보군에서선택 된값(White List) 이거나적절하게검증하면안전하고그외에는취약하다. public class U78 { public void f() throws IOException { Properties props = new Properties(); String filename = "file_list"; FileInputStream in = new FileInputStream(fileName); props.load(in); // 외부에서전달된값이시스템내부명령어의일부로사용됨. String version = props.getproperty("dir_type"); ➁ String cmd = new String("cmd.exe /K \"rmandb.bat && cleanup.bat\""); // 입력값검증없이내부명령어의일부로사용됨. Runtime.getRuntime().exec(cmd + " c:\\prog_cmd\\" + version); ➀ 다음의예제에서외부입력값인 processmon의값을파라미터로 getprocessid 를호출하고, 42라인에서 execstr 문자열을만들며그문자열이 55 라인에서명령어로쓰이고있어취약한것으로판정한다. I3 : EgovProcess electprocesssttus.do") public String ProcessMonVO processmo nvo, ModelMap model ) throws Exception { 41

42 //System.out.printl n("filesysnm" + filesysmntrngvo.getfilesysnm()); m o d e l. a d d A t t r i b u t e ( " p r o c e s s S t t u s ", Process MonChecker.getProcessId(processMonVO.getProcessNm()));... I3 : ProcessMo nchecker.java public staticstring getprocessid( String process Nm) throws Exception { Process p = null String procssttus = null BufferedReader buf = null String result = null 42: String execstr = "tasklist /fo table /nh /fi \"imagename eq "+processnm+"\"" int cnt = 0; String str = null try { // if (Globals.OS_TYPE == null) { throw new RuntimeException("Globals.OS_TYPE property value is needed!!!"); // if ("WINDOWS".equals(Globals.OS_TYPE)) { cnt = -1;// 55: p = Runtime.getRuntime().exec(execStr); 프레임워크특성상 Property 사용은금지할수없다. 하지만시스템프로퍼 티등공용으로사용하는프로퍼티가아닌개별사용프로퍼티일경우는취약한 42

43 것으로, 시스템프로퍼티를사용하는경우는안전한것으로판정한다. 다음의예제에서 12라인 cmdstr 변수는 Property에서값을가져온이후 13 라인에서문자열을만드는데사용되고, 해당문자열이 15라인에서명령어로사 용되므로안전한것으로판정한다. I3 : EgovSysInfo.java public static floatgetmoryfreecpcty() throws Exception { // float cpcty = 0; Process p = null try { 12: String cmdstr = EgovProperties.getPathProperty(Globals.SERVER_CONF_PATH, "SHELL."+Globals.OS_TYPE+".getMoryInfo"); 13: Stri ng[] command = {cmd Str.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR), "FREE" 15: p = Runtime.getRuntime().exec(command); //p.waitfor(); 사용자의입력값이운영체제명령어를실행하는데들어가지않을때에는안 전한것으로판정한다. 다음의예제에서 fname은 srcfile.getname() 의결과값인파일의이름이므로 명령어에삽입되어공격할수있는 file separator 나.. 등의문자열이없으므 로취약하지않은것으로판정한다. public static String getowner(string file) throws Exception { 43

44 String owner = "" String src = file.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR); BufferedReader b_err=null BufferedReader b_out=null try { File srcfile = newfile(src); if (srcfile.exists()) { String parentpath = srcfile.getparent(); String fname = srcfile.getname(); Process p = null String cmdstr = EgovProperties.getProperty(Globals.SHELL_FILE_PATH, "SHELL."+Globals.OS_TYPE+".getDrctryOwner"); String[] command = {cmdstr.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR), parentpath.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR), fname; p = Runtime.getRuntime().exec(command); 마. 참고문헌 [1] CWE-78 OS injection - [2] OWASP Top (OWASP 2010) A1 Injection [3] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Insecure Interaction Between Components, RANK 2 CWE-78 Improper 44

45 Neutralization of Special Elements used in an OS Command('OS Command Injection') 45

46 5. 위험한형식파일업로드 가. 개요 서버측에서실행될수있는스크립트파일(asp, jsp, php 파일등) 이업로드가능하고, 이파일을공격자가웹을통해직접실행시킬수있는경우공격자는스크립트파일을업로드하고이파일을통해시스템내부명령어를실행하거나외부와연결하여시스템을제어할수있다. < 그림위3-5> 험한형식파일업로드 나. 보안대책 화이트리스트방식으로허용된확장자만업로드를허용한다. 업로드되는파일 을저장할때에는파일명과확장자를외부사용자가추측할수없는문자열로 변경하여저장하며, 저장경로는 web document root 밖에위치시켜서공격자 가웹을통한직접접근을차단한다. 다. 코드예제 업로드할파일에대한유효성을검사하지않으면, 위험한유형의파일을공 격자가업로드하거나전송할수있다. 안전하지않은코드의예 JAVA 46

47 1: 2: public void upload(httpservletrequest request) throws ServletException { 3: MultipartHttpServletRequest mrequest = (MultipartHttpServletRequest) request; 4: String next = (String) mrequest.getfilenames().next(); 5: MultipartFile file = mrequest.getfile(next); 6: 7: // MultipartFile 로부터을 file 얻음 8: String filename = file.getoriginalfilename(); 9: 10: // upload 파일에대한확장자체크를하지않음 11: File uploaddir = new File("/app/webapp/data/upload/notice"); 12: String uploadfilepath = uploaddir.getabsolutepath()+"/" + filename; 13: 14: /* 이하 file upload 루틴 */ 15: 업로드파일의확장자를검사하여허용되지않은확장자일경우업로드를제한하고있으며저, 장시외부입력된파일명을그대로사용하지않고있다. 안전한코드의예 JAVA 1: 2: public void upload(httpservletrequest request) throws ServletException { 3: MultipartHttpServletRequest mrequest = (MultipartHttpServletRequest) request; 4: String next = (String) mrequest.getfilenames().next(); 5: MultipartFile file = mrequest.getfile(next); 6: if ( file == null ) return ; 7: // 화이트리스트방식으로업로드파일의확장자를체크한다. 8: if ( filename!= null ) { 9: if ( filename.endswith(".doc") filename.endswith(".hwp") 10: filename.endswith(".pdf") filename.endswith(".xls") ) { 11: /* file 업로드루틴 */ 12: // 저장시파일명을외부사용자가추측할수없는형태로변경 13:... 14: 15: else throw new ServletExeption(" 에러"); 16: 17: /* 이하 file upload 루틴 */ 18: 47

48 라. 진단방법 외부입력값에서파일명을얻어오는부분이존재하는지확인하고허( ➀), 용된 확장자에대해서만파일업로드를허용하는지확인한다( ➁). 제어문등을사용 하여허용된파일만업로드될경우와업로드된파일명을외부에서알수없는형태로변경할경우엔안전하지만그외에는취약하다. public class U434 { public void upload(httpservletrequest request) throws ServletException { // MultipartHttpServletRequest 를케스팅 MultipartHttpServletRequest mrequest = (MultipartHttpServletRequest) request; String next = (String) mrequest.getfilenames().next(); MultipartFile file = mrequest.getfile(next); // MultipartFile로부터이름 file 을얻어옴 String filename = file.getoriginalfilename(); ➀ // upload 파일에대한확장자유효성체크를하지않음 File uploaddir = new File("/app/webapp/data/upload/notice"); String uploadfilepath = uploaddir.getabsolutepath()+"/"+filename; ➁ /* 이하 file upload 루틴 */ getoriginalfilename() 함수를사용하여파일을업로드하면서해당파일의확 장자를체크하지않는경우엔취약하다고판정한다. 다음의예제는업로드된파일의확장자를체크하고있지않으므로취약한것 으로판정한다. while (itr.hasnext()) { Entry<String, List<MultipartFile>> entry = itr.next(); filelist = entry.getvalue(); for(int i=0, s=filelist.size(); i<s; i++) { file = (MultipartFile)fileList.get(i); 48

49 String orginfilename = file.getorigi nalfilename(); // // 원파일명이없는경우처리 // ( 첨부가되지않은 inp ut file type) // if ("".equals(orginfilename)) continue; //// int index = orginfilename.lastindexof("."); //String filename = orgi nfilename.substring(0, index); String fileext = orginfil ename.substring(index + 1); String newname = KeyStr + EgovStringUtil.getTimeStamp() + filekey; long _size = file.getsize(); if (!"".equals(orginfilename)) { filepath = storepathstring + File.separator + newname; file.transferto(new File(filePath)); fvo = new FileVO(); fvo.setfileextsn(fileext); fvo.setfilestrecours(storepathstring); fvo.setfilemg(long.tostring(_size)); fvo.setorignlfilenm(orginfilename); fvo.setstrefilenm(newname); fvo.setatchfileid(atchfileidstring); fvo.setfilesn(string.valueof(fil ekey)); //writefile(file, newname, storepathstri ng); result.add(fvo); filekey++; 49

50 return result; 다음의예제는파일의확장자를체크하여필터링하고있으므로안전하다. String orginfilename = file.getoriginalfilename() // // 원파일명이없는경우처리 // ( 첨부가되지않은 inp ut file type) // if ("".equals(orginfilename)) { continue //// int index = orginfilename.lastindexof("."); //String filename = orgi nfilename.substring(0, index); String fileext = orginfilename.substring(index + 1); /* 확장자체크 */ for(object fileexclusionext : this.fileexclusionextension) { if( ((String) fileexclusionext).equals(fileext.tolowercase())) { throw new Exception("egume.message.error.file.exclusion.extension"); 다음의예제와같이 getoriginalfilename() 의리턴값을저장하여사용하지 않으면, 파일명을사용하기위해다른곳에서해당함수를호출할것이므로취 약하지않다고판정한다. if (!"".equals(file.getoriginalfilename())) { zipmanageservice.insertexcelzip(file.getinputstream()); 50

51 마. 참고문헌 [1] CWE-434 Unrestricted Upload of File with Dangerous Type - [2] OWASP Top Ten 2007 A3, Malicious File Execution [3] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Insecure Interaction Between Components, RANK 9 CWE-434 Unrestricted Upload of File with Dangrous Type 51

52 6. 신뢰되지않는 URL 주소로의자동접속연결 가. 개요 사용자로부터입력되는값을외부사이트의주소로사용하여자동으로연결하는 서버프로그램은피싱공격에 (phishing) 노출되는취약점을가질수있다. 일반적으로클라이언트에서전송된주URL 소로연결하기때문에안전하다고 생각할수있으나, 해당폼의요청을변조함으로써공격자는사용자가위험한 URL 로접속할수있도록공격할수있다. 나. 보안대책 자동연결할외부사이트의과 URL 도메인은화이트리스트로관리하고, 사 용자입력값을자동연결할사이트주소로사용하는경우에는입력된값이화 이트리스트에존재하는지확인해야한다. 다. 진단방법 사이트자동연결기능을구현하고있고, 대상사이트주소를사용자입력을 통해동적으로결정하고있으나주소에대한검증절차가없다면취약한것으로 판정한다. 52

53 다. 코드예제 다음과같은코드가서버에존재할경우공격자는다음과같은링크를희생자가접근하도록함으로써희생자가피싱사이트등으로접근하도록할수있다. (<a href=" 안전하지않은코드의예 JAVA 1: 2: protected void doget(httpservletrequest request, HttpServletResponse response) 3: throws ServletException, IOException { 4: String query = request.getquerystring(); 5: if (query.contains("url")) { 6: String url = request.getparameter("url"); 7: response.sendredirect(url); 8: 9: 다음의예제와같이, 외부로연결할과 URL 도메인들은화이트리스트를작 성한후, 그중에서선택함으로써안전하지않은사이트로의접근을차단할수 있다. 안전한코드의예 JAVA 1: protected void doget(httpservletrequest request, HttpServletResponse response) 2: throws ServletException, IOException { 3: 4: // 다른페이지이동하는 URL 리스트를만든다. 5: String allowurl[] = { " " " ; 6: 7: // 입력받는은 url 미리정해진 URL의로 order 받는다. 8: 9: String nurl = request.getparameter("nurl"); 10: 11: try { 12: Integer n = Integer.parseInt(nurl); 53

54 13: if ( n >= 0 && n < 3) 14: response.sendredirect(allowurl[n]); 15: catch (NumberFormatException nfe) { 16: // 사용자입력값이숫자가아닐경우적절히에러를처리한다. 17: 18: 19: 라. 진단방법 외부사이트로리다이렉션하는함수나메소드(java의경우 response.sendredirect 메소드) 가존재하는지확인하고( ➀), 리다이렉션하는함 수나메소드의인자값이 (url) 외부입력값인지확인한다( ➁). 일반적으로외부에 서입력받는변수가아닌경우안전하다고판정한다. 외부에서입력받는변수 인경우, 다이렉션하는함수나메소드의인자값(url) 을관리하는지확인해서 유효값검사및화이트리스트로관리하는경우안전한것으로판정한다. public class U601 extends HttpServlet { protected void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { String query = request.getquerystring(); ➁ if (query.contains("url")) { String url = request.getparameter("url"); // url에대한유효성점검없이의 sendredirect 인자로사용 if( url!= null ) { url = url.replaceall("\r", "").replaceall("\n", ""); response.sendredirect(url); ➀ 외부입력값을이용하여 URL을이동하는 response.sendredirect(string url) 함수가사용된다면취약하다. 다음의예제에서 19, 20 라인에서 code, action을 request 에서받아온다. 이후 66번째라인에서페이지이동 URL에값code, action 을사용하여 URL을만든 54

55 다. M1 : redirect.jsp <% //redirect 19: String code = nvl(request.getattribute("redirectcode")); 20: String action = nvl(request.getattribute("action")); logger.debug(">>> redirectcode - " + code); logger.debug(">>> redirectaction - " + action);... 66: se.sendredirect(cp + action + "?redirectcode=" + code); return; %> 다음의예제에서 HttpRequest.getContextPath() 함수는내장함수로 context path를리턴하므로안전한 URL 이다. response.sendredirect(request.getcontextpath() + "/login.do"); 마. 참고문헌 [1] CWE-601 URL Redirection to Untrusted Site - [2] OWASP Top Ten 2010 Category A10 - Unvalidated Redirects and Forward [3] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Insecure Interaction Between Components, RANK 22 CWE-601 URL Redirection to Untrusted Site('Open Redirect') 55

56 7. XQuery 삽입 가. 개요 XQuery를사용하여 XML 데이터에대한동적쿼리문을생성할때사용하 는외부입력값에대해적절한검증절차가존재하지않으면공격자가쿼리문의 구조를임의로변경할수있게된다. 이로인해허가되지않은데이터를조회 하거나인증절차를우회할수있다. 나. 보안대책 XQuery 에사용되는외부입력데이터에대하여특수문자및쿼리예약어를 필터링하고, XQuery를사용한쿼리문은스트링을연결하는형태로구성하지 않고인자( 파라메터) 화된쿼리문을사용한다. 다. 코드예제 다음의예제에서는외부의입력(name) 값을 executequery 를사용한쿼리생성 의문자열인자생성에사용하고있다. 만일을 something' or '='1 name의값 으로전달하면다음과같은쿼리문을수행할수있으며, 이를통해파일내의 모든값을출력할수있게된다. (doc('users.xml')/userlist/user[uname='something' or '=') 안전하지않은코드의예 JAVA 1: 2: // 외부로부터입력을받음 3: String name = props.getproperty("name"); 4: Hashtable env = new Hashtable(); 5: env.put(context.initial_context_factory, "com.sun.jndi.ldap.ldapctxfactory"); 6: env.put(context.provider_url, "ldap://localhost:389/o=rootdir"); 7: javax.naming.directory.dircontext ctx = new InitialDirContext(env); 8: javax.xml.xquery.xqdatasource xqds = 56

57 9: (javax.xml.xquery.xqdatasource) ctx.lookup("xqj/personnel"); 10: javax.xml.xquery.xqconnection conn = xqds.getconnection(); 11: 12: String es = "doc('users.xml')/userlist/user[uname='" + name + "']"; 13: // 입력값이 Xquery 의인자로사용 14: XQPreparedExpression expr = conn.prepareexpression(es); 15: XQResultSequence result = expr.executequery(); 16: while (result.next()) { 17: String str = result.getatomicvalue(); 18: if (str.indexof('>') < 0) { 19: System.out.println(str); 20: 21: 다음의예제에서는외부입력값을받고해당값기반의 XQuery상의쿼리구 조를변경시키지않는 bindxxx 함수를이용함으로써외부의입력으로인하여 쿼리구조가바뀌는것을막을수있다. 안전한코드의예 JAVA 1: 2: // 외부로부터입력을받음 3: String name = props.getproperty("name"); 4: Hashtable env = new Hashtable(); 5: env.put(context.initial_context_factory, "com.sun.jndi.ldap.ldapctxfactory"); 6: env.put(context.provider_url, "ldap://localhost:389/o=rootdir"); 7: javax.naming.directory.dircontext ctx = new InitialDirContext(env); 8: javax.xml.xquery.xqdatasource xqds = 9: (javax.xml.xquery.xqdatasource) ctx.lookup("xqj/personnel"); 10: javax.xml.xquery.xqconnection conn = xqds.getconnection(); 11: 12: String es = "doc('users.xml')/userlist/user[uname='$xpathname']"; 13: // 입력값이 Xquery 의인자로사용 14: XQPreparedExpression expr = conn.prepareexpression(es); 15: expr.bindstring(new QName("xpathname"), name, null); 16: XQResultSequence result = expr.executequery(); 17: while (result.next()) { 18: String str = result.getatomicvalue(); 19: if (str.indexof('>') < 0) { 57

58 20: System.out.println(str); 21: 22: 라. 진단절차 XQuery 가실행되는부분을확인하고( ➀), XQuery 쿼리스트링에사용되는변 수가외부입력값여부를확인한후( ➁), 변수에대한필터링모듈이존재하는 지확인한다. 필터링모듈이존재하거나관련프레임워크에서적절한조치할 경우안전한것으로판정한다. // 외부로부터입력을받음 String name = props.getproperty("name"); ➁ Hashtable env = new Hashtable(); env.put(context.initial_context_factory, "com.sun.jndi.ldap.ldapctxfactory"); env.put(context.provider_url, "ldap://localhost:389/o=rootdir"); javax.naming.directory.dircontext ctx = new InitialDirContext(env); javax.xml.xquery.xqdatasource xqds = (javax.xml.xquery.xqdatasource) ctx.lookup("xqj/personnel"); javax.xml.xquery.xqconnection conn = xqds.getconnection(); String es = "doc('users.xml')/userlist/user[uname='" + name + "']"; // 입력값이의 Xquery 인자로사용 XQPreparedExpression expr = conn.prepareexpre ssion(es); XQResultSequence result = expr.executequery(); while (result.next()) {... String str = result.getatomicvalue(); if (str.indexof('>') < 0) { System.out.println(str); ➁ ➀ 다음의코드에서는외부의입력(name) 값을 executequery를사용한쿼리생성 의문자열인자생성에사용하고있다만. 일다음과 something' or '='1 을 name 의값으로전달하면다음과같은쿼리문을수행할수있으며, 이를통해 파일내의모든값을출력할수있게되어취약하다. (doc('users.xml')/userlist/user[uname='something' or '=') 58

59 1: 2: // 외부로부터입력을받음 3: String name = props.getproperty("name"); 4: Hashtable env = new Hashtable(); 5: env.put(context.initial_context_factory, "com.sun.jndi.ldap.ldapctxfactory"); 6: env.put(context.provider_url, "ldap://localhost:389/o=rootdir"); 7: javax.naming.directory.dircontext ctx = new InitialDirContext(env); 8: javax.xml.xquery.xqdatasource xqds = 9: (javax.xml.xquery.xqdatasource) ctx.lookup("xqj/personnel"); 10: javax.xml.xquery.xqconnection conn = xqds.getconnection(); 11: 12: String es = "doc('us ers.xml')/us erlist/user[uname='" + name + "']"; 13: // 입력값이 Xquery 의인자로사용 14: XQPreparedExpr essio n expr = conn.prepareexpression(es); 15: XQResultSequence result = expr.executequery(); 16: while (result.next()) { 17: String str = res ult.getatomicvalue(); 18: if (str.indexof('>') < 0) { 19: System.out.println(str); 20: 21: 마. 참고문헌 [1] CWE-652 XQuery injection - [2] OWASP Top A1 Injection Flaws 59

60 8. XPath 삽입 가. 개요 외부입력값을적절한검사과정없이쿼XPath 리문생성을위한문자열로 사용하면, 공격자는프로그래머가의도하지않았던문자열을전달하여쿼리문 의의미를왜곡시키거나그구조를변경하고임의의쿼리를실행하여인가되지 않은데이터를열람할수있다. < 그림삽입 3-6> XPath 나. 보안대책 Xpath 쿼리에사용되는외부입력데이터에대하여특수문자(", [, ], /, 등) 및쿼리예약어필터링을수행하고인자화된쿼리문을지원하는 XQuery를 사용한다. 다. 코드예제 name 의값으로 user1, passwd 의값으로 ' or ''=' 을전달하면다음과같 은쿼리문이생성되어인증과정을거치지않고로그인할수있다. 60

61 (//users/user[login/text()= user1' or ''='' and password/text() = or = ]/home_dir/text()) 안전하지않은코드의예 JAVA 1: 2: // 외부로부터입력을받음 3: String name = props.getproperty("name"); 4: String passwd = props.getproperty("password"); 5: 6: XPathFactory factory = XPathFactory.newInstance(); 7: XPath xpath = factory.newxpath(); 8: 9: // 외부입력이의 xpath 인자로사용 10: XPathExpression expr = xpath.compile("//users/user[login/text()='" + name 11: + "' and password/text() = '" + passwd + "']/home_dir/text()"); 12: Object result = expr.evaluate(doc, XPathConstants.NODESET); 13: NodeList nodes = (NodeList) result; 14: for (int i = 0; i < nodes.getlength(); i++) { 15: String value = nodes.item(i).getnodevalue(); 16: if (value.indexof(">") < 0) { 17: System.out.println(value); 18: 19: 인자화된쿼리문을지원하는를 XQuery 사용하여미리쿼리골격을생성하 고, 이에인자값을설정함으로써외부입력으로인해쿼리구조가바뀌는것을 막을수있다. 안전한코드의예 JAVA dologin.xp 파일 1: declare variable $loginid as xs:string external; 2: declare variable $password as xs:string external; 3: //users/user[@loginid=$loginid XQuery 를이용한 XPath Injection 방지 1: // 외부로부터입력을받음 2: String name = props.getproperty("name"); 3: String passwd = props.getproperty("password"); 61

62 4: Document doc = new Builder().build("users.xml"); 5: // XQuery 를위한정보로딩 6: XQuery xquery = new XQueryFactory().createXQuery(new File("dologin.xq")); 7: Map vars = new HashMap(); 8: vars.put("loginid", name); 9: vars.put("password", passwd); 10: Nodes results = xquery.execute(doc, null, vars).tonodes(); 11: for (int i=0; i < results.size(); i++) { 12: System.out.println(results.get(i).toXML()); 13: 라. 진단방법 xpath 객체를통해쿼리스트링이컴파일되는부분을확인하고( ➀), xpath 쿼리스트링에사용되는변수가외부입력값인지확인한후( ➁) 변수에대한 필터링모듈이존재하는지확인한다. 필터링모듈이존재하거나관련프레임워 크에서적절하게조치된경우엔안전하다고판정한다.... String acctid = request.getparameter("acctid"); ➁ String query = null; if(acctid!= null) { StringBuffer sb = new StringBuffer("/accounts/account[acctID='"); sb.append(acctid); ➁ sb.append("']/ /text()"); query = sb.tostring(); DocumentBuilderFac tory domfactory = DocumentBuilderFactory.newInstance(); domfactory.setnamespaceaware(true); DocumentBuilder builder = domfactory.newdocumentbuilder(); Document doc = builder.parse("accounts.xml"); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newxpath(); XPathExpression expr = xpath.compile(query); ➀ Object result = expr.evaluate(doc, XPathConstants.NODESET);... 다음의예제에서는 name 의값으로의 user1, passwd 값으로 ' or ''=' 을전달하면다음과같은쿼리문이생성되어인증과정을거치지않고로 62

63 그인할수있어취약하다고판정한다. (//users/user[login/text()= user1' or ''='' and password/text() = or = ]/home_dir/text()) 1: 2: // 외부로부터입력을받음 3: String name = props.getproperty("name"); 4: String passwd = props.getproperty("password"); 5: 6: XPathFactory factory = XPathFactory.newInstance(); 7: XPath xpath = factory.newxpath(); 8: 9: // 외부입력이의 xpath 인자로사용 10: XPathExpression expr = xpath.compile("//users/user[login/text()='" + name 11: + "' and password/text() = '" + passwd + "']/home_dir/text()"); 12: Object r esult = expr.evaluate(doc, XPathConstants.NODESET); 13: NodeList nodes = (NodeList) result; 14: for (int i = 0; i < nodes.getlength(); i++) { 15: String value = nodes.item(i).getnod evalue(); 16: if (value.indexof(">") < 0) { 17: System.out.println(value); 18: 19: 마. 참고문헌 [1] CWE-643 XPath Injection - [2] OWASP Top A1 Injection Flaws [3] Web Application Security Consortium. "XPath Injection" 63

64 9. LDAP 삽입 가. 개요 공격자가외부입력을통해서의도하지않은 LDAP 명령어를수행할수있 다. 즉, 웹애플리케이션이사용자가제공한입력을올바르게처리하지못하면, 공격자가 LDAP 명령문의구성을바꿀수있다. 이로인해프로세스가명령을 실행한컴포넌트와동일한권한(authentication) 을가지고동작하게된다. LDAP 쿼리문이나결과로외부입력이부분적으로적절한처리없이사용되 면, LDAP 쿼리문이실행될때공격자는 LDAP 쿼리문의내용을마음대로변 경할수있다. < 그림삽입 3-7>LDAP 나. 보안대책 DN 과필터에사용되는사용자입력값에는특수문자가포함되지않도록특 수문자를제거한다. 특수문자를사용해야하는경우특수문자(DN 에사용되는 64

65 특수문자는 \, 필터에사용되는특수문자(=, +, <, >, #, ; \ 등) 에대해서는 실행명령이아닌일반문자로인식되도록처리한다. 다. 코드예제 name 변수의값으로을 "*" 전달할경우필터문자열은 "(name=*)" 가되어항 상참이되며이는의도하지않은동작을유발시킬수있다. 안전하지않은코드의예 JAVA 1: Properties props = new Properties(); 2: String filename = "ldap.properties"; 3: FileInputStream in = new FileInputStream(fileName); 4: props.load(in); 5: String name = props.getproperty("name"); 6: String filter = "(name =" + name + ")"; 7: NamingEnumeration answer = ctx.search("ou=newhires", filter, new SearchControls()); 8: printsearchenumeration(answer); 9: ctx.close(); 검색을위한필터문자열로사용되는외부의입력에서위험한문자열을제거 하여위험성을부분적으로감소시킬수있다. 안전한코드의예 JAVA 1: Properties props = new Properties(); 2: String filename = "ldap.properties"; 3: FileInputStream in = new FileInputStream(fileName); 4: if (in == null in.available() <= 0) return; 5: props.load(in); 6: if (props == null props.isempty()) return; 7: String name = props.getproperty("name"); 8: if (name == null "".equals(name)) return; 9: String filter = "(name =" + name.replaceall("\\*", "") + ")"; 10: NamingEnumeration answer = 11: ctx.search("ou=newhires", filter, new SearchControls()); 12: printsearchenumeration(answer); 13: ctx.close(); 65

66 라. 진단방법 LDAP 조회쿼리가실행됨을확인하고( ➀), LDAP 조회문의필터에사용되는 변수가외부입력값인지확인한후( ➁), 해당변수에대한필터링모듈이존재 하는지확인한다( ➂). 필터링모듈이존재하거나관련프레임워크에서적절히 조치할경우엔안전한것으로판정한다.... DirContext ctx = new InitialDirContext(env); String managername = request.getparameter("managername"); ➂ //retrieve all of the employees who report to a manager String filter = "(manager=" + managername + ")"; ➁ NamingEnumeration employees = ctx.search("ou=people,dc=example,dc=com", filter); -- ➀... 다음의예제에서는외부의입력(name) 이검색을위한필터문자열의생성에 사용되고있다변. name 수의값으로 "*" 을전달할경우, 필터문자열은 "(name=*)" 가할당되어항상참이되므로, 인증을우회하거나 SW가의도하지 않은동작을하게되므로취약한것으로판정한다. 1: 2: public void f() { 3: Hashtable env = new Hashtable(); 4: env.put(context.initial_context_factory, "com.sun.jndi.ldap.ldapctxfactory"); 5: env.put(context.provider_url, "ldap://localhost:389/o=rootdir"); 6: try { 7: javax.naming.directory.dircontext ctx = new InitialDirContext(env); 8: // 프로퍼티를만들고외부파일을로드한다. 9: Properties props = new Properties(); 10: String filename = "ldap.prop erties"; 11: FileInp utstream in = new FileInp utstream(filename); 12: props.load(in); 13: // LDAP Search 를하기위해을 name 읽는다 14: String name = props.getprop erty("name"); 66

67 15: String filter = "(name =" + name + ")"; 16: // LDAP search가값에 name 대한여과없이그대로통과되어검색이되어진다. 17: NamingEnumeration answer = ctx.search("ou=newhires", filter, new SearchControls()); 18: printsearchenumeration(answer); 19: ctx.close(); 20: catch (NamingException e) { 21: 외부의입력(name) 이검색을위한 base 문자열의생성에사용되고있다. 이 경우임의의루트디렉터리를지정하여정보에접근할수있으며, 적절한접근 제어가동반되지않을경우정보누출이발생할수있다. 1: 2: try { 3: 4: // 외부로부터입력을받는다. 5: String name = props.getproperty( ldap.properties"); 6: // 입력값에대한를 BasicAttribute 생성한다. 7: BasicAttribute attr = new BasicAttribute("name", name); 8: // 외부입력값이의 LDAP search 인자로사용이된다. 9: NamingEnumeration answer = 10: ctx.search("ou=newhires", attr.getid(), new SearchControls()); 11: printsearchenumeration(answer); 12: ctx.close(); 13: catch (NamingException e) { 14: 15: 16: public void printsearchenumeration(nami ngenumeration val ue) { 67

68 17: try { 18: while (value.hasmore()) { 19: SearchResult sr = (SearchResult) val ue.next(); 20: System.out.println(">>>" + sr.getname() + "\n" + sr.getattributes()); 21: 22: catch (NamingException e) { 23: 마. 참고문헌 [1] CWE-90 LDAP Injection - [2] OWASP Top A1 Injection Flaws [3] SPI Dynamics. "Web Applications and LDAP Injection" [4] SANS Top (SANS 2009) Insecure Interaction - CWE ID 116 Improper Encoding or Escaping of Output 68

69 10. 크로스사이트요청위조 가. 개요 특정웹사이트에대해서사용자가인지하지못한상황에서사용자의의도와 는무관하게공격자가의도한행위( 수정, 삭제, 등록등 ) 를요청하게하는공격을말 한다. 웹어플리케이션이사용자로부터받은요청에대해서사용자가의도한 대로작성되고전송된것인지확인하지않는경우발생가능하고특히해당사 용자가관리자인경우사용자권한관리, 게시물삭제, 사용자등록등관리자권 한으로만수행가능한기능을공격자의의도대로실행시킬수있게된다. 공격자는사용자가인증한세션이특정동작을수행하여도계속유지되어정 상적인요청과비정상적인요청을구분하지못하는점을악용하여피해가발생한다. 웹응용프로그램에요청을전달할경우, 해당요청의적법성을입증하기위하여 전달되는값이고정되어있고이러한자료가 GET 방식으로전달된다면공격자 가이를쉽게알아내어원하는요청을보냄으로써위험한작업을요청할수있 게된다. < 그림 3-8> 크로스사이트요청위조 나. 보안대책 입력화면폼작성시 GET 방식보다는 POST 방식을사용하고입력화면폼과 69

70 해당입력을처리하는프로그램사이에토큰을사용하여, 공격자의직접적인 URL 사용이동작하지않도록처리한다. 특히중요한기능에대해서는사용자 세션검증과더불어재인증을유도한다. 라. 코드예제 GET방식은단순히 form 데이터를 URL 뒤에덧붙여서전송하기때문에 GET 방식의 form을사용하면전달값이노출되므로 CSRF 공격에쉽게노출 될수있다. 안전하지않은코드의예 JAVA 1: 2: <form name="myform" method="get" action="customer.do"> 3: <input type=text name="txt1"> 4: <input type=submit value=" 보내기"> 5: </form> 6: Post 방식을사용하여위협을최소화한다. 안전한코드의예 JAVA 1: 2: <form name="myform" method="post" action="customer.do"> 3: <input type=text name="txt1"> 4: <input type=submit value=" 보내기"> 5: </form> 6: 라. 진단방법 사용자권한변경, 신규정보등록등주요기능을확인하고( ➀), 해당기능 수행시권한확인절차존재여부확인한다( ➁). 권한확인절차가없거나권한확 인방법이세션쿠키, 사용자 IP, SSL 인증과같이자동제출되는자격증명에 의존하는경우취약하다. 70

71 ... try { int level = request.getparameter("level"); int group = request.getparameter("group"); String id = request.getparameter("id"); ➁ String sql="update member set level=?, group=? where id=?;"; pstmt =con.preparestatement(sql); pstmt.setint(1, level); pstmt.setstring(2, group); pstmt.setint(3, id); pstmt.executeupdate();-- ➀ catch (Exception e) { e.printstacktrace(); finally { if ( con!= null ) try { con.close(); catch (SQLException se) {/* 처리*/ if ( pstmt!= null ) try { cpstmt.close(); catch (SQLException se2) {/* 처리*/ GET방식은단순히 form 데이터를 URL 뒤에덧붙여서전송하기때문에 GET 방식의 form을사용하면전달값이노출되므로 CSRF 공격에쉽게노출 될수있다. 1: 2: <form name="myform" method="get" action="customer.do"> 3: <input type=text name="txt1"> 4: <input type=submit value=" 보내기"> 5: </form> 6: 마. 참고문헌 [1] CWE-352 CSRF - [2] OWASP Top Ten 2010 Category A5 - Cross-Site Request Forgery(CSRF) [3] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Insecure 71

72 Interaction Between Components, RANK 12 CWE-352 Cross-Site Request Forgery(CSRF) 72

73 11. 디렉토리경로조작 가. 개요 외부의입력을통하여 디렉터리경로문자열 생성이필요한경우, 외부입 력값에대해경로조작에사용될수있는문자를필터링하지않으면, 예상밖 의접근제한영역에대한경로문자열구성이가능해져시스템정보누출, 서 비스장애등을유발시킬수있다. 즉, 경로조작을통해서공격자가허용되지않은권한을획득하여, 설정에관 계된파일을변경할수있거나실행시킬수있다. < 그림디3-9> 렉토리경로조작 나. 보안대책 파일경로와이름을생성할때외부입력값을사용하는경우, 정해진경로이 외의디렉토리와파일에접근할수없도록처리하고외부입력값에대해 replaceall() 등의메소드를사용하여예상밖의경로로의접근을허용하는위 험문자열(",/,\,..) 을제거하는필터링을수행한다. 다. 코드예제 외부의입력 (name) 이삭제할파일의경로설정에사용되고있다만. 일공격자 73

74 에의해 name 의값으로../../../rootFile.txt와같은값을전달하면의도하지않 았던파일이삭제되어시스템에악영향을준다. 안전하지않은코드의예 JAVA 1: 2: public void f(properties request) { 3: 4: String name = request.getproperty("filename"); 5: if( name!= null ) { 6: File file = new File("/usr/local/tmp/" + name); 7: file.delete(); 8: 9: 10: 외부에서입력되는값에대하여 Null 여부를체크하고, 외부에서입력되는파 일이름 (name) 에서상대경로(/, \\, &,. 등특수문자) 를설정할수없도록 replaceall 을이용하여특수문자를제거한다. 안전한코드의예 JAVA 1: 2: public void f(properties request) { 3: 4: String name = request.getproperty("user"); 5: if ( name!= null &&!"".equals(name) ) { 6: name = name.replaceall("/", ""); 7: name = name.replaceall("\\", ""); 8: name = name.replaceall(".", ""); 9: name = name.replaceall("&", ""); 10: name = name + "-report"; 11: File file = new File("/usr/local/tmp/" + name); 12: if (file!= null) file.delete(); 13: 14: 15: 라. 진단방법 74

75 디렉토리경로를사용하여파일을생성확인하고( ➀), 파일경로구성시외부 입력값을사용하는지확인한후( ➁) 외부입력값에대한필터링또는검증절차 가있는지확인한다( ➂). 외부입력값에대한필터링절차가없다면취약하다.... MultipartHttpServle tre quest mrequest = (MultipartHttpServletRequest) request; MultipartFile multifile = mrequest.getfile("uploadfile"); String tmpfilename = multifile.getoriginalfilename(); ➂ String startfilename = "/download/" ; if( multifile!= null ) { in putstream = multifile.getinputstream(); String filepath = startfilename + tmpfilename; outputstream = new FileOutputStream(filePath); ➁ ➀ int readbytes = 0; byte[] buffer = new byte[8192]; while((readbytes = inputstream.read(buffer, 0, 8192))!= -1) { outputstream. write(buffer, 0, readbytes); outputstream.close(); in putstream.close();... 마. 참고문헌 [1] CWE-23 Relative Path Traversal - [2] OWASP Top A4 Inseccure Direct Object Reference [3] Security Technical Implementation Guide Version 2 - (STIG 2) APP3510 CAT I, APP3600 CAT II [4] SANS Top (SANS 2009) Risky Resource Management - CWE ID

76 12. HTTP 응답분할 가. 개요 HTTP 요청에들어있는인자값이 HTTP 응답헤더에포함되어사용자에게 다시전달될때입력값에 CR(Carriage Return) 이나와 LF(Line Feed) 같은개 행문자가존재하면 HTTP 응답이개 2 이상으로분리될수있다. 이경우공격 자는개행문자를이용하여첫번째응답을종료시키고두번째응답에악의적 인코드를주입하여및 XSS 캐시훼손(cache poisoning) 공격등을수행할수 있다. < 그림응3-10> HTTP 답분할 나. 보안대책 외부에서입력된인자값을응HTTP 답헤더(Set Cookie 등) 에포함시킬경우 CR, LF 등의개행문자를제거한다. 다. 코드예제 외부의입력값을사용하여반환되는쿠키의값을설정하고있다. 그런데, 공 격자가 "Wiley Hacker\r\nHTTP/ OK\r\n" 를 authorname 의값으로설 정할경우, 예와같이의도하지않은두개의페이지가전달되며, 두번째응답 76

77 페이지는공격자가마음대로수정가능하다. 안전하지않은코드의예 JAVA 1: throws IOException, ServletException { 2: response.setcontenttype("text/html"); 3: String author = request.getparameter("authorname"); 4: Cookie cookie = new Cookie("replidedAuthor", author); 5: cookie.setmaxage(1000); 6: response.addcookie(cookie); 7: RequestDispatcher frd = request.getrequestdispatcher("cookietest.jsp"); 8: frd.forward(request, response); 9: 10: 외부에서입력되는값에대하여 Null 여부를체크하고, 헤더값이두개로나누 어지는것을방지하기위해 replaceall 을이용하여개행문자(\r, \n) 를제거한 다. 안전한코드의예 JAVA 1: throws IOException, ServletException { 2: response.setcontenttype("text/html"); 3: String author = request.getparameter("authorname"); 4: if (author == null "".equals(author)) return; 5: String filtered_author = author.replaceall("\r", "").replaceall("\n", ""); 6: Cookie cookie = new Cookie("replidedAuthor", filtered_author); 7: cookie.setmaxage(1000); 8: cookie.setsecure(true); 9: response.addcookie(cookie); 10: RequestDispatcher frd = request.getrequestdispatcher("cookietest.jsp"); 11: frd.forward(request, response); 12: 13: 라. 진단방법 Response 헤더에변수가사용되는것을확인하고변 ( ➀), 수가외부입력값인 지확인한후( ➁), 개행문자(\r, \n) 제거를위한필터링또는검증절차가있는 지확인한다. 외부입력값에대한필터링절차가없다면취약하다. 77

78 protected void common(httpservletrequest request, HttpServletResponse response) throws Exception { String fileid = request.getparameter("fileid"); ➁ BufferedInputStream in = null; String uploadpath = properties.getstring(propertyname + "UPLOAD"); try { String filename = uploadpath + "/" + fileid; response.setcontenttype(mimetype + ";charset=utf-8"); String filename = java.net.urlencoder.encode(fileid, "UTF-8"); response.setheader("content-disposition", "attachment; filename=\"" + filename + "\""); ➀ response.setheader("content-transfer-encoding", "binary"); response.getoutputstream().flush(); response.getoutputstream().close(); catch(exception e) { if(in!=null) { in.close(); finally { HTTP 응답분할은공격자보낸조작된입력값이헤더에쓰이고이로인해 HTTP 응답이나누어지게되는취약점이다. response.sendredirect 함수는 URL 을다른곳으로보내는함수인데그방식은헤더에서상태값을로 301 바꾸고 가고자하는 URL 을헤더에입력하는것이다. 이때 url에공격자의입력값이 쓰이게되면조작된입력값으로인해응답이변경된다. 다음의예제를살펴보면, 25번째라인에서 request의파라미터에서 filename 값을가져오고번27 째라인에서값filename 을이용하여헤더에값을설정하고 있어취약하다. L1 : DownloadServlet.java 78

79 public voidservice(httpservletrequest request, HttpServletResponse res) throws ServletException, IOException { String contextrealpath = request.getsession().getservletcontext().getrealpath("/"); String savepath = contextrealpath + "upfolder" res.setcontenttype("utf-8"); 25: String filename = request.getparameter("file"); res.setcontenttype("application/octet;charset=utf-8"); 27: res.setheader("content-disposition", "attachment;filename=" + filename); HttpRequest.getContextPath() 함수는내장함수로 context path를리턴하므 로 HTTP 응답분할이이루어지지않는다. response.sendredirect(request.getcontextpath() + "/login.do"); Long, Integer 값등값Numeric 은문자열로치환했을때 \r\n 등의문자열 이포함될수없으므로취약하지않다. response.setheader("content-length",long.tostring(file.length())); 마. 참고문헌 [1] CWE-113 HTTP Response Splitting - [2] OWASP Top A1 Unvalidated Input [3] OWASP Top A2 Injection Flaws [4] Web Application Security Consortium HTTP Response Splitting 79

80 13. 정수오버플로우 가. 개요 정수형변수의오버플로우는정수값이증가하면서, Java에서허용된가장큰 값보다더커져서실제저장되는값은의도하지않게아주작은수이거나음수 가될수있다. 특히반복문제어, 메모리할당, 메모리복사등을위한조건으 로사용자가제공하는입력값을사용하고그과정에서정수오버플로우가발생 하는경우보안상문제를유발할수있다. 나. 보안대책 언어/ 플래폼별정수타입의범위를확인하여사용한다. 정수형변수를연산 에사용하는경우결과값이범위체크하는모듈을사용한다. 특히외부입력값 을동적으로할당하여사용하는경우변수의값범위를검사하여적절한범위 내에존재하는값인지확인한다. 다. 코드예제 다음의예제는외부의입력 (args[0], args[1] ) 을이용하여동적으로계산한값 을배열의크기 (size) 를결정하는데사용하고있다만. 일외부입력으로부터계 산된값 (size) 이오버플로우에의해음수값이되면배열의크기가음수가되어 코드시스템에문제가발생할수있다. 안전하지않은코드의예 JAVA 1: 2: public static void main(string[] args) { 3: int size = new Integer(args[0]).intValue(); 4: size += new Integer(args[1]).intValue(); 5: MyClass[] data = new MyClass[size]; 6: 7: 80

81 동적메모리할당을위해크기를사용하는경우그값이음수가아닌지검사 하는작업이필요하다. 안전한코드의예 JAVA 1: 2: public static void main(string[] args) { 3: int size = new Integer(args[0]).intValue(); 4: size += new Integer(args[1]).intValue(); 5: // 배열의크기값이음수값이아닌지검사한다. 6: if (size < 0) return ; 7: MyClass[ ] data = new MyClass[size]; 8: 라. 진단방법 변수를사용하여배열의크기를동적으로결정하고있는경우변( ➀), 수가외 부입력값인지확인하고 (➁), 해당변수가의도한범위내에존재하는지확인하는 절차가있는지확인한다. 외부입력값에대한검증절차가없다면취약하다.... String cnt = request.getparameter("cnt"); ➁ if( cnt == null ){ cnt = "0"; int cnti = Integer.parseInt(cnt); String[] arr = new String[cntI]; ➀ for( int i = 0 ; i <cnti ; i++ ){ arr[i] = request.getparameter("r"+i);... 정수형변수의값이증가하면서정수형한계값보다더커지는경우아주작 은값이되거나음수가될수있다. 이러한상황에대한검사가이루어지지않 고진행하는경우취약하다. W2 : EgovFileTool.java 81

82 public static Vector parsfilebysize(string parfile, int[] parlen, int parline) throws Exception { // 파싱결과구조체 Vector parresult = new Vector(); // 파일오픈 String parfile1 = parfile.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR); File file = new File(parFile1); BufferedReader br = null; try { // 파일이며, 존재하면파싱시작 if (file.exists() && file.isfile()) { // 1. 입력된라인수만큼파일텍스트내용을읽어서 String[] 에쌓는다. br = new BufferedReader(new InputStreamReader(new FileInputStream(file))); String [] strarr = new String [parline]; String line = ""; int readcnt = 0; while ((line = br.readline())!= null && readc nt < parline) { if (line.length() <= MAX_STR_LEN) strarr[readcnt++] = line; 다음의예제에서 pubkey.available() 함수는 int 값을리턴한다. 그러므로정 수값한계를벗어난값은발생하지않는다. try { URL url = Util.class.getClassLoader() pubkey = url.openstream(); catch (MalformedURLException e) {.getresource(publickeyfilepath); pubkey = new FileInputStream(publicKeyFilepath); 82

83 byte[] bytes = new byte[pubkey.available()]; 다음의예제에서입력값은 초과할가능성이없다. HTTP 헤더의한계값이있으므로정수의한계를 String[] referer_split = Util.split(request.getHeader("Referer").toString(),"/"); String refer ervalue = referer_split[referer_split.length-1]; 다음의예제에서아규먼트의개수가정수의한계이상으로입력된다는것은 실현가능성이희박하므로취약하지않은것으로판단한다. public static void main(string[] args) { String[] jsargs = {"-j="+args[0]; String[] allargs = new String[jsargs.length + args.length]; 사용자입력값등외부값이아닌경우취약하지않다. 마. 참고문헌 [1] CWE-190 Integer Overflow - [2] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Risky Resource Management, RANK 24 CWE-190 Integer Overflow or Wraparound 83

84 14. 보호메커니즘을우회할수있는입력값변조 가. 개요 소프트웨어가외부입력값에대한신뢰를전제로보호메커니즘을사용하는경 우공격자가입력값을조작할수있다면보호메커니즘을우회할수있게된다. 개발자들이흔히쿠키, 환경변수또는히든필드와같은입력값이조작될수 없다고가정하지만공격자는다양한방법을통해이러한입력값들을변경할수 있고조작된내용은탐지되지않을수있다. 인증이나인가와같은보안결정이 이런입력값( 쿠키, 환경변수, 히든필드등 ) 에기반해수행되는경우공격자는이런입 력값을조작하여소프트웨어의보안을우회할수있으므로충분한암호화무, 결성체크또는다른메커니즘이없는경우외부사용자에의한입력값을신뢰해 서는안된다. 나. 보안대책 상태정보나민감한데이터특히사용자세션정보와같은중요한정보는서버 에저장하고보안확인절차도서버에서실행한다. 보안설계관점에서신뢰할수 없는입력값이어플리케이션내부로들어올수있는지점과보안결정에사용되 는입력값을식별하고제공되는입력값에의존할필요가없는구조로변경할 수있는지검토한다. 다. 코드예제 사용자의을 role 설정할때사용자웹브라우저의쿠키의에 role 할당된값을 사용하고있어이값이사용자에의해변경되는경우사용자값role 이의도하 지않은값으로할당될수있다. 안전하지않은코드의예 JAVA 1: Cookie[] cookies = request.getcookies(); 2: for (int i =0; i< cookies.length; i++) { 84

85 3: Cookie c = cookies[i]; 4: if (c.getname().equals("role")) { 5: userrole = c.getvalue(); 6: 7: 사용자권한, 인증여부등보안결정에사용하는값은사용자입력값을사용 하지않고내부세션값을활용한다. 안전한코드의예 JAVA 1:... 2: HttpSession session = context.getsession(id) ; 3: String userrole = (Stirng)session.getValue("role") ; 4:... 라. 진단방법 인증여부를확인하기위해사용하는변수를확인하고변( ➀), 수가세션정보 등서버내부에서검증된값인지확인한다( ➁). 인증결정의기준으로외부입력값 을그대로사용하는경우취약하다.... Cookie[] cookies = request.getcookies() ; ➁ for(int i=0 ; i<cookies.length ; i++){ Cookie c = cookies[i] ; if(c.getname().equals("authecticated")&&boolean.true.equals(c.getvalue())){ --- ➀ authenticated = true ;... 다음의예제에서는평문으로사용자의인증정보및 authenticated 를쿠키 에저장하고있다. 공격자는쿠키정보를변경가능하기때문에중요한정보를 쿠키에저장시에는암호화해서사용하고, 가급적해당정보는 WAS(Web Application Server) 서버의세션에저장한다. 85

86 1: <% 2: String username = request.getparameter("username"); 3: String password = request.getparameter("password"); 4: if (username==nill password==null!isauthenticateduser(usename, password)) { 5: throw new MyException(" 인증에러 "); 6: 7: Cookie usercookie = new Cookie("user",username); 8: Cookie authcookie = new Cookie("authenticated","1"); 9: 10: respons e.addcookie(usercookie); 11: respons e.addcookie(authcookie); 12: %> 마. 참고문헌 [1] CWE-807 Reliance on Untrusted Inputs in a Security Decision

87 제2절보안기능 보안기능( 인증, 접근제어, 기밀성, 암호화, 권한관리등) 을부적절하게구현 시발생할수있는취약점 1. 적절한인증없이중요기능을허용 가. 개요 적절한인증과정이없이중요정보( 계좌이체정보, 개인정보등 ) 를열람또는변경 때발생하는취약점이다. ( ) 할 나. 보안대책 클라이언트의보안검사를우회하여서버에접근하지못하도록설계하고중요 한정보가있는페이지는재인증을적용( 은행계좌이체등 ) 한다. 또한안전하다고 확인된라이브러리나프레임워크(OpenSSL이나 ESAPI 의보안기능등) 를사용 하는것이중요하다. 다. 코드예제 재인증을거치지않고계좌이체를하고있다. 안전하지않은코드의예 JAVA 1: public void sendbankaccount(string accountnumber,double balance) { 2:... 3: BankAccount account = new BankAccount(); 4: account.setaccountnumber(accountnumber); 5: account.settoperson(toperson); 6: account.setbalance(balance); 7: AccountManager.send(account); 8:... 9: 87

88 인증을수행된사용자만이재인증을거쳐계좌이체가가능하도록한다. 안전한코드의예 JAVA 1: public void sendbankaccount(httpservletrequest request, HttpSession session, 2: String accountnumber,double balance) { 3:... 4: // 재인증을위한팝업화면을통해사용자의 credential 을받는다. 5: String newusername = request.getparameter("username"); 6: String newpassword = request.getparameter("password"); 7: if ( newusername == null newpassword == null ) { 8: throw new MyEception(" 데이터오류:); 9: 10: 11: // 세션으로부터로긴한사용자의 credential 을읽는다. 12: String password = session.getvalue("password"); 13: String username = session.getvalue("username"); 14: 15: // 재인증을통해서이체여부를판단한다. 16: if ( isauthenticateduser() && newusername.equal(username) && 17: newpassword.equal(password) ) { 18: BankAccount account = new BankAccount(); 19: account.setaccountnumber(accountnumber); 20: account.settoperson(toperson); 21: account.setbalance(balance); 22: AccountManager.send(account); 23: 24:... 25: 라. 진단방법 해당취약점은보안특성중개인정보와관련된취약점으로정적도구를사용 하여이를판단하는것은어려움. 이에따라진단원이직접코드를보며해당 정보가중요정보인지파악해야한다. 패스워드, 개인정보주민등록번호여권번호외국인식별번호등 (,, ), 금융정보 ( 카드번호, 계좌 정보등 ) 등을포함하여접근및사용이제한되어야하는중요정보및기능을 정의하였는지확인하고 ( ➀), 접근및사용이제한되어야하는중요정보및기능 의사용여부를확인한다. 중요정보를사용하는경우접근변경시적절한인증 88

89 여부를확인하여허용하는기능이구현되었는지확인( ➁) 한다만. 약적절한인 증여부를확인하는경우안전하다고판단하고, 인증여부를확인하지않는경우 취약하다고판단한다. public BankAccount createbankaccount(string accountnumber, String accounttype, String accountname, String accountssn, double balance) { BankAccount account = new BankAccount(); ➀ account.setaccountnumber(accountnumber); account.setaccounttype(accounttype); account.setaccountownername(accountname); account.setaccountownerssn(accountssn); account.setbalance(balance); return account; public boolean authenticateuser(string username, String password) {... // createbankaccount 를사용 ➁... 다음의예제에서는재인증을거치지않고계좌이체를하고있으므로취약하 다고판정한다. 1: public void sendbankaccount(string accountnumber,double balance) { 2:... 3: BankAccount account = new BankAccount(); 4: account.setaccountnumber(accountnumber); 5: account.settoperson(toperson); 6: account.setbalance(balance); 7: AccountManager.send(account); 8:... 9: 89

90 마. 참고문헌 [1] CWE-306 Missing Authentication for Critical Function - [2] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Porous Defenses, RANK 5 CWE-306 Missing Authentication for Critical Function 90

91 2. 부적절한인가 가. 개요 프로그램이모든가능한실행경로에대해서접근제어를검사하지않거나불 완전하게검사하는경우, 공격자는접근가능한실행경로를통해정보를유출 할수있다. < 그림 3-11> 부적적한인가 나. 보안대책 응용프로그램이제공하는정보와기능을역할에따라배분함으로써공격자에 게노출되는공격대상 ( 10) attack surface) 을최소화하고사용자의권한에따른 ACL(Access Control List) 을관리한다. 프레임워크를사용해서취약점을피할 수도있는데예를들면, JAAS uthorization Framework나 OWASP ESAPI Access Control 등이인증프레임워크로사용가능하다. 다. 코드예제 사용자인증이성공적으로끝나면, 어떤 LDAP 검색도가능하다. 또한사용 10) OSSTMM 3 Defines Attack Surface as "The lack of specific separations and functional controls that exist for that vector" 91

92 자의로그인정보와인자로넘겨오는 username 의비교가없기때문에타인의 정보를볼수가있다. 안전하지않은코드의예 C 1: #define FIND_DN "uid=han,ou=staff,dc=example,dc=com" 2: 3: int searchdata2ldap(ldap *ld, char *username) { 4: unsigned long rc; 5: char filter[20]; 6: LDAPMessage *result; 7: snprintf(filter, sizeof(filter), "(name=%s)", username); 8: rc = ldap_search_ext_s(ld, FIND_DN, LDAP_SCOPE_BASE, filter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result); 9: 10: return rc; 11: LDAP 검색전에 username 을인증하고, username 이로그인정보와일치하는지 점검한다. 안전한코드의예 C 1: if ( ldap_simple_bind_s(ld, username, password)!= LDAP_SUCCESS ) { 2: printf(" 인증에러 ); 3: return(fail); 4: 5: if ( strcmp(username,getloginname())!= 0 ) { 6: printf(" 인증에러 ); 7: return(fail); 8: 9: snprintf(filter, sizeof(filter), "(name=%s)", username); 10: rc = ldap_search_ext_s(ld, FIND_DN, LDAP_SCOPE_BASE, filter, NULL, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result); 라. 진단방법 해당취약점은보안특성중외부시스템( 웹서버, DB 서버, LADP 등) 의권한설정과 관련된취약점으로정적도구를사용하여이를판단하는것은쉽지않다. 92

93 먼저중요정보를저장할수있는외부시스템이존재하는지식별하고해당시스템에접근( 열람) 및변경 ( 생성 삭제 수정등 ) 에대한권한을사전에적절하게정의하였는지확인한다. 해당정보또는기능 ( 접근변경 ) 을호출하는함수에서, 사전에정의한권한소유여부를검사하는지확인( ➀) 한다. public void f(string ssingleid, int iflag, String sserviceprovider, String suid, String spwd) { env.put(context.initial_context_factory, CommonMySingleConst.INITCTX); env.put(context.provider_url, sserviceprovider); // 익명으로인증을 LDAP 사용 env.put(context.security_authentication, "none"); env.put(context.security_principal, suid); env.put(context.security_credentials, spwd); ➀ 외부의입력인값name 이필터가아닌동적인쿼LDAP 리문에서사용자명 으로사용되었으며, 사용자인증을위한별도의접근제어방법이사용되지않 고있다. 이는 anonymous binding 을허용하는것으로볼수있다. 따라서임 의사용자의정보를외부에서접근할수있게된다. 1: public void f(string ssingleid, int iflag, String sserviceprovider, String suid, String spwd) { 2: 3: env.put(context.initial_context_factory, CommonMySingleConst.INITCTX); 4: env.put(context.provider_url, sserviceprovider); 5: // 익명으로 LDAP 인증을사용 6: env.put(context.security_authentication, "none"); 7: env.put(context.security_principal, suid); 8: env.put(context.security_credentials, spwd); 9: 마. 참고문헌 93

94 [1] CWE-285 Improper Authorization - [2] OWASP Top (OWASP 2010) A8 Failure to Restrict URL Access [3] SANS Top (SANS 2010) Porus Defense - CWE ID 285 Improper Authorization [4] NIST. "Role Based Access Control and Role Based Security" [5] M. Howard and D. LeBlanc. "Writing Secure Code". Chapter 4, "Authorization" Page 114; Chapter 6, "Determining Appropriate Access Control" Page nd Edition. Microsoft

95 3. 중요한자원에대한잘못된권한설정 가. 개요 SW가중요한보안관련자원에대하여읽기또는수정하기권한을의도하지않게허가할경우, 권한을갖지않은사용자가해당자원을사용하게된다. 나. 보안대책 설정파일, 실행파일, 라이브러리등은 SW 관리자에의해서만읽고쓰기가가 능하도록설정하고설정파일과같이중요한자원을사용하는경우허가, 받지 않은사용자가중요한자원에접근가능한지검사한다. 다. 코드예제 파일생성시가장많은권한을허가하는형태로 umask를사용하고있어, 모든 사용자가읽기/ 쓰기권한을갖게된다. 안전하지않은코드의예 C 1: // 파일권한디: rw-rw-rw-, 렉터리권한 : rwxrwxrwx 2: umask(0); 3: FILE *out = fopen("important_file", "w"); 4: if (out) { 5: fprintf(out, " 민감한정보 6: fclose(out); 7: \n"); 파일에대한설정을가장제한이많도록, 즉사용자를제외하고는읽고쓰기 가가능하지않도록 umask 를설정하는것이필요하다. 안전한코드의예 C 1: umask(077) ; // 파일권한디: rw , 렉터리권한 : rwx : FILE *out = fopen("important_file", "w"); 3: if (out) { 4: fprintf(out, " 민감한정보 \n"); 95

96 5: fclose(out); 6: 라. 진단방법 해당취약점은보안특성중중요자원에대한접근권한설정과관련된취약 점으로정적도구를사용하여중요자원이무엇인지판단하는것은어려운작업 니다. 이에따라진단원이직접중요자원을식별하고이에대한취약성을판단 하는것이필요하다. SW에서생성하는중요자원( 파일등 ) 이존재하는지식별한다. 사용자업로드파 일, 프로그램이사용하는설정파일등중요자원에대해읽기쓰, 기실행, 등의 권한을사전에정의하였는지확인하고사전에정의한권한대로중요자원에접 근권한을허용하는지확인한다. 설정파일, 문서파일의경우실행권한이설정되 지않았는지확인하여야한다. // 파일권한디: rw-rw-rw-, 렉터리권한 : rwxrwxrwx String cmd = "umask 0"; File file = new File("/home/report/report.txt");... Runtime.getRuntime().exec(cmd); SW가중요한보안관련자원에대하여읽기또는수정하기권한을의도하지않게허가할경우, 권한을갖지않은사용자가해당자원을사용하게된다. 1: // 파일권한 : rw-rw-rw-, 디렉터리권한 : rwxrwxrwx 2: String cmd = "umask 0"; 3: File file = new File("/home/report/report.txt"); 4:... 5: Runtime.getRuntime().exec(cmd); 마. 참고문헌 96

97 [1] CWE-732 Incorrect Permission Assignment for Critical Resource - [2] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Porous Defenses, RANK 17 CWE-732 Incorrect Permission Assignment for Critical Resource 97

98 4. 취약한암호화알고리즘허용 가. SW 개요 개발자들은환경설정파일에저장된패스워드를보호하기위하여간단한 인코딩함수를이용하여패스워드를감추는방법을사용하기도한다. 그렇지만 base64 와같은지나치게간단한인코딩함수를사용하는것은패스워드를제대 로보호할수없다. 정보보호측면에서취약하거나위험한암호화알고리즘을사용해서는안된 다. 표준화되지암호화알고리즘을사용하는것은공격자가알고리즘을분석하 여무력화시킬수있는가능성을높일수도있다. 몇몇오래된암호화알고리 즘의경우는컴퓨터의성능이향상됨에따라취약해지기도해서, 예전에는해 독하는데몇십억년이걸리던알고리즘이며칠이나몇시간내에해독되기도 한다알. RC2, RC4, RC5, RC6, MD4, MD5, SHA1, DES 고리즘이여기에해당 된다. < 그림 3-12> 취약한암호화알고리즘허용 < 그림 3-12> 은취약한대칭키암호화알고리즘를 DES 이용하여평문을암호 화하고복호화하는과정을나타내고있다. 나. 보안대책 자신만의암호화알고리즘을개발하는것은위험하며, 학계및업계에서이 미검증된표준화된알고리즘을사용한다. 기존에취약하다고알려진 DES, RC5 등의암호알고리즘을대신하여, 3DES, AES, SEED 등의안전한암호알고리 98

99 즘으로대체하여사용한다. 참고 : 안전한암호알고리즘및키길이 블록암호 운영모드 메시지 인증코드 난수발생기 분류 최소안전성수준 블록암호 해쉬함수 기밀성 보호함수목록 112비트 ARIA( 키길이 : 128/192/256), SEED( 키길이 : 128) ECD, CBC, CFB, OFB, CTR 기밀성/ 인증 CCM, GCM 해쉬함수기반 블록기반 해쉬함수 /HMAC 공개키암호 블록기반 기반 SHA-224/256/384/512 HMAC CMAC, GMAC HASH_DRBG, HMAC_DRBG CTR_DRBG RSAES - ( 공개키길이 ) 2048, RSA-OAEP 에서사용되는해쉬함수 : SHA-224/256 전자서명 키설정방식 보호함수 RSA-PSS, KCDSA, ECDSA, EC-KCDSA DH, ECDH 보호함수파라미터 시스템 파라미터 RSA-PSS KCDSA, DH ECDSA, EC-KCDSA, ECDH ( 공개키길이) 2048, 3072 ( 공개키길이, 개인키길이) (2048, 224), (2048, 256) (FIPS) B-233, B-283 (FIPS) K-233, K-283 (FIPS) P-224, P-256 출처 : 암호알고리즘검증기준 Ver 2.0(2012.3), 암호모듈시험기관 99

100 다. 코드예제 취약한 DES 알고리즘으로암호화하고있다. 안전하지않은코드의예 JAVA 1. try { 1: Cipher c = Cipher.getInstance("DES"); 2: c.init(cipher.encrypt_mode, k); 3: rslt = c.update(msg); 4: 5: catch (InvalidKeyException e) { 안전하다고알려진 AES 알고리즘등을적용한다. 안전한코드의예 JAVA 1: try { 2: Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); 3: c.init(cipher.encrypt_mode, k); 4: rslt = c.update(msg); 5: 6: catch (InvalidKeyException e) { 라. 진단방법 해당취약점은보안특성중암호알고리즘사용과관련된내용으로정적도구 를사용하여암호알고리즘의적절성여부를판단하는것은어렵다. 다만, 일부 언어들에서는암호화함수를제공하기때문에이언어들에대해서는암호화함 수를통하여취약한암호알고리즘사용여부를진단원이판단할수있다. 하지 만자체암호화알고리즘을사용여부는수동진단이필요하다. 자체구현한암호화관련알고리즘을사용하는지확인하고자체구현한암호 알고리즘을사용할경우취약함으로판단한다. 만약, 암호전문가가존재할경우 해당암호함수의암호알고리즘의적절성을판단하여보증하는것은가능하다. 특정언어에서제공하는암호관련함수를호출하는지식별한다. 100

101 - 취약한알고리즘등: MD4, MD5, RC2, RC4, RC5, DES, 2DES - 안전한알고리즘등: SHA-256, AES, SEED, ARIA try { Ciphe r c = Cipher.getInstance("DES"); c.init(cipher.encrypt_mode, k); rslt = c.update(msg); catch (InvalidKeyException e) { 패스워드를 base64로인코딩하여 configuration 파일에저장한경우이다. Basea64 인코딩기법자체가가지는취약점때문에이경우패스워드를안전하 게보호할수없다. 1: 2: boolean DBConnect() throws SQLException { 3: url = "DBServer"; 4: usr = "Scott"; 5: con = null; 6: 7: { 8: prop = new Properties(); 9: FileInputStream("config.properties")); 10: 11: // 패스워드를 64bit로한다 decoding. 12: password[] = Base64.decode(prop.getProperty("password")); 13: 14: 유효성점검없이패스워드를문자열로읽는다. 15: = DriverManager.getConnection(url, usr, password.tostring()); 16: catch (FileNotFoundException e) { 17: 18: catch (IOException e) { 19: 20: 21: 101

102 DES 등의낮은보안수준의알고리즘을사용하는경우는안전하지않다. public static EgovFormBasedUUID nameuuidfrombytes(byte[] name) { MessageDigest md; try { md = MessageDigest.getInstance("MD5"); catch (NoSuchAlgorithmException nsae) { throw new InternalError("MD5 not supported"); byte[] md5bytes = md.digest(name); md5bytes[6] &= 0x0f; /* cl ear version */ md5bytes[6] = 0x30; /* set to version 3 */ md5bytes[8] &= 0x3f; /* cl ear variant */ md5bytes[8] = 0x80; /* set to IETF variant */ return new EgovFormBasedUUID(md5Bytes); Base64 encoding 의경우는암호화가아닌인코딩이다. 개발시 base64 encoding 을사용하는경우는암호화목적이아닌가시성과보관성을위해서이 다. 그러므로 base64 encoding을사용하였을때취약한암호화알고리즘이라 하기어렵다. 하지만개발자가암호화를위해을 base64 encoding 사용하였다 면취약하다고판정한다. 마. 참고문헌 [1] CWE-327 Use of a Broken or Riscky Cryptographic Algorithm - [2] OWASP Top (OWASP 2010) A7 Insecure Cryptographic Storage 102

103 [3] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Porous Defenses, RANK 19 CWE-327 Use of a Broken or Risky Cryptographic Algorithm [4] Bruce Schneier. "Applied Cryptography". John Wiley &Sons

104 5. 중요정보평문저장( 또는전송) 가. 개요 프로그램이보안과관련된민감한데이터를평문으로통신채널을통해서송 수신할경우, 통신채널스니핑을통해인가되지않은사용자에게민감한데이 터가노출될수있는보안취약점이다. 나. 보안대책 < 그림 3-13> 중요정보평문저장( 또는전송 ) 개인정보( 주민등록번호, 여권번호등 ), 금융정보 ( 카드 계좌번호 ), 패스워드등을저장할 때에는반드시암호화하여저장하고중요한정보를통신채널을전송할때에 도암호화한다. 다. 코드예제 속성파일에서읽어들인패스워드(Plain text) 를네트워크를통하여서버에전송하고있다. 이경우패킷스니핑을통하여 password 가노출될수있다. 안전하지않은코드의예 JAVA 1: void foo() { 2: try { 3: Socket socket = new Socket("taranis", 4444); 4: PrintWriter out = new PrintWriter 104

105 5: (socket.getoutputstream(), true); 6: String password = getpassword(); 7: out.write(password); 8: catch (FileNotFoundException e) { 9:... 10: 패스워드를네트워크를통하여서버에전송하기전에암호화를수행하였다. 안전한코드의예 JAVA 1: void foo() { 2: try { 3: Socket socket = new Socket("taranis", 4444); 4: PrintStream out = new PrintStream 5: (socket.getoutputstream(), true); 6: Cipher c = Cipher.getInstance 7: ("AES/CBC/PKCS5Padding"); 8: String password = getpassword(); 9: encryptedstr= c.update(password.getbytes()); 10: out.write(encryptedstr,0,encryptedstr.length); 11: catch (FileNotFoundException e) { 라. 진단방법 해당취약점은보안특성중평문전송과관련된내용으로정적도구를사용하 여중요정보의기준을판단하는것은불가능하다. 개인정보( 주민등록번호, 여권번호등 ), 금융정보 ( 카드 계좌번호), 패스워드등민감한정 보를다루는지확인하고( ➀), 해당정보가네트워크등을통하여전송될때암 호화되는지확인한다 ( ➁). void foo() { try { Socket socket = new Socket("taranis", 4444); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); String password = getpassword(); out.write(password); ➁ ➀ catch (FileNotFoundException e) {

106 다음의예제에서는인증을통과한사용자의패스워드정보가평문으로에 DB 저장되므로취약하다. 1: String username = request.getparameter("username"); 2: String password = request.getparameter("password"); 3: PreparedStatement p=null; 4: try { 5:... 6: if (username==nill password==null 7:!isAuthenticatedUser(usename, password)) { 8: throw new MyException(" 인증에러 "); 9: 10: p = conn.preparestatement("insert INTO employees VALUES(?,?)"); 11: p.setstring(1,username); 12: p.setstring(2,password); 13: p.execute(); 14:... 15: 속성파일에서읽어들인패스워드(Plain text) 를네트워크를통하여서버에 전송하고있다. 이경우패킷스니핑을통하여패스워드가노출될수있어취 약하다. 1: 2: String getpassword() { 3: return "secret"; 4: 5: 6: void foo() { 7: try { 106

107 8: Socket socket = new Socket("taranis", 4444); 9: PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 10: String password = getpassword(); 11: out.write(password); 12: catch (FileNotFoundException e) { 13: 14: 마. 참고문헌 [1] CWE-311 Cleartext Transmission of Sensitive Information - [2] OWASP Top (OWASP 2007) A9 Insecure Communications [3] 2011 CWE/SANS Top 25 Most Dangerous Software Errors - Porous Defenses, RANK 8 CWE-311 Missing Encryption of Sensitive Data 107

108 6. 하드코드된패스워드 가. 개요 프로그램코드내부에하드코드된패스워드를포함하고, 이를이용하여내부 인증에사용하거나외부컴포넌트와통신을하는경우관리자정보가노출될 수있어위험하다. 또한, 코드내부에하드코드된패스워드가인증실패를야기 하는경우, 시스템관리자가그실패의원인을파악하기쉽지않은단점이있다. < 그림 3-14> 하드코드된패스워드 위에그림은데이터베이스연결을위한아이디및패스워드를하드코딩해놓았다. 이를통해관리자정보가노출될수있다. 나. 보안대책 패스워드는암호화하여별도의파일에저장하여사용하고 SW 설치시사용 하는디폴트패스워드, 키등을사용하는대신 " 최초- 로그인" 모드를두어사용자가직접패스워드나키를입력하도록설계한다. 108

109 다. 코드예제 데이터베이스를연결하기위하여코드내부에상수형태로정의된패스워드 를사용하면프로그램에취약점을야기할수있다. 안전하지않은코드의예 JAVA 1: public Connection DBConnect(String url, String id) { 2: try { 3: conn = DriverManager.getConnection(url, id, "tiger"); 4: catch (SQLException e) { 5: System.err.println("..."); 6: 7: return conn; 8: 9: 데이터베이스를사용하는프로그램작성시패스워드를구하는로직을따로구현하여, 주어진로직에의하여검증된패스워드를사용한다. 안전한코드의예 JAVA 1: try { 2: String url = props.getproperty("url"); 3: String id = props.getproperty("id"); 4: String pwd = props.getproperty("passwd"); 5: 6: byte[] decrypted_pwd = cipher.dofinal(pwd.getbytes()); 7: pwd = new String(decrypted_pwd); 8: conn = DriverManager.getConnection(url, id, pwd); 라. 진단방법 사용자 관리자로그인페이지 ( 식별인증 ) 를요청하는모듈 함수를확인하여사용 자관리자 패스워드가소스코드안에직접코딩되어있는지확인하고내외부 서버( 업무서버, DB 등) 에접속을관리하는모듈 함수를확인하여서버접속패스워 드가소스코드안에직접코딩되어있는지확인한다. 109

110 패스워드를별도의파일에저장하여사용하지않고소스코드안에하드코 eld 되어있는경우엔취약하다고판정한다. 다음의예제에서데이터베이스접속정보인비밀번호를 47번라인에서입력 하고있다. private static final String JDBC_DRIVER = "org.gjt.mm.mysql.driver" private static final String JDBC_URL = "jdbc:mysql:// :1621/com" private static final String JDBC_USER = "com" 47: private static final String JDBC_PASSWORD = "com01" 마. 참고문헌 [1] CWE-259 Hard-coded Password - [2] OWASP Top (OWASP 2010) A7 Insecure Cryptographic Storage [3] SANS Top (SANS 2010) Porus Defense 110

111 7. 충분하지않은키길이사용을허용하는취약점 가. 개요 길이가짧은키를사용하는것은암호화알고리즘을취약하게만들수있다. 현재 RSA 알고리즘은적어도 1024 비트이상의길이를가진키와함께사용해 야한다고알려져있다. Symmetric 암호화의경우에는적어도 128비트이상의 키를사용하는것이바람직하다. 나. 보안대책 최소한 128 비트이상의키를사용한다. 다. 코드예제 다음의예제는보안성이강한 RSA 알고리즘을사용함에도불구하고, 키사이 즈를작게설정함으로써프로그램의취약점을야기한경우이다. 안전하지않은코드의예 JAVA 1: 2: public void target() throws NoSuchAlgorithmException { 3: KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA"); 4: // Key generator 의불충분한키크기 5: keygen.initialize(512); 6: KeyPair mykeys = keygen.generatekeypair(); 7: 공개키암호화에사용하는키의길이는적어도 1,024 비트이상으로설정한다. 안전한코드의예 JAVA 1: 2: public void target() throws NoSuchAlgorithmException { 3: KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA"); 4: // Key generator 의값은최소 1024bit 로설정한다. 5: keygen.initialize(1024); 111

112 6: KeyPair mykeys = keygen.generatekeypair(); 7: 라. 진단방법 대칭키암호알고리즘( 예,AES, ARID, SEED 등) 의경우 128bit 이상, 해쉬함 수예 (, SHA 등의 ) 경우 128bit 이상, 공개키암호알고리즘( 예, RSA, ECC 등 ) 2,048bit 이상(ECC 의경우, 256 이상) 의키를사용하는지확인한다. 다음의예제는보안성이강한알RSA 고리즘을사용함에도불구하고키, 사 이즈를작게설정함으로써프로그램의취약점을야기한경우이다. 1: 2: public void target() throws NoSuchAlgorithmException { 3: KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA"); 4: // Key generator 의불충분한키크기 5: keygen.initialize(512); 6: KeyPair mykeys = keygen.generatekeypair(); 7: 마. 참고문헌 [1] CWE-310 Cryptographic Issues - [2] OWASP Top (OWASP 2010) A7 Insecure Cryptographic Storage 112

113 8. 적절하지않은난수값사용 가. 개요 예측가능한난수를사용하는것은시스템에취약점을야기시킨다. 예측불 가능한숫자가필요한상황에서예측가능한난수를사용한다면, 공격자는 SW 에서생성되는다음숫자를예상하여시스템을공격하는것이가능하다. 나. 보안대책 난수발생기에서를 seed 사용하는경우에는예측하기어려운방법으로변경한 다. 일반적으로 Java에서는 java.lang.math.random() 메소드사용을자제하고, java.util.random 클래스를사용, C에서는대신 rand() 를 randomize(seed) 사용하 하는것이좋다. 세션ID, 암호화키등보안결정을위한값을생성하고보안결정 을수행하는경우에는 java.security.securerandom 클래스를사용한다. 다. 코드예제 java.lang.math 클래스의메소드는 random() 를 seed 재설정할수없기때문에 위험하다. 안전하지않은코드의예 JAVA 1: 2: public double roledice() { 3: return Math.random(); 4: 5: java.util.random 클래스는를 seed 재설정하지않아도매번다른난수를생성한 다. 따라서 Random 클래스를사용하는것이보다안전하다. 안전한코드의예 JAVA 1: import java.util.random; 113

114 2: import java.util.date; 3: 4: public int roledice() { 5: Random r = new Random(); 6: // setseed() 메소드를사용해서 r을예측불가능한 long 타입으로설정한다. 7: r.setseed(new Date().getTime()); 8: // 난수생성 9: return (r.nextint()%6) + 1; 10: 11: 라. 진단방법 Math.random() 메소드를사용하는지확인한다.( ➀), Math.random() 을사용하 는경우취약한다. 난수값을세션ID로설정하여보안결정에사용하는지확인한 다 (➁). 보안결정인경우 java.security.securerandom 를사용하면안전하다.... function setsessionid() { ➁ if (!Get_Cookie( SessionID )) Set_Cookie( SessionID,Math.random()); ➀ Math.random() 함수를사용하여난수값을발생시켰을경우취약하다. public static int[] insertrandom(int[] Cnt, int i,int scope) { int ran = (int) (Math.random() * scope) - 1; if (checkdigit(ran,cnt)) { Cnt[i] = ran; else { insertrandom(cnt,i,scope); return Cnt; 114

115 자체랜덤키생성으로취약점보완하는경우즉, 다음의예제와같이 Date 요소들로취약점을보완하는경우는안전하다고판정한다. long rand = ((r.nextlong()>>>1)%( enddate.gettimeinmillis()-begindate.gettimeinmillis() + 1)) + begindate.gettimeinmillis(); Java.util.Random, java.security.securityrandom 사용시에는복잡도가상대적으로높으므로취약하지않다. import java.security.securerandom;... SecureRandom r = new SecureRandom(); long rand = ((r.nextlong()>>>1)%( enddate.gettimeinmillis()-begindate.gettimeinmillis() + 1)) + begindate.gettimeinmillis(); 마. 참고문헌 [1] CWE-330 Use of Insufficiently Random Values - [2] SANS Top (SANS 2009) Porus Defense - CWE ID 330 Use of Insufficiently Random Values [3] J. Viega and G. McGraw. "Building Secure Software: How to Avoid Security Problems the Right Way"

116 9. 패스워드평문저장 가. 개요 패스워드를암호화되지않은텍스트의형태로저장하는것은시스템손상의 원인이될수있다환. 경설정파일에평문으로패스워드를저장하면, 환경설정 파일에접근할수있는사람은누구나패스워드를알아낼수있다. 패스워드는 높은수준의암호화알고리즘을사용하여관리되어져야한다. 패스워드를설정파일에저장하는것은경우패스워드를암호화되지않은상 태로저장하게되면, 암호가외부에직접적으로드러날위험성이있다. 따라서, 패스워드는쉽게접근할수없는저장소에저장하든지아니면암호화한상태로 저장하여야한다. 나. 보안대책 패스워드를외부환경파일에저장한다면, 암호화하여저장한다. 다. 코드예제 다음의예제는속성파일에서읽어들인패스워드를 String 형태그대로데이 터베이스를연결하는데사용하고있다. 사용자가속성파일에공격을위한문 자열을저장한경우, 프로그램이의도한공격에노출될수있다. 안전하지않은코드의예 JAVA 1: package testbed.unsafe; 2: import java.sql.*; 3: import java.util.properties; 4: import java.io.*; 5: public class U256 { 6: public void f(string url, String name) throws IOException { 7: Connection con = null; 8: try { 9: Properties props = new Properties(); 10: FileInputStream in = new FileInputStream("External.properties"); 116

117 11: byte[] pass = new byte[8]; 12: // 외부파일로부터 password 를읽는다. 13: in.read(pass); 14: // password 가 DB connection 의인자변수로그대로사용이된다. 15: con = DriverManager.getConnection(url, name, new String(pass)); 16: con.close(); 17: catch (SQLException e) { 18: System.err.println("SQLException Occured "); 19: finally { 20: try { 21: if (con!= null) 22: con.close(); 23: catch (SQLException e) { 24: System.err.println("SQLException Occured "); 25: 26: 27: 28: 외부에서입력된패스워드는사용전에복호화후사용되어야한다. 안전한코드의예 JAVA 1: package testbed.safe; 2: import java.sql.*; 3: import java.util.properties; 4: import java.io.*; 5: public class S256 { 6: public void f(string[] args) throws IOException { 7: Connection con = null; 8: try { 9: Properties props = new Properties(); 10: FileInputStream in = new FileInputStream("External.properties"); 11: props.load(in); 12: String url = props.getproperty("url"); 13: String name = props.getproperty("name"); 14: // 외부파일로부터를 password 읽은후, 복호화한다. 15: String pass = decrypt(props.getproperty("password")); 16: // 외부파일로부터의패스워드를복호화후사용함. 17: con = DriverManager.getConnection(url, name, pass); 18: catch (SQLException e) { 19: System.err.println("SQLException Occured "); 117

118 20: finally { 21: try { 22: if (con!= null) 23: con.close(); 24: catch (SQLException e) { 25: System.err.println("SQLException Occured "); 26: 27: 28: 29: 라. 진단방법 DB 접속등패스워드사용이필요한로직을확인하고( ➀), 사용된패스워드의 복호화여부확인한다( ➁). 복호화절차가없다면패스워드가평문으로저장되 어있는것이므로취약하다.... properties prop = new Properties() ; prop.load(new FileInputStream("conifig.properties")) ; String password = prop.getprope rty("password"); ➁ DriverManager.getConnection(url, u sr, password) ; ➀... 다음의예제는속성파일에서읽어들인패스워드를 String 형태그대로데 이터베이스를연결하는데사용하고있다. 사용자가속성파일에공격을위한 문자열을저장한경우, 프로그램이의도한공격에노출될수있다. 1: package testbed.unsafe; 2: import java.sql.*; 3: import java.util.properties; 4: import java.io.*; 5: public class U256 { 6: public void f(string url, String name) throws IOException { 7: Connection con = null; 8: try { 118

119 9: Properties props = new Properties(); 10: FileInputStream i n = new FileInputStream("External.properties"); 11: byte[] pass = new byte[8]; 12: // 외부파일로부터 password 를읽는다. 13: in.r ead(pass); 14: // password가db connection 의인자변수로그대로사용이된다. 15: con = DriverManager.getCo nnection(url, name, new String(pass)); 16: con.close(); 17: catch (SQLException e) { 18: System.err.printl n("sqlexceptio n Occured "); 19: finally { 20: try { 21: if (con!= null) 22: con.close(); 23: catch (SQLException e) { 24: System.err.printl n("sqlexceptio n Occured "); 25: 26: 27: 28: configuration 파일( 설정파일) 에저장된패스워드를읽어서그대로데이터베 이스연결에사용하고있다. 이것은다른사람이패스워드에쉽게접근할수 있도록하므로프로그램취약점을유발할수있다. 1: package testbed.unsafe; 2: import java.io.fileinputstream; 3: import java.io.filenotfoundexception; 4: import java.io.ioexception; 5: import java.sql.connection; 119

120 6: import java.sql.drivermanager; 7: import java.sql.sqlexception; 8: public class U260 { 9: public boolean connecttest(string url, String usr) { 10: Connection con = null; 11: byte[] b = new byte[1024]; 12: boolean result = false; 13: try { 14: FileInputStream fs = new FileInputStream("sample.cfg"); 15: // 외부데이터를배열로읽어온다. 16: fs.read(b); 17: // 패스워드문자열을만든다 18: String password = new String(b); 19: // 패스워드가 DB 연결정보로사용이된다. 20: con = DriverManager.getCo nnection(url, usr, password); 21: catch (FileNotFoundException e) { 22: System.err.printl n("file Not Fo und Exception Occurred!"); 23: catch (IOException e) { 24: System.err.printl n("i/o Exception Occurred!"); 25: catch (SQLException e) { 26: System.err.printl n("sql Exceptio n Occurred!"); 27: finally { 28: try { 29: if (con!= null) { 30: con.close(); 31: result = true; 32: 33: catch (SQLException e) { 34: System.err.printl n("sql Exceptio n Occurred!"); 35: 120

121 36: 37: return result; 38: 39: 마. 참고문헌 [1] CWE-256 Plantext Storage of a Password - [2] J. Viega and G. McGraw. "Building Secure Software: How to Avoid Security Problems the Right Way"

122 10. 하드코드된암호화키 가. 개요 코드내부에하드코드된암호화키를사용하여암호화를수행하면암호화된 정보가유출될가능성이높아진다. 많은 SW 개발자들이코드내부의고정된 패스워드의해쉬를계산하여저장하는것이패스워드를악의적인공격자로부터 보호할수있다고믿고있다. 그러나많은해쉬함수들이역계산이가능하며, 적어도 brute-force 공격에는취약하다는것을고려해야만한다. 나. 보안대책 암호화알고리즘에서상수가아닌키를사용해서암호화를수행하도록설계하 여야하며암호화되, 었더라도패스워드를상수의형태로프로그램소스코드내부 에저장하여사용하면안된다. 다. 코드예제 암호화된패스워드를상수의형태로코드내부에서사용하는것은프로그램 소스가노출되는경우패스워드도동시에노출되는취약점을가지게된다. 안전하지않은코드의예 JAVA 1: 2: private Connection con; 3: 4: public String encryptstring (String usr) { 5: Stringc seed = "68af404b c4b6f22b6c63e6b"; 6: 7: try { 8: // 상수로정의된암호화키를이용하여 encrypt 를수행한다. 9: SecretKeySpec skeyspec = new SecretKeySpec(seed.getBytes(), "AES"); 10: 11: // 해당암호화키기반의암호화또는복호화업무수행 12:.. 13: catch (SQLException e) { 122

123 14: 15: 16: return con; 17: 18: 암호화된패스워드를복호화하기위하여사용되는암호화키도소스코드내 부에상수형태로정의해서사용하면안된다. 안전한코드의예 JAVA 1: 2: private Connection con; 3: 4: public String encryptstring (String usr) { 5: Stringc seed = null; 6: 7: try { 8: // 암호화키를외부환경에서읽음. 9: seed = getpassword("./password.ini"); 10: // 암호화된암호화키를복호화함. 11: seed = decrypt(seed); 12: // 상수로정의된암호화키를이용하여 encrypt 를수행한다. 13: // use key coss2 14: SecretKeySpec skeyspec = new SecretKeySpec(seed.getBytes(), 15: "AES"); 16: // 해당암호화키기반의암호화또는복호화업무수행 17:.. 18: catch (SQLException e) { 19: 20: 21: return con; 22: 23: 라. 진단방법 DB 접속등패스워드사용이필요한로직을확인하고( ➀), 사용된패스워드의 암호화여부확인한다( ➁). 암호화된패스워드가소스내에존재하는지여부확 123

124 인한다( ➂). 소스코드내에암호화된패스워드를저장하는경우취약하다 public Connection DBConnect(String url, String usr) { String password = "68af404b c4b6f22b6c63e6b"; try { // 패스워드로상수를사용하고있다 ➁ con = DriverManager.getConnection(url, usr, password); ➀ catch (SQLException e) { System.err.println("..."); return con; 암호화를하는데사용되는암호화키를소스에하드코딩해서사용하는경우 취약하다. import java.security.invalidkeyexception; import java.security.nosuchalgorithmexception; import java.sql.sqlexception; import javax.crypto.badpaddingexception; import javax.crypto.illegalblocksizeexception; import javax.crypto.nosuchpaddingexception; public class U321 { String getpassword(){ return "secret"; void foo(string url, String usr){ try { String encryptedpwd = getpassword(); // private key를상수로정의 byte[] privatekey = {'6','8','a','f','4','0','4','b','5','1','3','0','7' javax.crypto.cipher cipher = javax.crypto.cipher.getinstance("rsa"); 124

125 // 상수를 key 사용하여보안키생성 javax.crypto.secretkey mydeskey = new javax.crypto.spec.secretkeyspec(privatekey, "DES"); cipher.init(javax.crypto.cipher.decrypt_mode,mydeskey); // 암호화된를 password 복호화 byte[] plaintextpwdbytes = cipher.dofinal(encryptedpwd.getbytes()); // DB 연결 java.sql.drivermanager.getconnection(url, usr, new String(plainTextPwdBytes)); catch (InvalidKeyException e) { e.printstacktrace(); catch (NoSuchAlgorithmException e) { e.printstacktrace(); catch (NoSuchPaddingException e) { e.printstacktrace(); catch (IllegalBlockSizeException e) { e.printstacktrace(); catch (BadPaddingException e) { e.printstacktrace(); catch (SQLException e) { e.printstacktrace(); 다. 암호화를위한암호화키가아닌알고리즘명을지정하는경우취약하지않 // 키를설정한다. skey = new SecretKeySpec( key, "DESede" ); 125

126 마. 참고문헌 [1] CWE-321 Use of Hard-coded Cryptographic Key

127 11. 취약한패스워드허용 가. 개요 사용자에게강한패스워드조합규칙을요구하지않으면사용자계정이취약 하게된다. 안전한패스워드를생성하기위해서는숫자/ 문자/ 특수문자를조합 하여 7 자리이상으로해야한다. < 그림 3-15> 취약한패스워드허용 나. 보안대책 패스워드생성시강한조건검증을수행한다. 패스워드는문자숫/ 자/ 특수문 자세가지조합을사용하는경우 8 자리이상, 문자/ 숫자/ 특수문자중두가지 조합을사용하는경우 10 자리이상으로생성한다. 다. 코드예제 가입자가입력한패스워드에대한복잡도검증없이가입승인처리를수행 하고있다. 안전하지않은코드의예 JAVA 1: try { 2: String id = request.getparameter("id"); 3: String passwd = request.getparameter("passwd"); 4: catch (SQLException e) 5: { 사용자계정을보호하기위해가입시패스워드복잡도검증후가입승인처 리를수행한다. 127

128 안전한코드의예 JAVA 1: try { 2: String id = request.getparameter("id"); 3: String passwd = request.getparameter("passwd"); 4: if (passwd == null "".equals(passwd)) 5: return; 6: if (!passwd.matches("") &&(passwd.indexof("@!#")>0) &&(passwd.length() > 7)) 7: catch (SQLException e) 8: { 라. 진단방법 패스워드생성또는변경때입력값을다음과같은규칙으로검사하는모듈 이존재하는지확인한다. ( 참고) 안전한패스워드조합규칙 - 영문자( 대 소구별), 숫자, 특수문자조합한경우, 패스워드길이는자리 8 이상 - 영문자( 대 소구별), 숫자, 특수문자중가지 2 문자열로조합한경우, 패 스워드길이는 10자리이상 - 특정패턴및사용자를 ID 사용금지 다음의예제와같이사용자계정등록등비밀번호를필요로하는정보입력 에서널체크, 비밀번호의자릿수, 특수문자포함등비밀번호요구조건이없거 나약할경우취약하다. 128

129 <% String id = request.getparameter("id"); String pass = r equest.getparameter("pass"); UserVo us ervo = new UserVo(id,pass);... // 사용자를등록한다. String result = registdao.regist(uservo);... 다음의예제와같이가입자가입력한패스워드에대한복잡도검증없이가 입승인처리를수행하게되면사용자계정을보호하기힘들다. 1: 2: public void dopost(httpservletrequest request, HttpServletResponse response) 3: throws IOException, ServletException { 4: try { 5: String id = request.getparameter("id"); 6: String passwd = request.getparameter("passwd"); 7: // 패스워드복잡도검증없이가입승인처리 8:... 9: catch (SQLException e) { 10: 다음의예제는로그인시에비밀번호를확인하는것은비밀번호를저장하는 것이아니므로취약하지않다. 129

130 <% // 로그인시입력한값받음 String id = request.getparameter("id"); String pass = r equest.getparameter("pass"); 다음의예제와같이패스워드저장을위한목적이아닌확인의목적일경우취약하지않다고판정한다. fis = new FileInputStream(PROPERTIES_FILE); props.load(new java.io.bufferedinputstream(fis)); username = (String)props.getProperty("id"); password = (String)props.getProperty("password"); 마. 참고문헌 [1] CWE-521 Weak Password Requirements - [2] OWASP Top A3 Broken Authentication Session Management [3] Web Application Security Consortium (WASC ) Information Leakage 130

131 12. 사용자하드디스크에저장되는쿠키를통한정보노출 가. 개요 대부분의웹응용프로그램에서쿠키는메모리에상주하며브, 라우저의실행 이종료되면사라진다. 프로그래머가원하는경우, 브라우저세션에관계없이 지속적으로저장되도록설정할수있으며, 이것은디스크에기록되고다음브 라우저세션이시작되었을때메모리에로드된다. 개인정보, 인증정보등이영 속적인쿠키 (persistent Cookie) 에저장된다면, 공격자는쿠키에접근할수있는보 다많은기회를가지게되며, 이는시스템을취약하게만든다. 나. 보안대책 쿠키의만료시간은세션이지속되는시간과관련하여최소한으로설정하고 영속적인쿠키에는사용자권한등급, 세션ID 가포함되지않도록한다. 다. 코드예제 javax.servlet.http.cookie.setmaxage 메소드호출에외부의입력이쿠키의유 효시한설정에그대로사용되어프로그램의취약점을야기하는경우이다. 안전하지않은코드의예 JAVA 1: 2: public void makecookie(servletrequest request) { 3: String maxage = request.getparameter("maxage"); 4: if (maxage.matches("[0-9]+")) { 5: String sessionid = request.getparameter("sesionid"); 6: if (sessionid.matches("[a-z=0-9a-z]+")) { 7: Cookie c = new Cookie("sessionID", sessionid); 8: // 외부입력이쿠키유효시한설정에그대로사용되었다. 9: c.setmaxage(integer.parseint(maxage)); 10: 11: 12: 131

132 사용자가요청한값으로쿠키의유효시한을설정하기전에사용자요청을검증하는로직을별도로작성하여, 메소드호출전에호출한다. 안전한코드의예 JAVA 1: 2: public void makecookie(servletrequest request) { 3: String maxage = request.getparameter("maxage"); 4: 5: if (maxage == null "".equals(maxage)) return; 6: if (maxage.matches("[0-9]+")) { 7: String sessionid = request.getparameter("sesionid"); 8: if (sessionid == null "".equals(sessionid)) return; 9: if (sessionid.matches("[a-z=0-9a-z]+")) { 10: Cookie c = new Cookie("sessionID", sessionid); 11: // 쿠키유효시한의최대값을설정해서, 그아래값으로조정한다. 12: int t = Integer.parseInt(maxAge); 13: if (t > 3600) { 14: t = 3600; 15: 16: c.setmaxage(t); 17: 18: 19: 라. 진단방법 사용자브라우저로쿠키를전송하는지확인하고( ➀), 쿠키유효기간확인한다 ( ➁). 쿠키설정값에 id 정보등중요정보포함여부를확인한다( ➂).... Cookie ck1 = new Cookie("id", "test123") ; ➂ ck.setmaxage(60*60*24*365*10) ; ➁ response.addcookie(ck) ; ➀... 다음의예제는 javax.servlet.http.cookie.setmaxage 메소드호출에외부의입 력이쿠키의유효시한설정에그대로사용되어프로그램의취약점을야기하는 경우이다. 132

133 1: 2: public void makecookie(servletrequest request) { 3: String maxage = request.getparameter("maxage"); 4: if (maxage.matches("[0-9]+")) { 5: String sessio nid = r equest.getparameter("sesio nid"); 6: if (sessionid.matches("[a-z=0-9a-z]+")) { 7: Cookie c = new Cookie("sessionID", sessionid); 8: // 외부입력이쿠키유효시한설정에그대로사용되었다. 9: c.setmaxage(integer.parseint(maxage)); 10: 11: 12: 마. 참고문헌 [1] CWE-539 Information Exposure Through Persistent Cookies - [2] OWASP Top (OWASP 2010) A7 Insecure Cryptographic Storage [3] Web Application Security Consortium (WASC ) Information Leakage 133

134 13. 보안속성미적용으로쿠키가노출될수있는취약점 가. 개요 HTTPS 로만서비스하는경우모든정보가암호화되어안전하게전송된다고 생각한다. 그러나보안에민감한데이터를브라우저쿠키에저장할때보안속 성을세팅하지않으면공격자에게단순한텍스트의형태로노출될수있다. 나. 보안대책 HTTPS 로만서비스하는경우브라우저쿠키에데이터를저장할때반드시 Cookie 객체의 setsecure(true) 메소드를호출하여보안속성을설정한다. 한사이 트도메인에서 ( ) HTTP나 HTTP와 HTTPS를함께사용하는경우 setsecure 메소 드를호출하면해당쿠키가 HTTP를통해서는서버에전송되지않아장애가 발생할수있으므로주의해야한다. 다. 코드예제 HTTPS 로만서비스하는경우민감한정보를가진쿠키를전송하는과정에서, 보안속성을설정하지않으면공격자에게정보가노출될수있다. 안전하지않은코드의예 JAVA 1: 2: private final String ACCOUNT_ID = "account"; 3: 4: public void setupcookies(servletrequest r, HttpServletResponse response) { 5: String acctid = r.getparameter("accountid"); 6: // 보안속성설정되지않은쿠키 7: Cookie c = new Cookie(ACCOUNT_ID, acctid); 8: response.addcookie(c); 9: HTTPS 로만서비스하는경우민감한정보를가진쿠키를사용할경우에는 반드시 Cookie 객체의 setsecure(true) 를호출하여야한다. 134

135 안전한코드의예 JAVA 1: 2: private final String ACCOUNT_ID = "account"; 3: 4: public void setupcookies(servletrequest r, HttpServletResponse response) { 5: String acctid = r.getparameter("accountid"); 6: // 계정유효성점검 7: if (acctid == null "".equals(acctid)) return; 8: String filtered_id = acctid.replaceall("\r", ""); 9: 10: Cookie c = new Cookie(ACCOUNT_ID, filtered_id); 11: // 민감한정보를가진쿠키를전송할때에는보안속성을설정하여야한다. 12: c.setsecure(true); 13: response.addcookie(c); 14: 라. 진단방법 HTTPS 프로토콜을 통해쿠키에 ID 등의민감한정보를담아전송하는경 우보안속성을설정(setSecure(true) 메서드호출) 하였는지확인한다. 쿠키값을전송할때는보안속성을켜고 [setsecure(true)] 전송하여야안전 하다. 하지만서비스전체를로 https 전송하지않는경우해당보안속성을켜 면서비스가작동하지않으므로취약점에서제외한다. Cookie cookie = new Cookie(" Cookie", ); cookie.setsecure(true); response.addcookie(cookie); 마. 참고문헌 [1] CWE-614 Sensitive Cookie in HTTPS Session Without 'Secure' Attribute - [2] OWASP Top (OWASP 2010) A9 Insufficient Transport Layer Protection 135

136 14. 주석문안에포함된패스워드 가. 개요 패스워드를주석문에넣어두면시스템보안이훼손될수있다. SW 개발자가 편의를위해서주석문에패스워드를적어둔경우, SW가완성된후에는그것을제거하는것이매우어렵게된다. 또한공격자가소스코드에접근할수있다면, 아주쉽게시스템에침입할수있다. 나. 보안대책 주석에는 ID, 패스워드등보안과관련된내용을기입하지않는다. 다. 코드예제 다음의예제는디버깅등의목적으로사용자이름과패스워드를주석문안 에서술하고제대로지우지않아서취약점이발생한경우이다. 안전하지않은코드의예 JAVA 1: 2: // Password for administrator is "tiger."<- 주석에패스워드가적혀있다. 3: public boolean DBConnect() { 4: String url = "DBServer"; 5: String password = "tiger"; 6: Connection con = null; 7: 8: try { 9: con = DriverManager.getConnection(url, "scott", password); 10: catch (SQLException e) { 11: 12: 프로그램개발시에주석문등에남겨놓은사용자계정이나패스워드등의정 보는개발완료시에확실하게삭제하여야한다. 136

137 안전한코드의예 JAVA 1: 2: // 디버깅등의용도로소스주석에적어놓은패스워드는삭제해야한다. 3: public Connection DBConnect(String id, String password) { 4: String url = "DBServer"; 5: Connection conn = null; 6: try { 7: String CONNECT_STRING = url + ":" + id + ":" + password; 8: InitialContext ctx = new InitialContext(); 9: DataSource datasource = (DataSource) ctx.lookup(connect_string); 10: conn = datasource.getconnection(); 11: catch (SQLException e) { 12: return conn; 13: 라. 진단방법 DB 접속, 관리자로그인등이구현된코드를확인하고( ➀), 주석을확인하여 암호포함여부확인한다 ( ➁).... /* * Password for administrator is "tiger." ➁ */ public Connection DBConnect(String id, String password) { String url = "DBServer"; Connection conn = null; try { String CONNECT_STRING = url + ":" + id + ":" + password; InitialContext ctx = new InitialContext(); DataSource datasource = (DataSource) ctx.lookup(connect_string); ➀ conn = datasource.getconnection(); catch (SQLException e) { System.err.printf("...");... 다음의예제에서는주석문안에개발자의이해를돕기위한목적등으로패 스워드를적어놓고있으므로취약하다고판정한다. 137

138 J1 : DaoTest.java public void daotest() throws Exception { // db sampl e : 84d5d0a08a3ec5e2d91a // 암호화전, 후 : 1365ADMIN_01, aa84c40031d ad3dcf81f9af String pwd= "46c165a343fd ae04655af24dd"; String pwd1 = ARIAEngi ne.decaria(pwd); System.out.println(pwd1); 주석문안에 password, passwd, 비밀번호 등의텍스트가존재하지만실 제로그내용이비밀번호가아닌경우에는취약하지않다고판정한다. // 암호화 String Sid = getsessionvalue(session, "ihidnum"); Sid = AEScryptWithSaltKey.encode(StrTool.sNN(Sid)); String sihidnum = Sid; 소스코드내에비밀번호를설정하지않고환경설정 XML에 DB 접속정보 등비밀번호를저장할경우취약하지않다. <!-- hsql <bean id="datasource" class="org.apache.commons.dbcp.basicdatasource" destroy-method="close"> <property name="driverclassname" value="net.sf.log4jdbc.driverspy"/> <property name="url" value="jdbc:log4jdbc:hsqldb:hsql://localhost/bcvpldb"/> <property name="username" value="sa"/> <property name="password" value=""/> <property name="defaultautocommit" value="false"/> <property name="poolpreparedstatements" value="true"/> </bean> 138

139 마. 참고문헌 [1] CWE-615 Information Exposure Through Comments - [2] OWASP Top (OWASP 2010) A7 Insecure Cryptographic Storage [3] Web Application Security Consortium (WASC ) Information Leakage 139

140 제3절시간및상태 동시또는거의동시수행을지원하는병렬시스템, 하나이상의프로세스가 동작되는환경에서시간및상태를부적절하게관리하여발생할수있는취약점 1. 경쟁조건 : 검사시점과사용시점(TOCTOU) 가. 개요 병렬시스템( 멀티프로세스로구현한응용프로그램) 에서는자원 ( 파일, 소켓등 ) 을사용하기에 앞서자원의상태를검사한다. 하지만자원을사용하는시점과검사하는시점이다르기때문에검, 사하는 시점 (time of check) 에존재하던자원이사용하던시점 (time of use) 에사라지는 등자원의상태가변하는경우가발생한다 < 그림경3-16> 쟁조건검: 사시점과사용시점(TOCTOU) < 그림과 3-16> 같이, 프로세스와 A 가 B 존재하는멀티병렬시스템환경에서 프로세스는 A 사용 ( 파일읽기 ) 에앞서해당파일이존재하는지검사하는과정 (TOC) 을거친다. 이때는프로세스 B에서해당파일을아직사용 ( 삭제) 하지않은 상태이기때문에, 해당자원이문제없음을프로세스는 A 확인하게된다. 하지만 실제사용(TOU) 시점에프로세스는 A 존재하지않는자원을사용하려고하기 140

141 때문에오류등이발생할수있다. 이와같이하나의자원에대하여동시에검사시점과사용시점이달라생기는 취약점으로인해동기화오류뿐아니라교착상태등과같은문제점이발생한다 나. 보안대책 공유자원( 예: 파일) 을여러프로세스가접근하여사용할경우, 동기화구문을 사용하여한번에하나의프로세스만접근가능하도록 (synchronized, mutex 등) 하고 성능에미치는영향을최소화하기위해임계코드주변만동기화구문을사용한 다. 다. 코드예제 다음의예제는파일의존재를확인하는부분과실제로파일을사용하는부분 을실행하는과정에서시간차가발생하는경우, 파일에대한삭제가발생하 여프로그램이예상하지못하는형태로수행될수있다. 또한시간차를이용하 여파일을변경하는등의공격에취약할수있다. 안전하지않은코드의예 JAVA 1: import java.io.*; 2: 3: class FileAccessThread extends Thread { 4: public void run() { 5: try { 6: File f = new File("Test_367.txt"); 7: if(f.exists()) { // 만약파일이존재하면파일내용을읽음 8: BufferedReader br = new BufferedReader(new FileReader(f)); 9: br.close(); 10: 11: catch(ioexception e) { System.err.println("IOException occured"); 12: 13: 14: class FileDeleteThread extends Thread { 15: public void run() { 141

142 16: File f = new File("Test_367.txt"); 17: 18: if(f.exists()) { // 만약파일이존재하면파일을삭제함 19: f.delete(); 20: 21: 22: 23: 24: public class U367 { 25: public static void main(string[] args) { 26: // 파일의읽기와파일을삭제하는것을동시에수행한다. 27: FileAccessThread fileaccessthread = new FileAccessThread(); 28: FileDeleteThread filedeletethread = new FileDeleteThread(); 29: fileaccessthread.start(); 30: filedeletethread.start(); 31: 32: 따라서안전한코드예제와같이동기화구문인 synchronized 를사용하여공유자원 ("Test_367.txt") 이동시에사용되지않도록해야한다. 안전한코드의예 JAVA 1: import java.io.*; 2: 3: class FileAccessThread extends Thread { 4: // synchronized 를사용함으로써블록을수행하는동안지정된객체에 lock이 5: // 걸려서다른 Thread 객체 f 에접근할수없다. 6: public synchronized void run() { 7: try { 8: File f = new File("Test_367.txt"); 9: if(f.exists()) { 10: BufferedReader br = new BufferedReader(new FileReader(f)); 11: br.close(); 12: 13: catch(ioexception e) { System.err.println("IOException occured"); 14: 15: 16: class FileDeleteThread extends Thread { 17: public synchronized void run() { 142

143 18: File f = new File("Test_367.txt"); 19: 20: if(f.exists()) { 21: f.delete(); 22: 23: 24: 25: 26: public class S367 { 27: public static void main(string[] args) { 28: FileAccessThread fileaccessthread = new FileAccessThread(); 29: FileDeleteThread filedeletethread = new FileDeleteThread(); 30: fileaccessthread.start(); 31: filedeletethread.start(); 32: 33: 라. 진단방법 소스코드상에다음과같이공유자원( 파일/ 폴더, 소켓, 드라이버등) 을여러 프로세스가사용하는지확인한다( ➀). 이때, 하나의공유자원을동시에접근할 가능성이존재한다면취약하다고판단하며, 동기화구문등을사용할경우안 전하다고판단한다. 그외공유자원억세스를관리하는 pool 형태의자체모듈 을제작할경우에도안전하다고판단한다. import java.io.*; class FileAccessThread extends Thread { public void run() { try { File f = new File("Test_367.txt"); ➀ if(f.exists()) { // 만약파일이존재하면파일내용을읽음 BufferedReader br = new BufferedReader(new FileReader(f)); br.close(); catch(ioexception e) { System.err.println("IOException occured"); 143

144 class FileDeleteThread extends Thread { public void run() { File f = new File("Test_367.txt"); ➀ if(f.exists()) { // f.delete(); 만약파일이존재하면 파일을삭제함 public class U367 { public static void main(string[] args) { // 파일의읽기와파일을삭제하는것을동시에수행한다. FileAccessThread fileaccessthread = new FileAccessThread(); ➁ FileDeleteThread filedeletethread = new FileDeleteThread(); fileaccessthread.start(); filedeletethread.start(); 다음의예제와같이검사시점과사용시점이달라발생하는경쟁조건을가정해볼수있다. File f = newfil e("toctou.txt"); if (!f.exists()) { FileOutputStreamfos = null; try { fos = newfileoutputstream("toctou.txt"); // 파일에대한처리를한다. catch (IOException e) { // TODO에러처리를한다. finally { // 자원을해제한다. 하지만자바에서는스트림을생성할때을 IOExceptin 발생시키며이에따라 예외에대한적절한처리를하면되므로문제가되지않는다. 144

145 TOCTOU는 C 프로그래밍을할때다음과같은경우에발생한다. if (!access(file,w_ok)) { f = fopen(file,"w+"); operate(f);... else { fprintf(stderr,"unable to open file %s.\n",file); 실제로경쟁조건이이루어지지않는경우취약하지않다. file = new File(filename); File[] flist = file.listfiles(); for (int i = 0; i < flist.length; i++) { currentlist.add(flist[i].getabsolutepath() + "$" + getlastmodifiedtime(flist[i]) + "$" + ((flist[i].length() / 1024) > 0? (flist[i].length() / 1024) : 1) + "KB"); 마. 참고문헌 [1] CWE-367 Time-of-check Time-of-use(TOCTOU) Race Condition

146 3. 제어문을사용하지않는재귀함수 가. 개요 재귀의순환횟수를제어하지못하여할당된메모리나프로그램스택등의 자원을과다하게사용하면위험하다. 대부분의경우, 귀납조건이 (base case) 없 는재귀함수는무한루프에빠져들게되고자원고갈을유발함으로써시스템의 정상적인서비스를제공할수없게한다 < 그림 3-17> 제어문을사용하지않는재귀함수 위그림은함수 Func_A가재귀함수형태로무한반복함으로써자원고갈을 유발하는경우를보여주고있다. 나. 보안대책 모든재귀호출을조건문블럭이나반복문블럭안에서만수행한다. 146

147 다. 코드예제 다음의예제는적절한나 JAVA C에서적절한제어문없이자기자신을호출하 여무한재귀가되는예이다. 안전하지않은코드의예 JAVA 1: 2: public int factorial(int n) { 3: return n * factorial(n - 1); 4: 5:... 안전하지않은코드의예 C 1: int fac(n) { 2: return n*fac(n-1); 3: 이와같은재귀호출은조건문이나반복문같은제어문을통하여다음과같이 해당루프를빠져나올수있게기술되어야한다. 안전한코드의예 JAVA 1: public int factorial(int n) { 2: int i; 3: if (n == 1) { 4: i = 1; 5: else { 6: i = n * factorial(n - 1); 7: 8: return i; 9: 안전한코드의예 C 1: int fac(n) { 2: if (n <= 0) return 1; 3: else return n*fac(n-1); 4: 10: 147

148 위의예제들은 n 나씩감소시킴으로써이 n 1 이될때최종, 계산값을 return 함으로써종료된다. 라. 진단방법 자신을호출하는재귀함수나메소드가존재하는지식별하고, 해당함수내에 제어문을통하여해당함수에서리턴될수있는지확인한다. 제어문을통하여 재귀함수를빠져나올수있으면안전하다. public int factorial(int n) { return n * factorial(n - 1); ➀ 재귀함수는함수내부에서자신을호출하는경우이다. 함수명과파라미터의 개수, 파라미터의자료형이일치하는경우취약하다. public class RecursiveCall { private int a public void func(int a) { this.a = a; public void func(string a) { func(a); 다음의예제와같이같은이름에파라미터가다른함수가있는경우는취약 하지않다. 다음의예제는 Func(String a) 에서 func(int a) 를호출하고있는데 148

149 recursive call 이아닌다른함수의호출이므로안전하다. public class RecursiveCall { private int a public void func(int a) { this.a = a; public void func(string a) { func(integer.parseint(a)); 제어조건이존재하여제어가되는재귀인경우취약하지않다. public MenuVO getfirstleafchildmenu(int menuseq) { List<MenuVO> childmenulist = menumap.get(menuseq).getchild MenuList(); if (CollectionUtils.isEmpty(childMenuList)) { return menumap.get(menuseq); return getfirstleafchildmenu( childmenulist.get(0).getmenuseq()); 마. 참고문헌 [1] CWE-674 Uncontrolled Recursion

150 제4절에러처리 에러를처리하지않거나, 불충하게처리하여에러정보에중요정보( 시스템내부정보등 ) 가포함될때발생할수있는취약점 1. 오류메시지통한정보노출 가. 개요 소프트웨어가실행환경, 사용자, 관련데이터에대한민감한정보를포함하는 오류메시지를생성하여외부에제공하는경우공격자의악성행위를도와줄수 있다. 예외발생시예외이름이나스택트레이스를출력하는경우프로그램내부구 조를쉽게파악할수있다. < 그림오3-18> 류메시지통한정보노출 < 그림은 3-18> 오류메시지통한정보노출 을나타내주고있으며, 오류화면 을통해서해당시스템의운영체제가윈도우계열이며데이터베이스는 MS-SQL 을사용함을알수있다. 150

151 나. 보안대책 오류메시지는정해진사용자에게유용한최소한의정보만포함하도록한다. 소스코드에서 예외상황은내부적으로처리하고사용자에게민감한정보를포함 하는오류를출력하지않도록설정하고적절한환경설정을통해에러정보를노 출하지않고, 미리정의된페이지를제공하도록설정한다. 다. 코드예제 예외이름이나오류추적정보를출력하면프로그램내부정보가유출된다. 안전하지않은코드의예 JAVA 1: public static void main(string[] args) { 2: String urlstring = args[0]; 3: try{ 4: URL url = new URL(urlString); 5: URLConnection cmx = 6: url.openconnection(); 7: cmx.connect(); 8: 9: catch (Exception e) 10: { e.printstacktrace(); 11: 12: 예외이름이나오류추적정보를출력하지않는다. 안전한코드의예 JAVA 1: public static void main(string[] args) { 2: String urlstring = args[0]; 3: try{ 4: URL url = new URL(urlString); 5: URLConnection cmx = 6: url.openconnection(); 151

152 7: cmx.connect(); 8: 9: catch (Exception e) 10: { System.out.println(" 연결예외발생 "); 11: 12: 라. 진단방법 해당취약점에서시스템환경, 유저정보, 민감한정보등에대한기준을정적 도구가판단하기어려움. 이에따라진단원이출력함수등을통하여외부에출 력되는값중민감한정보등을판단할필요가있다. 오류메시지를출력하는 경우해당오류에시스템환경, 유저정보, 데이터등민감한정보가포함되어있 는지확인한다. public static void main(string[] args) { String urlstring = args[0]; try{ URL url = new URL(urlString); URLConnection cmx = url.openconnection(); cmx.connect(); catch (Exception e) { e.printstacktrace(); ➀ 오류메시지를통해환경, 사용자, 관련데이터등의내부정보가유출될경우 취약하다. W2 : EgovUnitCalc.jsp <%@ page language="java" contenttype="text/html; charset=utf-8" buffer="none"%> <%@page import="egovframework.com.utl.fda.ucc.service.egovunitcalcutil" %> <% 152

153 String scmd = r equest.getparameter("cmd") == null? "" : (String) r equest.getparameter("cmd"); double nresult=0.0; try{ if(!scmd.equals("")){ EgovUnitCalcUtil egovunitcalcutil= new EgovUnitCalcUtil();. catch(exception e){ e.printstacktrace(); %> 마. 참고문헌 [1] CWE-209 Information Exposure Through an Error Message

154 2. 오류상황에대응부재 가. 개요 오류가발생할수있는부분을확인하였으나, 이러한오류에대하여예외처 리를하지않을경우에는프로그램이충돌하거나종료되는등의개발자가의도 하지않은결과가발생한다. 나. 보안대책 오류가발생할수있는부분에대하여제어문을사용하여적절하게예외처 리(C/C++ 에서와 if 에서 switch, Java 등try-catch ) 를한다. 다. 코드예제 위예제는 try 블록에서발생하는오류를포착 (catch) 하고있지만그오류에대 해서아무조치를하고있지않다. 따라서프로그램이계속실행되기때문에프 로그램에서어떤일이일어났는지전혀알수없게된다. 안전하지않은코드의예 JAVA 1: 2: private Connection conn; 3: 4: public Connection DBConnect(String url, String id, String password) { 5: try { 6: String CONNECT_STRING = url + ":" + id + ":" + password; 7: InitialContext ctx = new InitialContext(); 8: DataSource datasource = (DataSource) ctx.lookup(connect_string); 9: conn = datasource.getconnection(); 10: catch (SQLException e) { 11: // catch 블록이비어있음 12: catch (NamingException e) { 13: // catch 블록이비어있음 14: 15: return conn; 16: 154

155 예외를포착 (catch) 한후, 각각의예외사항 (Exception ) 에대하여적절하게처리해야한다. 안전한코드의예 JAVA 1: 2: private Connection conn; 3: 4: public Connection DBConnect(String url, String id, String password) { 5: try { 6: String CONNECT_STRING = url + ":" + id + ":" + password; 7: InitialContext ctx = new InitialContext(); 8: DataSource datasource = (DataSource) ctx.lookup(connect_string); 9: conn = datasource.getconnection(); 10: catch (SQLException e) { 11: // Exception catch 이후에 Exception 대한적절한처리를해야한다. 12: if ( conn!= null ) { 13: try { 14: conn.close(); 15: catch (SQLException e1) { 16: conn = null; 17: 18: 19: catch (NamingException e) { 20: // Exception catch 이후에 Exception 대한적절한처리를해야한다. 21: if ( conn!= null ) { 22: try { 23: conn.close(); 24: catch (SQLException e1) { 25: conn = null; 26: 27: 28: 29: return conn; 30: 라. 진단방법 오류가발생할수있는부분에대하여예외처리를수행했는지확인하고제어문 을통하여예외처리하는루틴이비어있는지확인한다. 155

156 다음의예제는 try 블록에서발생하는오류를포착(catch) 하고있지만그오 류에대해서아무조치를하고있지않다. 따라서프로그램이계속실행되기 때문에프로그램에서어떤일이일어났는지전혀알수없게된다. 1: 2: private Connection conn; 3: 4: public Connection DBConnect(String url, String id, String password) { 5: try { 6: String CONNECT_STRING = url + ":" + id + ":" + password; 7: InitialContext ctx = new InitialContext(); 8: DataSource datasource = (DataSource) ctx.lookup(connect_string); 9: conn = datasource.getconnection(); 10: catch (SQLException e) { 11: // catch 블록이비어있음 12: catch (NamingException e) { 13: // catch 블록이비어있음 14: 15: return conn; 16: 마. 참고문헌 [1] CWE-390 Detection of Error Condition Without Action - [2] OWASP Top Ten 2004 Category A7 - Improper Error Handling 156

157 3. 적절하지않은예외처리 가. 개요 프로그램수행중에함수의결과값에대한적절한처리또는예외상황에대한조건을적절하게검사하지않을경우, 예기치않은문제를야기할수있다. 나. 보안대책 값을반환하는모든함수의결과값을검사하여, 그값이기대한값인지 검사하고, 예외처리를사용하는경우에광범위한예외처리대신구체적인예 외처리를수행한다. 다. 코드예제 함수의인자로 filename 에대한 Null 체크없이 File 객체를생성하였으며광범, 위한예외클래스인 Exception 을사용하여예외처리를했다. 안전하지않은코드의예 JAVA 1: public void readfromfile(string filename) { 2: try { 3:... 4: File myfile = new File(fileName); 5: FileReader fr = new FileReader(myFile); 6:... 7: catch (Exception ex) {... 8: filename 이 Null 값인지검사하고 Null 이면에러메시지를출력과예외를발생 시킨다. 또한발생가능한모든예외에대한구체적인예외처리를한다. 안전한코드의예 JAVA 1: public void readfromfile(string filename) throws FileNotFoundException, 2: IOException,MyException { 3: try { 157

158 4:... 5: // filename 에대한널을조사 6: if ( filename == NULL ) throw new MyException(" 에러 ); 7: File myfile = new File(fileName); 8: FileReader fr = new FileReader(myFile); 9:... 10: // 함수루틴에서모든가능한예외에대해서처리한다. 11: catch (FileNotFoundException fe) {... 12: catch (IOException ie) {... 13: 라. 진단방법 함수또는메서드에대하여반환값을검사하고예외를발생시키는경우구체적 인예외처리를수행하는지확인한다. public void readfromfile(string filename) { try {... File myfile = new File(fileName); FileReader fr = new FileReader(myFile);... catch (Exception ex) { ➀ 마. 참고문헌 [1] CWE-754 Improper Check for Unusual or Exceptional Conditions - [2] SANS Top 25 Most Dangerous Software Errors, [3] M. Howard, D. LeBlanc, Writing Secure Code, Second Edition, Microsoft Press 158

159 제5절코드품질 타입변환오류자원, ( 메모리등 ) 의부적절한반환등과같이개발자가범할수 있는코딩오류로인해유발되는취약점 1. 널(Null) 포인터역참조 가. 개요 널포인터역참조는일' 반적으로그객체가이 NULL 될수없다' 라고하는 가정을위반했을때발생한다. 공격자가의도적으로 NULL 포인터역참조를 발생시키는경우, 그결과발생하는예외상황을이용하여추후의공격을계획 하는데사용될수있다. 나. 보안대책 널이될수있는레퍼런스 (reference) 는참조하기전에널값인지를검사하여 안전한경우에만사용한다. 다. 코드예제 다음의예제는 "cmd" 프로퍼티가항상정의되어있다고가정하고있지만, 만 약공격자가프로그램의환경을제어해 "cmd" 프로퍼티가정의되지않게하면, cmd는널이되어 trim() 메소드를호출할때널포인터예외가발생하게된다. 안전하지않은코드의예 JAVA 1: 2: public void f() { 3: String cmd = System.getProperty("cmd"); 4: // cmd 가 null 인지체크하지않았다. 5: cmd = cmd.trim(); 6: System.out.println(cmd); 159

160 7: 먼저가 cmd 널인지검사한후에사용한다. 안전한코드의예 JAVA 1: 2: public void f() { 3: String cmd = System.getProperty("cmd"); 4: // cmd 가 null 인지체크하여야한다. 5: if (cmd!= null) { 6: cmd = cmd.trim(); 7: System.out.println(cmd); 8: else System.out.println("null command"); 9: 라. 진단방법 표현된객체가널값이될수있는지확인한다. 만약널값이될수있는지체크 하여예외처리를한경우안전으로판단하고널체크를하지않은경우취약한 것으로판단한다. public void f() { String cmd = System.getProperty("cmd"); // cmd가인지 null 체크하지않았다. cmd = cmd.trim(); System.out.println(cmd); ➀ ( 참고) 널값이될가능성은다음의기준으로확인 - - 널이할당된값은널이될수있음 선언이된후객체가생성되지않은값은널이될수있음 - 널인객체로필드접근을하거나널 / 인객체에메소드호출을할경우 결과값은널이될수있음 - 문자열등널 이될수있는객(NULLABLE)' 체들의연산결과값은널 160

161 이될수있음 변수를 NULL로초기화한후값을대입하지못하는경우에해당변수를 참조하면널포인터역참조가발생한다. 다음의예제는 330 라인에서널로초기화한이후에 338 라인에서 NULL 값인vmrs 값을참조하고있다. 이경우는조건문등에의해분기가이루어지 면서 NULL 로초기화된변수가초기화되지않는경우이다. public Hashtable deleteall(connection con, GenericModel model) throws Exception { Hashtable<String, Object> m = new Hashtable<String, Object>(); 330: VMResultSet vmrs = null int rvalue = 0; try{ ArrayList grid =null ;... con.commit(); con.setautocommit(true); if(rvalue > 0) { vmrs = dao.listgoodknowquestion(con, model); vmrs.setmessage(utilmsg.getinstance().getmsg("suc003")); else{ 383: vmrs.setmessage(utilmsg.getinstance().getmsg("err000")); m.put("result", vmrs); catch (Exception e) {... finally {... return m; 161

162 다른유형으로자주발생하는경우는의 database Connection, Statement등의 자원을사용한후에해제하는과정에서해당자원이널인지확인하지않는경 우이다. 다음의예제에서는 81번째라인에서널로 Statement 초기화하고있고 85번째 라인에서예외가발생하면번 95 라인의의 Statement 값을대입하지못하고 111 번의 finally 문으로분기한후번 117 라인이실행되면서널값을참조하게된 다. private static void m ak eli st () { Connection con = null StringBuffer sql = new StringBuffer(); 81: PreparedStatement statement = null ResultSet rs = null list.clear(); try { 85: con = GenericDAO.getDataSource().getConnection();... 95: statement = con.preparestatement(sql.tostring()); rs = statement.executequery(); while (rs.next()) { String authgrp = rs.getstring("authority_group");... catch (Exception e) { if (verbose) { : finally { try { rs.close(); catch (Exception e1) { 162

163 try { 117: statement.close(); catch (Exception e1) { if (con!= null) { try { con.close(); catch (SQLException e) { e.printstacktrace(); Interface Iteration은을 Null 리턴하지않는데를 Null Dereference 탐지해내 는경우나, 함수의설계상 Null을리턴하지않도록정의되어있는함수의리 턴값을참조할경우에는이 NullPointerException 발생하지않는다. 이를확인 하기위해서는함수의 Java document 를유의깊게살펴보아야한다. 함수의 리턴값에대한기술되어있는을 Javadoc 참조해서코드를검토하여야한다. StringTokenizer st = new StringTokenizer(info_url,"?"); int sti=0; while (st.hasmoretokens()) { if(sti==0) if(sti==1) sti++; jsonurl=st.nexttoken(); jsparam=st.nexttoken(); String [] jsonparams = jsparam.split("&"); jsparam=""; for (int i=0;i<jsonparams.length;i++){ jsparam=jsparam+jsonparams[i].split("=")[0]+": '"+jsonparams[i].split("=")[1]+"'"; if(i!=jsonparams.length-1)jsparam=jsparam+","; 163

164 Try ~ catch 문에서를 throw 하는경우절 catch 이후는실행되지않음으로 Null Dereference 가발생하지않는다. 다음의예제에서은 System.out.println("After Throw 1"); 실행되지않는다. publicstaticvoidte stfunction(string datestr1) throws Exception { SimpleDateFormatsdf = newsimpledateformat("yyyymmdd",locale.getdefault()); Date date1 = null try { date1 = sdf.parse(datestr1); catch (ParseException e) { System.err.println("Inner Function"); e.printstacktrace(); thrownew Exception(e); System.out.println("After Throw 1"); intdays1 = (int)((date1.gettime()/100000)/24); System.out.println("After Throw 2"); 다음의예제에서 intdays1 = (int)((date1.gettime()/100000)/24); 에서 data1이 Null 일경우, NullPointerException 이발생하고다음단계로진행되지않게된 다. 이러한이유로 intdays2 = (int)((date1.gettime()/100000)/24); 문은실행되 지않으며을 Null 참조하지않게된다. SimpleDateFormatsdf = newsimpledateformat("yyyymmdd",locale.getdefault()); Date date1 = null try { date1 = sdf.parse(datestr1); catch (ParseException e) { 164

165 System.err.println("Inner Function"); e.printstacktrace(); System.out.println("After Throw 1"); intdays1 = (int)((date1.gettime()/100000)/24); intdays2 = (int)((date1.gettime()/100000)/24); System.out.println("After Throw 2"); 다음과같은조건은앞의널체크조건이참이면뒤의 or 조건은판단하지 않는다. 그러므로뒤의문장에서 NullPointerException 은발생하지않는다. if (a == null a.length() == 0) { // 처리한다. 다음의예제에서는 catch 절안에서 return 하고있으므로예외가발생하여 f 에값을넣지못하더라도는 f.write 실행되지않는다. FileOutputStream f = null try { f = newfileoutputstream("toctou"); catch (FileNotFoundException e) { try { // TODO Auto-generated catch block e.printstacktrace(); return f.write(0); catch (IOException e) { // TODO Auto-generated catch block e.printstacktrace(); 165

166 다음의예제에서는 JSP 내장객체를참조하고있다. 이경우에는 Null Deference 가발생하지않는다. <td align="center" colspan='2'><inp ut type='button' val ue=' 다시로그인' onclick="location.href='${pagecontext.request.contextpath/utl/sec/certlogin.do'"></td> 다음과같은 Integer 클래스의 static 함수호출은 Integer가객체가아니므로 Null 값을참조하지않는다. Integer.parseInt(stringValue); 다음과같이 Data Flow 상이아닌단일함수에서파라미터가널일경우는 취약하지않은것으로판단한다. 해당함수를호출할때널체크를하도록해 야한다. public SmsConnection sendrequsest(smsconnection smsconn) throws Exception { // SMS 전송요청 SmsSender sender = null SmsConnection result = null try { sender = new SmsSender(smeConfigPath); sender.open(); result = sendrequsest(smsconn, sender); finally { if (sender!= null) { sender.close(); smsconn.setresult(result.getresult()); smsconn.setresultmessage(result.getresultmessage()); return smsconn; 166

167 프로그램의논리상널이아닌경우에는오탐으로처리한다. 다음의예제에서 BsnList는 java.util.list 인터페이스로 List 의사이즈만큼순환참조하고있다. List 의사이즈내에서 get(int offset) 함수는을 Null 리턴하지않는다. hm에는항상널이아니라는것이보장되고을 hm 참조는문제가되지않는 다. 그러므로 Null Dereference 는발생하지않는다. for( int i = 0 ; i < BsnList.size() ; i++){ hm = (HashMap)BsnList.get(i) ; if(hm.get("bsn_se")!= null &&!hm.get("bsn_se").equals("")){ if (hm.get("bsn_se").equals("eta")){ JRE 기본패키지클래스의생성자의경우, Null 을반환할수있다고명시 되어있지않은한을 Null 리턴한다고판단하지않는다. if(infolist == null) infolist = new ArrayList(); for(int i=0; containers!= null && i < containers.length; i++) { hm = new HashMap(); for(int j=0; j < paramrecvdata.length; j++) { h m. p u t ( p a r a m R e c v D a t a [ j ], containers[i].getfield(paramrecvdata[j]).getvalueasstring()); infolist.add(hm); 마. 참고문헌 [1] CWE-476 NULL Pointer Dereference - 167

168 [2] OWASP Top (OWASP 2004) A9 Application Denial of Service 168

169 2. 부적절한자원해제 가. 개요 프로그램의자원예를, 들면열린파일기술자힙 (open file descriptor), 메모리 (heap memory), 소켓(socket) 등은유한한자원이다. 이러한자원을할당받아 사용한후, 더이상사용하지않는경우에는적절히반환하여야하는데프로그램 오류또는에러로사용이끝난자원을반환하지못하는경우이다. < 그림 3-19> 부적절한자원해제 나. 보안대책 자원을획득하여사용한다음에는반드시자원을해제하여반환한다. 다. 코드예제 데이터베이스에연결된후에사용중예외가발생하면할당된데이터베이스 커넥션및 JDBC 자원이반환되지않는다. 169

170 안전하지않은코드의예 JAVA 1: : try { 3: Class.forName("com.mysql.jdbc.Driver"); 4: conn = DriverManager.getConnection(url); 5: conn.close(); 6: catch (ClassNotFoundException e) { 7: 예외상황이발생하여함수가종료될때예외의발생여부와상관없이 finally 블록에서할당받은자원을반환한다. 안전한코드의예 JAVA 1: : try { 3: Class.forName("com.mysql.jdbc.Driver"); 4: conn = DriverManager.getConnection(url); 5: stmt = conn.createstatement() ; 6: 7: : 9: catch (ClassNotFoundException e) { 10: System.err.print("error"); 11: catch (SQLException e) { 12: System.err.print("error"); 13: finally { 14: if(stmt!= null){ 15: try{ 16: stmt.close() ; 17: catch(sqlexception e){ 18: : 20: 21: if(conn!= null){ 22: try{ 23: conn.close() ; 24: catch(sqlexception e){ 25: : 27: 28: 라. 진단방법 170

171 자원( 파일기술자, 힙메모리, 소켓) 이선언되고, 선언된자원이할당된경우해제되는 지확인한다. 진단자는제어문, 예외처리문등의분기등에따라모든흐름 (control flow) 을판단하여자원해제여부를체크해야한다. 할당된자원이해제될 경우안전하다고판단하고자원이해제되지않는분기가존재할경우취약하 다. public void f() { String cmd = System.getProperty("cmd"); // cmd 가인지 null 체크하지않았다. cmd = cmd.trim(); System.out.println(cmd); ➀ 자원을얻어사용한후에는반드시자원을해제해야자원유출을막을수있다. 다음과같이 rs, pstmt, pstmt1, conn등자원을얻어서사용한후 try catch 문안에서해당자원을해제하면중간에예외가발생할경우자원해제가이루 어지지않은채예외처리구문인 일어난다. catch 구문으로건너뛰게되어자원유출이 try{ String sqlselect = "SELECT USER_ID, PWD FROM OSS_USER" String sqlupdate = "UPDATE OSS_USER SET PASSWD =? WHERE USER_ID =?" Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection("jdbc:oracle:thin:@ :1521:ossdb", "oss", "OSS"); pstmt = conn.preparestatement(sqlselect); pstmt1 = conn.preparestatement(sqlupdate); rs = pstmt.executequery(); while( rs.next() ){ System.out.println("#################### user_id : " + 171

172 rs.getstring("user_id")); pstmt1.setstring(1, CryptUtils.encrypt(rs.getString("PWD"))); pstmt1.setstring(2, rs.getstring("user_id")); pstmt1.executeupdate(); pstmt1.clearparameters(); System.out.println("#################### ing01 : "); conn.commit(); rs.close(); pstmt.close(); pstmt1.close(); conn.close(); catch(exception e){ e.printstacktrace(); try{conn.rollback();catch(exception ex){ 다음과같은예제는 rs.close(), pstmt.close() 등자원해제가 try catch 문안에 서함께이루어지고있다. 이경우 rs.close() 문에서예외가발생하면 pstmt.close() 이하의자원해제는이루어지지않으므로자원유출이일어난다. try{ String sqlselect = "SELECT USER_ID, PWD FROM OSS_USER" String sqlupdate = "UPDATE OSS_USER SET PASSWD =? WHERE USER_ID =?" Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection("jdbc:oracle:thin:@ :1521:ossdb", "oss", "OSS"); pstmt = conn.preparestatement(sqlselect); pstmt1 = conn.pr eparestatement(sqlupdate); rs = pstmt.executequery(); while( rs.next() ){ 172

173 System.out.println("#################### user_id : " + rs.getstring("user_id")); pstmt1.setstring(1, CryptUtils.encrypt(rs.getString("PWD"))); pstmt1.setstring(2, rs.getstring("user_id")); pstmt1.executeupdate(); pstmt1.clearparameters(); System.out.println("#################### ing01 : "); conn.commit(); catch(exception e){ e.printstacktrace(); try{conn.rollback();catch(exception ex){ finally { try{ rs.close(); pstmt.close(); pstmt1.close(); conn.close(); catch(exception e){ 다음의예제와같이 finally 절에서을 connection 해주 close 고있으므로자원 의부적절한반환이이루어지지않는다. try{ String sqlselect = "SELECT USER_ID, PWD FROM OSS_USER" String sqlupdate = "UPDATE OSS_USER SET PASSWD =? WHERE USER_ID =?" Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection("jdbc:oracle:thin:@ :1521:ossdb", "oss", "OSS"); pstmt = conn.preparestatement(sqlselect); pstmt1 = conn.pr eparestatement(sqlupdate); 173

174 rs = pstmt.executequery(); while( rs.next() ){ System.out.println("#################### user_id : " + rs.getstring("user_id")); pstmt1.setstring(1, CryptUtils.encrypt(rs.getString("PWD"))); pstmt1.setstring(2, rs.getstring("user_id")); pstmt1.executeupdate(); pstmt1.clearparameters(); System.out.println("#################### ing01 : "); conn.commit(); catch(exception e){ e.printstacktrace(); try{conn.rollback();catch(exception ex){ finally { try{rs.close();catch(exception e){ try{pstmt.close();catch(exception e){ try{pstmt1.close();catch(exception e){ try{conn.close();catch(exception e){ 다음의예제는예외가발생하여절catch 에서 return 하고있다. 예외가발생 할경우에는 Socket 할당이이루어지지않으므로자원의부적절한반환이이루 어지지않는다. public void run() { Socket sock= null try { if (threadhost!= null ) { sock = new Socket(threadHost, threadport); else { sock = new Socket(threadInetAddr, threadport); 174

175 catch (IOException ioe) { threadexception = ioe; return threadsocket = sock; 클래스의멤버변수에자원을저장하고사용하기위한경우에는자원해제의 주체가함수내부가아닌함수외부이므로취약하지않다. public void run() { Socket sock = null try { if (threadhost!= null) { sock = new Socket(threadHost, threadport); else { sock = new Socket(threadInetAddr, threadport); catch (IOException ioe) { threadexception = ioe; threadsocket = sock; 함수의역할이자원을리턴하는경우에는자원의해제는함수를호출한쪽에 서담당하므로취약하지않다. public class DBUtil { public static Connection getconnection() { Connection conn = null; try { 175

176 Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection(DbInfo.url,DbInfo.id, DbInfo.password); catch (SQLException e) { // TODO Auto-generated catch block e.printstacktrace(); catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printstacktrace(); return conn; 마. 참고문헌 [1] CWE-404 Improper Resource Shutdown or Release - [2] OWASP Top (OWASP 2004) A9 Application Denial of Service [3] SANS Top (SANS 2009) Risky Resource Management 176

177 제6절캡슐화 중요한데이터또는기능성을불충분하게캡슐화함으로써인가되지않은사 용자에게데이터누출이가능해지는취약점 1. 잘못된세션에의한데이터노출 가. 개요 다중스레드환경에서는싱글톤 (singleton) 11) 객체필드에경쟁조건 (race condition) 이발생할수있다. 따라서다중스레드환경에서서블릿에 (servlet) 정보를저장하는멤버변수가포함되지않도록하여서로다른세션에서데이터를공유하지않도록해야한다. 나. 보안대책 싱글톤패턴을사용하는경우, 변수범위(Scope) 에주의를기울여야한다. 특 히 Java에서는 HttpServlet 클래스의하위클래스에서멤버필드를선언하지않도 록하고필요한경우지역변수를선언하여사용한다. 다. 코드예제 두사용자가거의동시에접속할시, 첫번째사용자를위한스레드가 out.println(...) 을수행하기전에두번째사용자의스레드가을 name =... 수행 하면첫번째사용자는두번째사용자의정보(name) 를보게된다. 안전하지않은코드의예 JAVA 1: public class U488 extends HttpServlet { 2: private String name; 11) Singleton Pattern : GOF 32 가지패턴중하나. 하나의프로그램내에서하나의인스턴스만을생성해야만하는패턴. Connection Pool, Thred Pool 과같이풀(Pool) 형태로관리되는클래스의경우프로그램내에서단하나의인스턴트로관리해야하는경우를말함 177

178 3: protected void dopost(httpservletrequest request, HttpServletResponse response) 4: throws ServletException, IOException { 5: name = request.getparameter("name"); 6: 7: out.println(name + ", thanks for visiting!"); 8: 9: 필요한경우지역변수를선언하여사용한다. 안전한코드의예 JAVA 1: public class S488 extends HttpServlet { 2: protected void dopost(httpservletrequest request, HttpServletResponse response) 3: throws ServletException, IOException { 4: // 지역변수로변경한다. 5: String name = request.getparameter("name"); 6: if (name == null "".equals(name)) return; 7: out.println(name + ", thanks for visiting!"); 8: 9: 라. 진단방법 HttpServlet의하위클래스에멤버필드가선언되어있고 final이아닌경우는취 약한것으로판단한다. public class U488 extends HttpServlet { private String name; protected void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { name = request.getparameter("name"); out.println(name + ", thanks for visiting!"); 서블릿(JSP 포함) 에서상수로사용하지않는멤버변수를사용하면취약하다. 178

179 page import="javax.xml.namespace.*" %> page import="gov.mogaha.ntis.web.frs.gis.cmm.util.*" %> page import="gov.mogaha.ntis.cmm.util.ssosessionutil"%> <%! String commonpath = "/"; String imagepath= commonpath +"img/"; String imagepath_gis = imagepath +"gis/cmm/btn/"; JSP 페이지나서블릿내에서의내부클래스사용은멤버필드가아니므로취약 하지않다. <%@ page language="java" import="java.io.*,java.text.*,java.util.*,java.net.*,com.inswave.system.config.*,com.inswave.system.exception.*"%> <%! private class CacheEntity { String name; String lastmodified; String expires; String etag; Final 필드의경우클래스내부에서상수로사용되는값이므로취약하지않 다. <%@ page import="java.util.*" %> <%@ page import="gov.mogaha.ntis.cmm.util.stringutil" %> <%@ page import="gov.mogaha.ntis.cmm.util.page" %> <%@ taglib uri="cmm.tld" prefix="cmm" %> <%! final String imagepath = "/img/"; String tr eeimagepath = imagepath+"gis/por/tr ee_sub.gif"; %> 179

180 Spring 프레임워크기반의 egov 프레임워크는 IoC 를사용하고있다. 이는 = "EgovFileMngService") private EgovFileMngService fileservice; 마. 참고문헌 [1] CWE-488 Exposure of Data Element to Wrong Session

181 2. 제거되지않고남은디버그코드 가. 개요 디버깅목적으로삽입된코드는개발이완료되면제거해야한다. 디버그코 드는설정등의민감한정보를담거나시스템을제어하게허용하는부분을담 고있을수있다만. 일남겨진채로배포될경우공격자가식별과정을우회하 거나의도하지않은정보와제어정보가노출될수있다. < 그림 3-20> 제거되지않고남은디버그코드 나. 보안대책 디버그코드는삭제후운영서버에배포한다. 다. 코드예제 다음의예제는 main() 메소드내에화면에출력하는디버깅코드를포함하고 있다. J2EE의경우 main() 메소드사용이필요없으며, 개발자들이콘솔응용프 로그램으로화면에디버깅코드를사용하는경우가일반적이다. 안전하지않은코드의예 JAVA 181

182 1: public class U489 extends HttpServlet { 2: protected void doget(httpservletrequest request, ) throws { 3: protected void dopost(httpservletrequest request, ) throws { 4: // 테스트를위한 main() 함수나디버깅용로그출력문등이남아있다. 5: public static void main(string args[]) { 6: System.err.printf("Print debug code"); 7: 8: 이에따라 J2EE와같은응용프로그램에서 main() 메소드는삭제한다. J2EE의 main() 메소드의경우디버깅코드인경우가일반적이다. 안전한코드의예 JAVA 1: public class S489 extends HttpServlet { 2: protected void doget(httpservletrequest request, ) throws { 3: protected void dopost(httpservletrequest request, ) throws { 4: // 테스트용코드는제거해준다. 5: 라. 진단방법 J2EE 를제외하고디버그코드를정적도구만으로판단하기는쉽지않다. 개발중테스트목적으로남아있는디버그코드가존재하는지확인한다 ( ➀). J2EE 환경(J2EE Standard) 에서는 main 메소드작성을금하고있으며, 일반적으 로개발자들은디버그코드를 main으로작성하므로 main 메소드가사용되는 경우디버그코드인지확인하여야한다. public class U489 extends HttpServlet { protected void doget(httpservletrequest request, ) throws { protected void dopost(httpservletrequest request, ) throws { // 테스트를위한함수나 main() 디버깅용로그출력문등이남아있다. public static void main(string args[]) { System.err.printf("Print debug code"); ➀ 182

183 J2EE와같은응용프로그램에서디버깅용으로사용되는 한다. main() 메소드는삭제 1: public class U489 extends HttpServlet { 2: protected void doget(httpservletrequest request, ) throws { 3: protected void dopost(httpservletrequest request, ) throws { 4: // 테스트를위한 main() 함수나디버깅용로그출력문등이남아있다. 5: public static void main(string args[]) { 6: System.err.pri ntf("print debug code"); 7: 마. 참고문헌 [1] CWE-489 Leftover Debug Code - [2] M. Howard and D. LeBlanc. "Writing Secure Code". Page nd Edition. Microsoft [3] 183

184 3. 시스템데이터정보노출 가. 개요 시스템의내부데이터나디버깅관련정보가공개되면, 이를통해공격자에 게아이디어를제공하는등공격의빌미가된다. < 그림 3-21> 시스템데이터정보노출 나. 보안대책 디버깅을위해작성한시스템정보출력코드를모두삭제한다. 다. 코드예제 예외발생시 getmessage() 를통해오류와관련된시스템에러정보등민감한 정보가유출될수있다. 안전하지않은코드의예 JAVA 1: 2: public void f() { 3: try { g(); 4: catch (IOException e) { 5: // 예외발생시 printf(e.getmessage()) 를통해오류메시지정보가유출된다. 6: System.err.printf(e.getMessage()); 7: 8: 9: private void g() throws IOException { 10: 184

2007 상반기 실적회의 - DRM Extension

2007 상반기 실적회의 - DRM Extension Secure Coding 을위한 Semantic 분석엔진 SPARROW SCE PA 사업부개발 2 팀장 정영범박사 사이버해킹 55 억 보안취약점 75% 보안약점의조기제거 30 배 Secure Coding Mandatory 2012.12 40억이상 2014. 20억이상 2015. 감리대상사업전체 행정기관 제안요청서에 SW 개발보안적용명시 계약시 SW개발보안을위한적절한개발절차및진단도구사용여부확인

More information

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp");

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher( 실행할페이지.jsp); 다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp"); dispatcher.forward(request, response); - 위의예에서와같이 RequestDispatcher

More information

Observational Determinism for Concurrent Program Security

Observational Determinism for  Concurrent Program Security 웹응용프로그램보안취약성 분석기구현 소프트웨어무결점센터 Workshop 2010. 8. 25 한국항공대학교, 안준선 1 소개 관련연구 Outline Input Validation Vulnerability 연구내용 Abstract Domain for Input Validation Implementation of Vulnerability Analyzer 기존연구

More information

Connection 8 22 UniSQLConnection / / 9 3 UniSQL OID SET

Connection 8 22 UniSQLConnection / / 9 3 UniSQL OID SET 135-080 679-4 13 02-3430-1200 1 2 11 2 12 2 2 8 21 Connection 8 22 UniSQLConnection 8 23 8 24 / / 9 3 UniSQL 11 31 OID 11 311 11 312 14 313 16 314 17 32 SET 19 321 20 322 23 323 24 33 GLO 26 331 GLO 26

More information

Microsoft PowerPoint - GUI _DB연동.ppt [호환 모드]

Microsoft PowerPoint - GUI _DB연동.ppt [호환 모드] GUI 설계 6 주차 DB 연동김문정 tops@yd.ac.kr 강의순서강의전환경 JDK 설치및환경설정톰캣설치및환경설정이클립스 (JEE) 설치및환경설정 MySQL( 드라이버 ) 설치및커넥터드라이브연결 DB 생성 - 계정생성이클립스에서 DB에연결서버생성 - 프로젝트생성 DB연결테이블생성및등록 2 MySQL 설치확인 mysql - u root -p MySQL 에데이터베이스추가

More information

Java XPath API (한글)

Java XPath API (한글) XML : Elliotte Rusty Harold, Adjunct Professor, Polytechnic University 2006 9 04 2006 10 17 문서옵션 제안및의견 XPath Document Object Model (DOM). XML XPath. Java 5 XPath XML - javax.xml.xpath.,? "?"? ".... 4.

More information

PowerPoint Template

PowerPoint Template JavaScript 회원정보 입력양식만들기 HTML & JavaScript Contents 1. Form 객체 2. 일반적인입력양식 3. 선택입력양식 4. 회원정보입력양식만들기 2 Form 객체 Form 객체 입력양식의틀이되는 태그에접근할수있도록지원 Document 객체의하위에위치 속성들은모두 태그의속성들의정보에관련된것

More information

J2EE Concepts

J2EE Concepts ! Introduction to J2EE (1) - J2EE Servlet/JSP/JDBC iseminar.. 1544-3355 ( ) iseminar Chat. 1 Who Are We? Business Solutions Consultant Oracle Application Server 10g Business Solutions Consultant Oracle10g

More information

14-Servlet

14-Servlet JAVA Programming Language Servlet (GenericServlet) HTTP (HttpServlet) 2 (1)? CGI 3 (2) http://jakarta.apache.org JSDK(Java Servlet Development Kit) 4 (3) CGI CGI(Common Gateway Interface) /,,, Client Server

More information

mytalk

mytalk 한국정보보호학회소프트웨어보안연구회 총괄책임자 취약점분석팀 안준선 ( 항공대 ) 도경구 ( 한양대 ) 도구개발팀도경구 ( 한양대 ) 시큐어코딩팀 오세만 ( 동국대 ) 전체적인 그림 IL Rules Flowgraph Generator Flowgraph Analyzer 흐름그래프 생성기 흐름그래프 분석기 O parser 중간언어 O 파서 RDL

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 @ Lesson 2... ( ). ( ). @ vs. logic data method variable behavior attribute method field Flow (Type), ( ) member @ () : C program Method A ( ) Method B ( ) Method C () program : Java, C++, C# data @ Program

More information

I T C o t e n s P r o v i d e r h t t p : / / w w w. h a n b i t b o o k. c o. k r

I T C o t e n s P r o v i d e r h t t p : / / w w w. h a n b i t b o o k. c o. k r I T C o t e n s P r o v i d e r h t t p : / / w w w. h a n b i t b o o k. c o. k r I T C o t e n s P r o v i d e r h t t p : / / w w w. h a n b i t b o o k. c o. k r Jakarta is a Project of the Apache

More information

Microsoft PowerPoint - file

Microsoft PowerPoint - file SW 보안약점소개 SIGPL Workshop, KCC2013 2013. 6. 28 한국항공대학교안준선 목차 시큐어코딩, 보안약점, 보안취약점 SW 보안약점의유형 입력데이터검증및표현 (Input Validation and Representation) API 오용 (API Abuse) 보안기능 (Security Features) 시간및상태 (Time and State)

More information

쉽게 풀어쓴 C 프로그래밊

쉽게 풀어쓴 C 프로그래밊 Power Java 제 27 장데이터베이스 프로그래밍 이번장에서학습할내용 자바와데이터베이스 데이터베이스의기초 SQL JDBC 를이용한프로그래밍 변경가능한결과집합 자바를통하여데이터베이스를사용하는방법을학습합니다. 자바와데이터베이스 JDBC(Java Database Connectivity) 는자바 API 의하나로서데이터베이스에연결하여서데이터베이스안의데이터에대하여검색하고데이터를변경할수있게한다.

More information

로거 자료실

로거 자료실 redirection 매뉴얼 ( 개발자용 ) V1.5 Copyright 2002-2014 BizSpring Inc. All Rights Reserved. 본문서에대한저작권은 비즈스프링 에있습니다. - 1 - 목차 01 HTTP 표준 redirect 사용... 3 1.1 HTTP 표준 redirect 예시... 3 1.2 redirect 현상이여러번일어날경우예시...

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 @ Lesson 3 if, if else, if else if, switch case for, while, do while break, continue : System.in, args, JOptionPane for (,, ) @ vs. logic data method variable Data Data Flow (Type), ( ) @ Member field

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 배효철 th1g@nate.com 1 목차 표준입출력 파일입출력 2 표준입출력 표준입력은키보드로입력하는것, 주로 Scanner 클래스를사용. 표준출력은화면에출력하는메소드를사용하는데대표적으로 System.out.printf( ) 를사용 3 표준입출력 표준출력 : System.out.printlf() 4 표준입출력 Example 01 public static void

More information

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4 ALTIBASE HDB 6.5.1.5.10 Patch Notes 목차 BUG-46183 DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG-46249 [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4 BUG-46266 [sm]

More information

XSS Attack - Real-World XSS Attacks, Chaining XSS and Other Attacks, Payloads for XSS Attacks

XSS Attack - Real-World XSS Attacks, Chaining XSS and Other Attacks, Payloads for XSS Attacks XSS s XSS, s, May 25, 2010 XSS s 1 2 s 3 XSS s MySpace 사건. Samy (JS.Spacehero) 프로필 페이지에 자바스크립트 삽입. 스크립트 동작방식 방문자를 친구로 추가. 방문자의 프로필에 자바스크립트를 복사. 1시간 만에 백만 명이 친구등록. s XSS s 위험도가 낮은 xss 취약점을 다른 취약점과 연계하여

More information

Research & Technique Apache Tomcat RCE 취약점 (CVE ) 취약점개요 지난 4월 15일전세계적으로가장많이사용되는웹애플리케이션서버인 Apache Tomcat에서 RCE 취약점이공개되었다. CVE 취약점은 W

Research & Technique Apache Tomcat RCE 취약점 (CVE ) 취약점개요 지난 4월 15일전세계적으로가장많이사용되는웹애플리케이션서버인 Apache Tomcat에서 RCE 취약점이공개되었다. CVE 취약점은 W Research & Technique Apache Tomcat RCE 취약점 (CVE-2019-0232) 취약점개요 지난 4월 15일전세계적으로가장많이사용되는웹애플리케이션서버인 Apache Tomcat에서 RCE 취약점이공개되었다. CVE-2019-0232 취약점은 Windows 시스템의 Apache Tomcat 서버에서 enablecmdlinearguments

More information

Microsoft PowerPoint - Supplement-03-TCP Programming.ppt [호환 모드]

Microsoft PowerPoint - Supplement-03-TCP Programming.ppt [호환 모드] - Socket Programming in Java - 목차 소켓소개 자바에서의 TCP 프로그램작성방법 주요클래스와메소드 HTTP 프로토콜을이용한예제 에코프로그램 Q/A 에코프로그램 - EchoServer 에코프로그램 - EchoClient TCP Programming 1 소켓소개 IP, Port, and Socket 포트 (Port): 전송계층에서통신을수행하는응용프로그램을찾기위한주소

More information

Microsoft PowerPoint - Java7.pptx

Microsoft PowerPoint - Java7.pptx HPC & OT Lab. 1 HPC & OT Lab. 2 실습 7 주차 Jin-Ho, Jang M.S. Hanyang Univ. HPC&OT Lab. jinhoyo@nate.com HPC & OT Lab. 3 Component Structure 객체 (object) 생성개념을이해한다. 외부클래스에대한접근방법을이해한다. 접근제어자 (public & private)

More information

PowerPoint Template

PowerPoint Template 설치및실행방법 Jaewoo Shim Jun. 4. 2018 Contents SQL 인젝션이란 WebGoat 설치방법 실습 과제 2 SQL 인젝션이란 데이터베이스와연동된웹서버에입력값을전달시악의적동작을수행하는쿼리문을삽입하여공격을수행 SELECT * FROM users WHERE id= $_POST[ id ] AND pw= $_POST[ pw ] Internet

More information

게시판 스팸 실시간 차단 시스템

게시판 스팸 실시간 차단 시스템 오픈 API 2014. 11-1 - 목 차 1. 스팸지수측정요청프로토콜 3 1.1 스팸지수측정요청프로토콜개요 3 1.2 스팸지수측정요청방법 3 2. 게시판스팸차단도구오픈 API 활용 5 2.1 PHP 5 2.1.1 차단도구오픈 API 적용방법 5 2.1.2 차단도구오픈 API 스팸지수측정요청 5 2.1.3 차단도구오픈 API 스팸지수측정결과값 5 2.2 JSP

More information

혼자서일을다하는 JSP. 이젠일을 Servlet 과나눠서한다. JSP와서블릿의표현적인차이 - JSP는 <html> 내에서자바를사용할수있는수단을제공한다. - 서블릿은자바내에서 <html> 을작성할수있는수단을제공한다. - JSP나서블릿으로만웹페이지를작성하면자바와다양한코드가

혼자서일을다하는 JSP. 이젠일을 Servlet 과나눠서한다. JSP와서블릿의표현적인차이 - JSP는 <html> 내에서자바를사용할수있는수단을제공한다. - 서블릿은자바내에서 <html> 을작성할수있는수단을제공한다. - JSP나서블릿으로만웹페이지를작성하면자바와다양한코드가 혼자서일을다하는 JSP. 이젠일을 Servlet 과나눠서한다. JSP와서블릿의표현적인차이 - JSP는 내에서자바를사용할수있는수단을제공한다. - 서블릿은자바내에서 을작성할수있는수단을제공한다. - JSP나서블릿으로만웹페이지를작성하면자바와다양한코드가웹페이지내에뒤섞여있어서웹페이지의화면설계가점점어려워진다. - 서블릿이먼저등장하였으나, 자바내에

More information

제목 레이아웃

제목 레이아웃 웹해킹이라고무시하는것들보소 2017.07.10 RUBIYA805[AT]GMAIL[DOT]COM SQL Injection 끝나지않은위협 2017.07.10 RUBIYA805[AT]GMAIL[DOT]COM Who am I 정도원 aka rubiya Penetration tester Web application bughuter Pwned 20+ wargame @kr_rubiya

More information

Microsoft PowerPoint - 03-TCP Programming.ppt

Microsoft PowerPoint - 03-TCP Programming.ppt Chapter 3. - Socket in Java - 목차 소켓소개 자바에서의 프로그램작성방법 주요클래스와메소드 HTTP 프로토콜을이용한예제 에코프로그램 에코프로그램 - EchoServer 에코프로그램 - EchoClient Q/A 1 1 소켓소개 IP,, and Socket 포트 (): 전송계층에서통신을수행하는응용프로그램을찾기위한주소 소켓 (Socket):

More information

기술문서 작성 XXE Attacks 작성자 : 인천대학교 OneScore 김영성 I. 소개 2 II. 본문 2 가. XML external entities 2 나. XXE Attack 3 다. 점검방법 3 라.

기술문서 작성 XXE Attacks 작성자 : 인천대학교 OneScore 김영성 I. 소개 2 II. 본문 2 가. XML external entities 2 나. XXE Attack 3 다. 점검방법 3 라. 기술문서 14. 11. 10. 작성 XXE Attacks 작성자 : 인천대학교 OneScore 김영성 dokymania@naver.com I. 소개 2 II. 본문 2 가. XML external entities 2 나. XXE Attack 3 다. 점검방법 3 라. Exploit 5 마. 피해 6 III. 결론 6 가. 권고사항 6 I. 소개 가. 역자 본문서는

More information

PowerPoint Presentation

PowerPoint Presentation Package Class 3 Heeseung Jo 목차 section 1 패키지개요와패키지의사용 section 2 java.lang 패키지의개요 section 3 Object 클래스 section 4 포장 (Wrapper) 클래스 section 5 문자열의개요 section 6 String 클래스 section 7 StringBuffer 클래스 section

More information

02 C h a p t e r Java

02 C h a p t e r Java 02 C h a p t e r Java Bioinformatics in J a va,, 2 1,,,, C++, Python, (Java),,, (http://wwwbiojavaorg),, 13, 3D GUI,,, (Java programming language) (Sun Microsystems) 1995 1990 (green project) TV 22 CHAPTER

More information

<3035303432365FC8A8C6E4C0CCC1F620B0B3B9DF20BAB8BEC8B0A1C0CCB5E5C3D6C1BE28C0FAC0DBB1C7BBE8C1A6292E687770>

<3035303432365FC8A8C6E4C0CCC1F620B0B3B9DF20BAB8BEC8B0A1C0CCB5E5C3D6C1BE28C0FAC0DBB1C7BBE8C1A6292E687770> 개 요 홈페이지 해킹 현황 및 사례 홈페이지 개발시 보안 취약점 및 대책 주요 애플리케이션 보안 대책 결 론 참고자료 [부록1] 개발 언어별 로그인 인증 프로세스 예제 [부록2] 대규모 홈페이지 변조 예방을 위한 권고(안) [부록3] 개인정보의 기술적 관리적 보호조치 기준(안) [부록4] 웹 보안관련 주요 사이트 리스트 7000 6,478 6000 5000

More information

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures 단일연결리스트 (Singly Linked List) 신찬수 연결리스트 (linked list)? tail 서울부산수원용인 null item next 구조체복습 struct name_card { char name[20]; int date; } struct name_card a; // 구조체변수 a 선언 a.name 또는 a.date // 구조체 a의멤버접근 struct

More information

KYO_SCCD.PDF

KYO_SCCD.PDF 1. Servlets. 5 1 Servlet Model. 5 1.1 Http Method : HttpServlet abstract class. 5 1.2 Http Method. 5 1.3 Parameter, Header. 5 1.4 Response 6 1.5 Redirect 6 1.6 Three Web Scopes : Request, Session, Context

More information

<4D F736F F F696E74202D20C1A63234C0E520C0D4C3E2B7C228B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D20C1A63234C0E520C0D4C3E2B7C228B0ADC0C729205BC8A3C8AF20B8F0B5E55D> Power Java 제 24 장입출력 이번장에서학습할내용 스트림이란? 스트림의분류 바이트스트림 문자스트림 형식입출력 명령어행에서입출력 파일입출력 스트림을이용한입출력에대하여살펴봅시다. 스트림 (stream) 스트림 (stream) 은 순서가있는데이터의연속적인흐름 이다. 스트림은입출력을물의흐름처럼간주하는것이다. 스트림들은연결될수있다. 중간점검문제 1. 자바에서는입출력을무엇이라고추상화하는가?

More information

歯JavaExceptionHandling.PDF

歯JavaExceptionHandling.PDF (2001 3 ) from Yongwoo s Park Java Exception Handling Programming from Yongwoo s Park 1 Java Exception Handling Programming from Yongwoo s Park 2 1 4 11 4 4 try/catch 5 try/catch/finally 9 11 12 13 13

More information

Microsoft PowerPoint - 04-UDP Programming.ppt

Microsoft PowerPoint - 04-UDP Programming.ppt Chapter 4. UDP Dongwon Jeong djeong@kunsan.ac.kr http://ist.kunsan.ac.kr/ Dept. of Informatics & Statistics 목차 UDP 1 1 UDP 개념 자바 UDP 프로그램작성 클라이언트와서버모두 DatagramSocket 클래스로생성 상호간통신은 DatagramPacket 클래스를이용하여

More information

** 5 개이발생한주요소프트웨어별취약점세 EDB 번호취약점종류공격난이도공격위험도취약점이름소프트웨어이름

** 5 개이발생한주요소프트웨어별취약점세 EDB 번호취약점종류공격난이도공격위험도취약점이름소프트웨어이름 EDB 분석보고서 (016.01) 016.01.01~016.01.31 Exploit-DB(http://exploit-db.com) 에공개된취약점별로분류한정보입니다. 분석내용정리 ( 작성 : 펜타시큐리티시스템보안성평가팀 ) 016 년 1 월에공개된 Exploit-DB 의분석결과, SQL Injection 공격에대한취약점보고개수가가장많았습니다. 분석된 SQL Injection

More information

Spring Data JPA Many To Many 양방향 관계 예제

Spring Data JPA Many To Many 양방향 관계 예제 Spring Data JPA Many To Many 양방향관계예제 오라클자바커뮤니티 (ojc.asia, ojcedu.com) 엔티티매핑 (Entity Mapping) M : N 연관관계 사원 (Sawon), 취미 (Hobby) 는다 : 다관계이다. 사원은여러취미를가질수있고, 하나의취미역시여러사원에할당될수있기때문이다. 보통관계형 DB 에서는다 : 다관계는 1

More information

Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 11 년 10 월 26 일수요일

Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 11 년 10 월 26 일수요일 Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 Introduce Me!!! Job Jeju National University Student Ubuntu Korean Jeju Community Owner E-Mail: ned3y2k@hanmail.net Blog: http://ned3y2k.wo.tc Facebook: http://www.facebook.com/gyeongdae

More information

Microsoft PowerPoint 웹 연동 기술.pptx

Microsoft PowerPoint 웹 연동 기술.pptx 웹프로그래밍및실습 ( g & Practice) 문양세강원대학교 IT 대학컴퓨터과학전공 URL 분석 (1/2) URL (Uniform Resource Locator) 프로토콜, 호스트, 포트, 경로, 비밀번호, User 등의정보를포함 예. http://kim:3759@www.hostname.com:80/doc/index.html URL 을속성별로분리하고자할경우

More information

제이쿼리 (JQuery) 정의 자바스크립트함수를쉽게사용하기위해만든자바스크립트라이브러리. 웹페이지를즉석에서변경하는기능에특화된자바스크립트라이브러리. 사용법 $( 제이쿼리객체 ) 혹은 $( 엘리먼트 ) 참고 ) $() 이기호를제이쿼리래퍼라고한다. 즉, 제이쿼리를호출하는기호

제이쿼리 (JQuery) 정의 자바스크립트함수를쉽게사용하기위해만든자바스크립트라이브러리. 웹페이지를즉석에서변경하는기능에특화된자바스크립트라이브러리. 사용법 $( 제이쿼리객체 ) 혹은 $( 엘리먼트 ) 참고 ) $() 이기호를제이쿼리래퍼라고한다. 즉, 제이쿼리를호출하는기호 제이쿼리 () 정의 자바스크립트함수를쉽게사용하기위해만든자바스크립트라이브러리. 웹페이지를즉석에서변경하는기능에특화된자바스크립트라이브러리. 사용법 $( 제이쿼리객체 ) 혹은 $( 엘리먼트 ) 참고 ) $() 이기호를제이쿼리래퍼라고한다. 즉, 제이쿼리를호출하는기호 CSS와마찬가지로, 문서에존재하는여러엘리먼트를접근할수있다. 엘리먼트접근방법 $( 엘리먼트 ) : 일반적인접근방법

More information

10.ppt

10.ppt : SQL. SQL Plus. JDBC. SQL >> SQL create table : CREATE TABLE ( ( ), ( ),.. ) SQL >> SQL create table : id username dept birth email id username dept birth email CREATE TABLE member ( id NUMBER NOT NULL

More information

rmi_박준용_final.PDF

rmi_박준용_final.PDF (RMI) - JSTORM http://wwwjstormpekr (RMI)- Document title: Document file name: Revision number: Issued by: Document Information (RMI)- rmi finaldoc Issue Date: Status:

More information

문서 템플릿

문서 템플릿 HDSI 툴분석 [sql injection 기술명세서 ] Sql injection 기술명세서 Ver. 0.01 이문서는 sql injection 기술명세가범위입니다. Copyrights Copyright 2009 by CanvasTeam@SpeeDroot( 장경칩 ) All Rights Reserved. 장경칩의사전승인없이본내용의전부또는일부에대한복사, 전재,

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 실습문제 Chapter 05 데이터베이스시스템... 오라클로배우는데이터베이스개론과실습 1. 실습문제 1 (5 장심화문제 : 각 3 점 ) 6. [ 마당서점데이터베이스 ] 다음프로그램을 PL/SQL 저장프로시져로작성하고실행해 보시오. (1) ~ (2) 7. [ 마당서점데이터베이스 ] 다음프로그램을 PL/SQL 저장프로시져로작성하고실행해 보시오. (1) ~ (5)

More information

12-file.key

12-file.key 11 (String).. java.lang.stringbuffer. s String s = "abcd"; s = s + "e"; a b c d e a b c d e ,., "910359,, " "910359" " " " " (token) (token),, (delimiter). java.util.stringtokenizer String s = "910359,,

More information

Cluster management software

Cluster management software 자바네트워크프로그래밍 (OCJP 국제공인자격취득중심 ) 충북대학교 최민 기본예제 예외클래스를정의하고사용하는예제 class NewException extends Exception { public class ExceptionTest { static void methoda() throws NewException { System.out.println("NewException

More information

JSP 의내장객체 response 객체 - response 객체는 JSP 페이지의실행결과를웹프라우저로돌려줄때사용되는객체이다. - 이객체는주로켄텐츠타입이나문자셋등의데이터의부가정보 ( 헤더정보 ) 나쿠키 ( 다음에설명 ) 등을지정할수있다. - 이객체를사용해서출력의방향을다른

JSP 의내장객체 response 객체 - response 객체는 JSP 페이지의실행결과를웹프라우저로돌려줄때사용되는객체이다. - 이객체는주로켄텐츠타입이나문자셋등의데이터의부가정보 ( 헤더정보 ) 나쿠키 ( 다음에설명 ) 등을지정할수있다. - 이객체를사용해서출력의방향을다른 JSP 의내장객체 response 객체 - response 객체는 JSP 페이지의실행결과를웹프라우저로돌려줄때사용되는객체이다. - 이객체는주로켄텐츠타입이나문자셋등의데이터의부가정보 ( 헤더정보 ) 나쿠키 ( 다음에설명 ) 등을지정할수있다. - 이객체를사용해서출력의방향을다른 URL로바꿀수있다. 예 ) response.sendredirect("http://www.paran.com");

More information

금오공대 컴퓨터공학전공 강의자료

금오공대 컴퓨터공학전공 강의자료 C 프로그래밍프로젝트 Chap 14. 포인터와함수에대한이해 2013.10.09. 오병우 컴퓨터공학과 14-1 함수의인자로배열전달 기본적인인자의전달방식 값의복사에의한전달 val 10 a 10 11 Department of Computer Engineering 2 14-1 함수의인자로배열전달 배열의함수인자전달방식 배열이름 ( 배열주소, 포인터 ) 에의한전달 #include

More information

<4D F736F F F696E74202D20B5A5C0CCC5CDBAA3C0CCBDBA5F3130C1D6C2F75F31C2F7BDC32E >

<4D F736F F F696E74202D20B5A5C0CCC5CDBAA3C0CCBDBA5F3130C1D6C2F75F31C2F7BDC32E > Chapter 8 데이터베이스응용개발 목차 사용자인터페이스와도구들 웹인터페이스와데이터베이스 웹기초 Servlet 과 JSP 대규모웹응용개발 ASP.Net 8 장. 데이터베이스응용개발 (Page 1) 1. 사용자인터페이스와도구들 대부분의데이터베이스사용자들은 SQL을사용하지않음 응용프로그램 : 사용자와데이터베이스를연결 데이터베이스응용의구조 Front-end Middle

More information

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx #include int main(void) { int num; printf( Please enter an integer "); scanf("%d", &num); if ( num < 0 ) printf("is negative.\n"); printf("num = %d\n", num); return 0; } 1 학습목표 을 작성하면서 C 프로그램의

More information

PowerPoint Presentation

PowerPoint Presentation 객체지향프로그래밍 클래스, 객체, 메소드 ( 실습 ) 손시운 ssw5176@kangwon.ac.kr 예제 1. 필드만있는클래스 텔레비젼 2 예제 1. 필드만있는클래스 3 예제 2. 여러개의객체생성하기 4 5 예제 3. 메소드가추가된클래스 public class Television { int channel; // 채널번호 int volume; // 볼륨 boolean

More information

Spring Boot/JDBC JdbcTemplate/CRUD 예제

Spring Boot/JDBC JdbcTemplate/CRUD 예제 Spring Boot/JDBC JdbcTemplate/CRUD 예제 오라클자바커뮤니티 (ojc.asia, ojcedu.com) Spring Boot, Gradle 과오픈소스인 MariaDB 를이용해서 EMP 테이블을만들고 JdbcTemplate, SimpleJdbcTemplate 을이용하여 CRUD 기능을구현해보자. 마리아 DB 설치는다음 URL 에서확인하자.

More information

3장

3장 C H A P T E R 03 CHAPTER 03 03-01 03-01-01 Win m1 f1 e4 e5 e6 o8 Mac m1 f1 s1.2 o8 Linux m1 f1 k3 o8 AJAX

More information

JUNIT 실습및발표

JUNIT 실습및발표 JUNIT 실습및발표 JUNIT 접속 www.junit.org DownLoad JUnit JavaDoc API Document 를참조 JUNIT 4.8.1 다운로드 설치파일 (jar 파일 ) 을다운로드 CLASSPATH 를설정 환경변수에서설정 실행할클래스에서 import JUnit 설치하기 테스트실행주석 @Test Test 를실행할 method 앞에붙임 expected

More information

chap 5: Trees

chap 5: Trees 5. Threaded Binary Tree 기본개념 n 개의노드를갖는이진트리에는 2n 개의링크가존재 2n 개의링크중에 n + 1 개의링크값은 null Null 링크를다른노드에대한포인터로대체 Threads Thread 의이용 ptr left_child = NULL 일경우, ptr left_child 를 ptr 의 inorder predecessor 를가리키도록변경

More information

슬라이드 1

슬라이드 1 UNIT 16 예외처리 로봇 SW 교육원 3 기 최상훈 학습목표 2 예외처리구문 try-catch-finally 문을사용핛수있다. 프로그램오류 3 프로그램오류의종류 컴파일에러 (compile-time error) : 컴파일실행시발생 럮타임에러 (runtime error) : 프로그램실행시발생 에러 (error) 프로그램코드에의해서해결될수없는심각핚오류 ex)

More information

목차 BUG offline replicator 에서유효하지않은로그를읽을경우비정상종료할수있다... 3 BUG 각 partition 이서로다른 tablespace 를가지고, column type 이 CLOB 이며, 해당 table 을 truncate

목차 BUG offline replicator 에서유효하지않은로그를읽을경우비정상종료할수있다... 3 BUG 각 partition 이서로다른 tablespace 를가지고, column type 이 CLOB 이며, 해당 table 을 truncate ALTIBASE HDB 6.1.1.5.6 Patch Notes 목차 BUG-39240 offline replicator 에서유효하지않은로그를읽을경우비정상종료할수있다... 3 BUG-41443 각 partition 이서로다른 tablespace 를가지고, column type 이 CLOB 이며, 해당 table 을 truncate 한뒤, hash partition

More information

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3 Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3 Example 3.1 Files 3.2 Source code 3.3 Exploit flow

More information

SOFTBASE XFRAME DEVELOPMENT GUIDE SERIES HTML 연동가이드 서울특별시구로구구로 3 동한신 IT 타워 1215 호 Phone Fax Co

SOFTBASE XFRAME DEVELOPMENT GUIDE SERIES HTML 연동가이드 서울특별시구로구구로 3 동한신 IT 타워 1215 호 Phone Fax Co SOFTBASE XFRAME DEVELOPMENT GUIDE SERIES 2012.02.18 서울특별시구로구구로 3 동한신 IT 타워 1215 호 Phone 02-2108-8030 Fax 02-2108-8031 www.softbase.co.kr Copyright 2010 SOFTBase Inc. All rights reserved 목차 1 장 : HTML 연동개요...

More information

Microsoft PowerPoint 세션.ppt

Microsoft PowerPoint 세션.ppt 웹프로그래밍 () 2006 년봄학기 문양세강원대학교컴퓨터과학과 세션변수 (Session Variable) (1/2) 쇼핑몰장바구니 장바구니에서는사용자가페이지를이동하더라도장바구니의구매물품리스트의내용을유지하고있어야함 PHP 에서사용하는일반적인변수는스크립트의수행이끝나면모두없어지기때문에페이지이동시변수의값을유지할수없음 이러한문제점을해결하기위해서 PHP 에서는세션 (session)

More information

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 2012.11.23 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Document Distribution Copy Number Name(Role, Title) Date

More information

2장 변수와 프로시저 작성하기

2장  변수와 프로시저 작성하기 Chapter. RequestDispatcher 활용 요청재지정이란? RequestDispatcher 활용 요청재지정구현예제 Chapter.9 : RequestDispatcher 활용 1. 요청재지정이란? 클라이언트로부터요청받은 Servlet 프로그램이응답을하지않고다른자원에수행흐름을넘겨다른자원의처리결과를대신응답하는것또는다른자원의수행결과를포함하여응답하는것을요청재지정이라고한다.

More information

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

@OneToOne(cascade = = addr_id) private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a 1 대 1 단방향, 주테이블에외래키실습 http://ojcedu.com, http://ojc.asia STS -> Spring Stater Project name : onetoone-1 SQL : JPA, MySQL 선택 http://ojc.asia/bbs/board.php?bo_table=lecspring&wr_id=524 ( 마리아 DB 설치는위 URL

More information

신림프로그래머_클린코드.key

신림프로그래머_클린코드.key CLEAN CODE 6 11st Front Dev. Team 6 1. 2. 3. checked exception 4. 5. 6. 11 : 2 4 : java (50%), javascript (35%), SQL/PL-SQL (15%) : Spring, ibatis, Oracle, jquery ? , (, ) ( ) 클린코드를 무시한다면 . 6 1. ,,,!

More information

Microsoft Word - src.doc

Microsoft Word - src.doc IPTV 서비스탐색및콘텐츠가이드 RI 시스템운용매뉴얼 목차 1. 서버설정방법... 5 1.1. 서비스탐색서버설정... 5 1.2. 컨텐츠가이드서버설정... 6 2. 서버운용방법... 7 2.1. 서비스탐색서버운용... 7 2.1.1. 서비스가이드서버실행... 7 2.1.2. 서비스가이드정보확인... 8 2.1.3. 서비스가이드정보추가... 9 2.1.4. 서비스가이드정보삭제...

More information

var answer = confirm(" 확인이나취소를누르세요."); // 확인창은사용자의의사를묻는데사용합니다. if(answer == true){ document.write(" 확인을눌렀습니다."); else { document.write(" 취소를눌렀습니다.");

var answer = confirm( 확인이나취소를누르세요.); // 확인창은사용자의의사를묻는데사용합니다. if(answer == true){ document.write( 확인을눌렀습니다.); else { document.write( 취소를눌렀습니다.); 자바스크립트 (JavaScript) - HTML 은사용자에게인터페이스 (interface) 를제공하는언어 - 자바스크립트는서버로데이터를전송하지않고서할수있는데이터처리를수행한다. - 자바스크립트는 HTML 나 JSP 에서작성할수있고 ( 내부스크립트 ), 별도의파일로도작성이가능하다 ( 외 부스크립트 ). - 내부스크립트 - 외부스크립트

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 실습 1 배효철 th1g@nate.com 1 목차 조건문 반복문 System.out 구구단 모양만들기 Up & Down 2 조건문 조건문의종류 If, switch If 문 조건식결과따라중괄호 { 블록을실행할지여부결정할때사용 조건식 true 또는 false값을산출할수있는연산식 boolean 변수 조건식이 true이면블록실행하고 false 이면블록실행하지않음 3

More information

어댑터뷰

어댑터뷰 04 커스텀어댑터뷰 (Custom Adapter View) 커스텀어댑터뷰 (Custom Adapter View) 커스텀어댑터뷰 (Custom Adatper View) 란? u 어댑터뷰의항목하나는단순한문자열이나이미지뿐만아니라, 임의의뷰가될수 있음 이미지뷰 u 커스텀어댑터뷰설정절차 1 2 항목을위한 XML 레이아웃정의 어댑터정의 3 어댑터를생성하고어댑터뷰객체에연결

More information

PowerPoint Presentation

PowerPoint Presentation Package Class 1 Heeseung Jo 목차 section 1 패키지개요와패키지의사용 section 2 java.lang 패키지의개요 section 3 Object 클래스 section 4 포장 (Wrapper) 클래스 section 5 문자열의개요 section 6 String 클래스 section 7 StringBuffer 클래스 section

More information

Microsoft PowerPoint - CSharp-10-예외처리

Microsoft PowerPoint - CSharp-10-예외처리 10 장. 예외처리 예외처리개념 예외처리구문 사용자정의예외클래스와예외전파 순천향대학교컴퓨터학부이상정 1 예외처리개념 순천향대학교컴퓨터학부이상정 2 예외처리 오류 컴파일타임오류 (Compile-Time Error) 구문오류이기때문에컴파일러의구문오류메시지에의해쉽게교정 런타임오류 (Run-Time Error) 디버깅의절차를거치지않으면잡기어려운심각한오류 시스템에심각한문제를줄수도있다.

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 HTML5 웹프로그래밍입문 부록. 웹서버구축하기 1 목차 A.1 웹서버시스템 A.2 PHP 사용하기 A.3 데이터베이스연결하기 2 A.1 웹서버시스템 3 웹서버의구축 웹서버컴퓨터구축 웹서버소프트웨어설치및실행 아파치 (Apache) 웹서버가대표적 서버실행프로그램 HTML5 폼을전달받아처리 PHP, JSP, Python 등 데이터베이스시스템 서버측에데이터를저장및효율적관리

More information

PowerPoint Presentation

PowerPoint Presentation Class - Property Jo, Heeseung 목차 section 1 클래스의일반구조 section 2 클래스선언 section 3 객체의생성 section 4 멤버변수 4-1 객체변수 4-2 클래스변수 4-3 종단 (final) 변수 4-4 멤버변수접근방법 section 5 멤버변수접근한정자 5-1 public 5-2 private 5-3 한정자없음

More information

Ext JS À¥¾ÖÇø®ÄÉÀ̼ǰ³¹ß-³¹Àå.PDF

Ext JS À¥¾ÖÇø®ÄÉÀ̼ǰ³¹ß-³¹Àå.PDF CHAPTER 2 (interaction) Ext JS., HTML, onready, MessageBox get.. Ext JS HTML CSS Ext JS.1. Ext JS. Ext.Msg: : Ext Ext.get: DOM 22 CHAPTER 2 (config). Ext JS.... var test = new TestFunction( 'three', 'fixed',

More information

Java ...

Java ... 컴퓨터언어 1 Java 제어문 조성일 조건문 : if, switch 어떠한조건을조사하여각기다른명령을실행 if 문, switch 문 if 문 if - else 문형식 if 문형식 if ( 조건식 ) { 명령문 1; 명령문 2;... if ( 조건식 ) { 명령문 1; 명령문 2;... else { 명령문 a; 명령문 b;... 예제 1 정수를입력받아짝수와홀수를판별하는프로그램을작성하시오.

More information

Secure Programming Lecture1 : Introduction

Secure Programming Lecture1 : Introduction Malware and Vulnerability Analysis Lecture3-2 Malware Analysis #3-2 Agenda 안드로이드악성코드분석 악성코드분석 안드로이드악성코드정적분석 APK 추출 #1 adb 명령 안드로이드에설치된패키지리스트추출 adb shell pm list packages v0nui-macbook-pro-2:lecture3 v0n$

More information

제11장 프로세스와 쓰레드

제11장 프로세스와 쓰레드 제9장자바쓰레드 9.1 Thread 기초 (1/5) 프로그램 명령어들의연속 (a sequence of instruction) 프로세스 / Thread 실행중인프로그램 (program in execution) 프로세스생성과실행을위한함수들 자바 Thread 2 9.1 Thread 기초 (2/5) 프로세스단위작업의문제점 프로세스생성시오버헤드 컨텍스트스위치오버헤드

More information

Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Cras

Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Cras Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Crash Unity SDK... Log & Crash Search. - Unity3D v4.0 ios

More information

<C0CCBCBCBFB52DC1A4B4EBBFF82DBCAEBBE7B3EDB9AE2D313939392D382E687770>

<C0CCBCBCBFB52DC1A4B4EBBFF82DBCAEBBE7B3EDB9AE2D313939392D382E687770> i ii iii iv v vi 1 2 3 4 가상대학 시스템의 국내외 현황 조사 가상대학 플랫폼 개발 이상적인 가상대학시스템의 미래상 제안 5 웹-기반 가상대학 시스템 전통적인 교수 방법 시간/공간 제약을 극복한 학습동기 부여 교수의 일방적인 내용전달 교수와 학생간의 상호작용 동료 학생들 간의 상호작용 가상대학 운영 공지사항,강의록 자료실, 메모 질의응답,

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 Web server porting 2 Jo, Heeseung Web 을이용한 LED 제어 Web 을이용한 LED 제어프로그램 web 에서데이터를전송받아타겟보드의 LED 를조작하는프로그램을작성하기위해다음과같은소스파일을생성 2 Web 을이용한 LED 제어 LED 제어프로그램작성 8bitled.html 파일을작성 root@ubuntu:/working/web# vi

More information

JMF2_심빈구.PDF

JMF2_심빈구.PDF JMF JSTORM http://wwwjstormpekr Issued by: < > Document Information Document title: Document file name: Revision number: Issued by: JMF2_ doc Issue Date: Status: < > raica@nownurinet

More information

PowerPoint Presentation

PowerPoint Presentation 객체지향프로그래밍 오류처리 손시운 ssw5176@kangwon.ac.kr 오류메시지를분석한다. 오류메시지에서많은내용을알수있다. 2 디버깅 디버거를사용하면프로그램에서쉽게오류를감지하고진단할수있다. 디버거는중단점을설정하여서프로그램의실행을제어할수있으며문장 단위로실행하거나변수의값을살펴볼수있다. 3 이클립스에서디버깅 4 이클립스에서디버깅 5 이클립스의디버깅명령어 6 예외처리

More information

- JPA를사용하는경우의스프링설정파일에다음을기술한다. <bean id="entitymanagerfactory" class="org.springframework.orm.jpa.localentitymanagerfactorybean" p:persistenceunitname=

- JPA를사용하는경우의스프링설정파일에다음을기술한다. <bean id=entitymanagerfactory class=org.springframework.orm.jpa.localentitymanagerfactorybean p:persistenceunitname= JPA 와 Hibernate - 스프링의 JDBC 대신에 JPA를이용한 DB 데이터검색작업 - JPA(Java Persistence API) 는자바의 O/R 매핑에대한표준지침이며, 이지침에따라설계된소프트웨어를 O/R 매핑프레임워크 라고한다. - O/R 매핑 : 객체지향개념인자바와관계개념인 DB 테이블간에상호대응을시켜준다. 즉, 객체지향언어의인스턴스와관계데이터베이스의레코드를상호대응시킨다.

More information

교육2 ? 그림

교육2 ? 그림 Interstage 5 Apworks EJB Application Internet Revision History Edition Date Author Reviewed by Remarks 1 2002/10/11 2 2003/05/19 3 2003/06/18 EJB 4 2003/09/25 Apworks5.1 [ Stateless Session Bean ] ApworksJava,

More information

JAVA PROGRAMMING 실습 09. 예외처리

JAVA PROGRAMMING 실습 09. 예외처리 2015 학년도 2 학기 예외? 프로그램실행중에발생하는예기치않은사건 예외가발생하는경우 정수를 0으로나누는경우 배열의크기보다큰인덱스로배열의원소를접근하는경우 파일의마지막부분에서데이터를읽으려고하는경우 예외처리 프로그램에문제를발생시키지않고프로그램을실행할수있게적절한조치를취하는것 자바는예외처리기를이용하여예외처리를할수있는기법제공 자바는예외를객체로취급!! 나뉨수를입력하시오

More information

강의 개요

강의 개요 DDL TABLE 을만들자 웹데이터베이스 TABLE 자료가저장되는공간 문자자료의경우 DB 생성시지정한 Character Set 대로저장 Table 생성시 Table 의구조를결정짓는열속성지정 열 (Clumn, Attribute) 은이름과자료형을갖는다. 자료형 : http://dev.mysql.cm/dc/refman/5.1/en/data-types.html TABLE

More information

DBMS & SQL Server Installation Database Laboratory

DBMS & SQL Server Installation Database Laboratory DBMS & 조교 _ 최윤영 } 데이터베이스연구실 (1314 호 ) } 문의사항은 cyy@hallym.ac.kr } 과제제출은 dbcyy1@gmail.com } 수업공지사항및자료는모두홈페이지에서확인 } dblab.hallym.ac.kr } 홈페이지 ID: 학번 } 홈페이지 PW:s123 2 차례 } } 설치전점검사항 } 설치단계별설명 3 Hallym Univ.

More information

슬라이드 1

슬라이드 1 Pairwise Tool & Pairwise Test NuSRS 200511305 김성규 200511306 김성훈 200614164 김효석 200611124 유성배 200518036 곡진화 2 PICT Pairwise Tool - PICT Microsoft 의 Command-line 기반의 Free Software www.pairwise.org 에서다운로드후설치

More information

서현수

서현수 Introduction to TIZEN SDK UI Builder S-Core 서현수 2015.10.28 CONTENTS TIZEN APP 이란? TIZEN SDK UI Builder 소개 TIZEN APP 개발방법 UI Builder 기능 UI Builder 사용방법 실전, TIZEN APP 개발시작하기 마침 TIZEN APP? TIZEN APP 이란? Mobile,

More information

JavaGeneralProgramming.PDF

JavaGeneralProgramming.PDF , Java General Programming from Yongwoo s Park 1 , Java General Programming from Yongwoo s Park 2 , Java General Programming from Yongwoo s Park 3 < 1> (Java) ( 95/98/NT,, ) API , Java General Programming

More information

4. #include <stdio.h> #include <stdlib.h> int main() { functiona(); } void functiona() { printf("hihi\n"); } warning: conflicting types for functiona

4. #include <stdio.h> #include <stdlib.h> int main() { functiona(); } void functiona() { printf(hihi\n); } warning: conflicting types for functiona 이름 : 학번 : A. True or False: 각각항목마다 True 인지 False 인지적으세요. 1. (Python:) randint 함수를사용하려면, random 모듈을 import 해야한다. 2. (Python:) '' (single quote) 는한글자를표현할때, (double quote) 는문자열을표현할때사용한다. B. 다음에러를수정하는방법을적으세요.

More information

초보자를 위한 C# 21일 완성

초보자를 위한 C# 21일 완성 C# 21., 21 C#., 2 ~ 3 21. 2 ~ 3 21.,. 1~ 2 (, ), C#.,,.,., 21..,.,,, 3. A..,,.,.. Q&A.. 24 C#,.NET.,.,.,. Visual C# Visual Studio.NET,..,. CD., www. TeachYour sel f CSharp. com., ( )., C#.. C# 1, 1. WEEK

More information

2) 활동하기 활동개요 활동과정 [ 예제 10-1]main.xml 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.

2) 활동하기 활동개요 활동과정 [ 예제 10-1]main.xml 1 <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android 2 xmlns:tools=http://schemas.android. 10 차시파일처리 1 학습목표 내장메모리의파일을처리하는방법을배운다. SD 카드의파일을처리하는방법을배운다. 2 확인해볼까? 3 내장메모리파일처리 1) 학습하기 [ 그림 10-1] 내장메모리를사용한파일처리 2) 활동하기 활동개요 활동과정 [ 예제 10-1]main.xml 1

More information

SKINFOSEC-CHR-028-ASP Mssql Cookie Sql Injection Tool 분석 보고서.doc

SKINFOSEC-CHR-028-ASP Mssql Cookie Sql Injection Tool 분석 보고서.doc Asp Mssql Sql Injection Tool 분석보고서 이재곤 (x0saver@gmail.com) SK Infosec Co., Inc MSS 사업본부 / 침해대응센터모의해킹파트 Table of Contents 1. 개요... 3 2. 구성... 3 3. 분석... 4 3.1. 기능분석... 4 4. 공격원리...14 4.1 기본공격원리...14 4.2

More information

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

Microsoft PowerPoint 자바-기본문법(Ch2).pptx 자바기본문법 1. 기본사항 2. 자료형 3. 변수와상수 4. 연산자 1 주석 (Comments) 이해를돕기위한설명문 종류 // /* */ /** */ 활용예 javadoc HelloApplication.java 2 주석 (Comments) /* File name: HelloApplication.java Created by: Jung Created on: March

More information

서블릿의라이프사이클 뇌를자극하는 JSP & Servlet

서블릿의라이프사이클 뇌를자극하는 JSP & Servlet 서블릿의라이프사이클 뇌를자극하는 JSP & Servlet Contents v 학습목표 서블릿클래스로부터서블릿객체가만들어지고, 서블릿객체가초기화되어서서블릿이되고, 서블릿이사용되고, 최종적으로소멸되기까지의전과정을서블릿의라이프사이클이라고한다. 이장에서는서브릿의라이프사이클에관련된프로그래밍기술을배워보자. v 내용 서블릿의라이프사이클 서블릿클래스의 init 메서드의 destroy

More information

목차 INDEX JSON? - JSON 개요 - JSONObject - JSONArray 서울시공공데이터 API 살펴보기 - 요청인자살펴보기 - Result Code - 출력값 HttpClient - HttpHelper 클래스작성 - JSONParser 클래스작성 공공

목차 INDEX JSON? - JSON 개요 - JSONObject - JSONArray 서울시공공데이터 API 살펴보기 - 요청인자살펴보기 - Result Code - 출력값 HttpClient - HttpHelper 클래스작성 - JSONParser 클래스작성 공공 메신저의새로운혁신 채팅로봇 챗봇 (Chatbot) 입문하기 소 이 메 속 : 시엠아이코리아 름 : 임채문 일 : soulgx@naver.com 1 목차 INDEX JSON? - JSON 개요 - JSONObject - JSONArray 서울시공공데이터 API 살펴보기 - 요청인자살펴보기 - Result Code - 출력값 HttpClient - HttpHelper

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 System Software Experiment 1 Lecture 5 - Array Spring 2019 Hwansoo Han (hhan@skku.edu) Advanced Research on Compilers and Systems, ARCS LAB Sungkyunkwan University http://arcs.skku.edu/ 1 배열 (Array) 동일한타입의데이터가여러개저장되어있는저장장소

More information

Microsoft Word - SKINFOSEC-CHR-026- Mass SQL Injection 탐지 우회분석 보고서.doc

Microsoft Word - SKINFOSEC-CHR-026- Mass SQL Injection 탐지 우회분석 보고서.doc 분석보고서 이동현 (dhclub20@naver.com) SK Infosec Co., Inc MSS 사업본부침해대응팀모의해킹파트 Table of Contents 1. 개요... 3 1.1. 배경... 3 1.2. 목적... 3 2. 공격분석... 4 2.1. Cookie Injection... 4 2.2. Cookie Injection의발생원인... 5 2.3.

More information

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CC0E7B0EDB0FCB8AE5C53746F636B5F4D616E D656E74732E637070>

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CC0E7B0EDB0FCB8AE5C53746F636B5F4D616E D656E74732E637070> 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include "QuickSort.h" 7 using namespace std; 8 9 10 Node* Queue[100]; // 추가입력된데이터를저장하기위한 Queue

More information