웹에서 입력창에 마법을 부릴 때 접근성이 훼손되면 싫다.

나는 마우스를 쓰는 걸 엄청 싫어해서 브라우저에도 pentadactyl1이라는 플러그인을 설치해서 쓴다. 이 플러그인은 웹 접근성이 떨어질 수록 이상하게 작동하는 문제가 있다. 예를 들어 코드 편집을 할 때 자동으로 인덴트를 해주는 경우 엔터가 두 번 입력된다든가.

하지만 오늘 WordPress의 CSS를 수정하다가 굉장히 짜증나는 걸 발견했다. 코드 하이라이팅을 해주기 위해 textarea에 입력하는 값들을 모두 후킹해서 화면 위에 덮어씌워진 pre태그 안에 쑤셔넣는다. 그래서 textarea는 비어있게 된다.

Pentadactyl은 vim 사용자를 위해 텍스트 입력중에 C-t를 누르면 그 입력창을 vim처럼 쓸 수 있게 해준다. hjkl로 이동도 되고 비주얼 블럭도 잡힌다. 그런데 CSS 편집중에 이 기능을 사용하지 아무런 입력도 되지 않고 이동도 되지 않아 개발자 도구를 꺼내서 이런 마법을 부려놓은 걸 알아냈다.
C-i를 누르면 입력창의 내용을 임시파일로 복사한 후 외부 편집기로 열어주는데 역시나 빈 내용 뿐이었다.
워드프레스는 웹 접근성을 엄청나게 따지고 접근성을 훼손하는 경우에는 접근성모드라는 것을 제공한다. 하지만 플러그인 제작자는 그럴 의무가 없다. 그래서 나는 불편을 겪고 아마 시각장애인들도 불편을 겪을 것이다.

요즘 웹을 한다는 어린 개발자들을 보면 접근성에 대해 말할 때 “그냥 잘 보이기만 하면 되지 그런 걸 왜 고려해요?”라고 말하는 사람들이 있다. 심지어 학교에서 HTML을 가르칠 때도 h1~6 태그의 의미를 가르치지 않고 그냥 글자 크기를 키워주는 태그라고 가르친다. 저렇게 가르칠 거면 차라리 가르치지 말았으면 하는 생각이다.


  1. http://5digits.org/pentadactyl/에서 제공하는 플러그인인데 Vim 사용자라면 꽤나 익숙하게 mouseless 브라우징을 할 수 있다.
    vimparator라는 플러그인이 더 유명하지만 이건 기능이 다양하지 않아서 Geek들은 pentadactyl을 더 좋아한다. 

HTTP에서 보안을 조금이나마 강화시키는 헤더들

오늘 STS(Strict-Transport-Security)를 적용하려고 검색을 하다가 몇 가지 처음 보는 헤더들을 찾았다. 이 글에 자세히 설명이 나와있는데 대충 적어보면 이렇다.

1. Content-Security-Policy

누군가 페이지에 외부 스크립트 등을 걸어서 XSS 공격을 할 수 있기 때문에 페이지에서 허용할 origin을 지정할 수 있다. Content의 종류는 아래와 같다.

  1. script-src: JavaScript code (이 헤더를 사용하는 가장 큰 이유다)
  2. connect-src: XMLHttpRequest, WebSockets, and EventSource.
  3. font-src: fonts
  4. frame-src: frame ulrs
  5. img-src: images
  6. media-src: audio & video
  7. object-src: Flash (and other plugins)
  8. style-src: CSS

자신의 사이트와 구글의 각종 스크립트들만 허용하고 싶다면 아래와 같이 적어주면 된다.

Content-Security-Policy: script-src 'self' https://apis.google.com

2. X-Frame-Options

가끔 누군가가 자신의 사이트와 비슷한 도메인을 사서 아무 내용도 없이 자신의 사이트만 전체 크기의 프레임으로 박아놓는 짓을 한다는 글을 몇 번 본 적이 있다. 접근하는 유저만 엄청 끌어모은 다음 나중에 갑자기 내용을 바꿔서 날로먹는 방법이라는데 아무튼 이런 짓을 막을 수 있게 자신의 페이지가 Frame 안에 들어가는 것을 방지하게 해준다. Clickjacking도 막을 수 있겠다.

사용 방법은 아래와 같이 3가지가 있다.

  • X-Frame-Options: DENY (프레임 안에 절대 들어가지 못하게 한다)
  • X-Frame-Options: SAMEORIGIN (같은 origin일 경우에만 허용한다)
  • X-Frame-Options: ALLOW FROM hxtp://some-domain.com (특정 origin에서만 허용한다)

3. X-Content-Type-Options

Github에서 잘 쓰고 있다고 하는데 jpg 확장자로 js파일을 올려 우회를 한 후에 script 태그에 src로 넣는 수법을 방지하는 헤더다. 이 헤더를 넣으면 MIMETYPE과 다르게 사용하지 못하게 한다. nosniff를 넣어주면 활성화가 된다.

4. Strict-Transport-Security

내가 오늘 하려고 했던 STS다. SSL strip 공격을 막기 위해 나온 헤더인데 이 헤더를 받게 되면 브라우저는 다음에 접속할 땐 URL이 http로 지정되어있어도 무시하고 무조건 https로 접속하게 된다. 이런 방법으로 SSL strip 공격을 피할 수 있게 된다.(단, 한 번이라도 이미 접속은 한 상태여야 한다)

사용방법은 그냥 쿠키 지정하듯이 max-age를 초단위로 입력해주면 된다. includeSubDomains를 넣어주면 서브도메인들에도 적용이 되지만 나는 SSL 인증서가 와일드카드가 아니라 그건 뺐다.

참고로 오늘 실험해본 결과 HTTP 통신을 하고 있을 때는 이 헤더를 무시하게 된다. 꼭 301이나 302 리다이렉트를 해서 HTTPS를 사용하게 한 후 이 헤더를 넣자(둘 다 넣어도 상관은 없지만 HTTPS에서 이 헤더를 꼭 한 번은 받아야 한다).

2014/08/02 추가:
STS를 적용하게 되면 해당 도메인에 대한 모든 HTTP 연결이 포트와 관계없이 HTTPS로 전환된다.
다른 포트에서 테스트 앱을 돌리거나 할 때는 IP를 이용해 접속하거나 해야 SSL 오류등이 뜨지 않는다.

uWSGI에서 thread 활성화

며칠 전에 웹서버 환경을 apache2, php5, mod_wsgi에서 nginx, php5-fpm, uwsgi로 바꿨는데 오늘 확인해보니 flask 앱중 하나가 계속 DB를 잡고 놔주질 않아서 Lock이 걸린 채로 서비스가 동작하질 않고 있었다.
uwsgi를 끄면 lock이 해제되는 걸 봐서 uwsgi로 돌리고 있던 게 문제인게 확실한데 테스트 해보면 잘 돌아가서 삽질을 또 엄청 했다.

확인 해보니 계산이 많이 필요한 작업은 스레드를 따로 돌려놨는데 이게 그냥 돌리면 돌아가지만 uwsgi 위에선 전혀 돌지 않고 있었다. 찾아보니 uwsgi는 기본적으로 멀티스레드가 꺼져 있었다. 실행 할 때 --enable-threads를 붙여서 실행해야 하고 ini파일에선 enable-threads = true라는 한 줄을 추가해주면 된다. 이제서야 정상적으로 돌아간다.

최근 nginx로 바꾸면서 익숙하지 않은 걸 여러 개 접하다 보니 삽질을 많이 하는 것 같다.
아직도 내가 찾지 못한 문제가 있을 것만 같아 두렵다.