Let’s Encrypt 使用方法

Let’s Encryptとは

「インターネットを介した安全な通信を行う際の、経済面・技術面・教育面での障壁を減らす」を使命としている、非営利団体ISRGが開発したサービス
無料、簡単にWEBサイトをSSL化できる

 

インストール

Pythonインストール
yum install certbot certbot-apache
# yum install scl-utils python27 python27-python-tools
# scl enable python27 bash

 

certbotインストール

certbot=Let’s Encryptが提供する証明書発行・更新ツール

# cd /usr/local
# git clone https://github.com/letsencrypt/letsencrypt

 

certbot-autoインストール

certbot-auto=Let’s Encryptが提供する証明書発行・更新ツール
Let’s Encryptから証明書を取得し、サーバのHTTPSを有効化する

# curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto
# chmod 700 /usr/bin/certbot-auto

 

証明書生成

apacheを停止しておく事

通常

# letsencrypt/letsencrypt-auto certonly -a standalone -d ドメイン名
# letsencrypt/letsencrypt-auto certonly -a standalone -d office-yone.com

DNS使用

certbot certonly
–manual

サブドメイン用
–domain *.office-yone.com

メインドメイン用
–domain office-yone.com

–email yone@office-yone.com
–agree-tos
–manual-public-ip-logging-ok
–preferred-challenges dns-01
–server https://acme-v02.api.letsencrypt.org/directory

実行後メッセージ
Please deploy a DNS TXT record under the name

_acme-challenge.office-yone.com with the following value:

↓をDNS登録(TXTレコード)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ドメインを複数指定した場合、複数DNS登録する
Before continuing, verify the record is deployed.

結果

↓ に証明書、秘密鍵が生成される
/etc/letsencrypt/live/office-yone.com/
└cert.pem
└privkey.pem
└chain.pem

 

設定

証明書設定

※ /etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/letsencrypt/live/office-yone.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/office-yone.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/office-yone.com/chain.pem

設定後、apacheを起動しておく事


Let’s Encryptの証明期限は3カ月

 

WEBサイトのリンク修正

上記設定によりSSL化は完了。

サイト内で「Http://~」でリンクを張っている場合、
上記画像の様に「保護された通信」とならず、「!」が表示されている場合は、「Https://~」に変更する

 

HTTP→HTTPSへリダイレクト

.htaccessファイル
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

 

証明書の自動定期更新

# crontab -e
00 04 01 * * ~/certbot-auto renew ̠–force-renew && service httpd graceful
毎月1日4:00にcertbot-autoを定期実行

Linux CRON」参照

reCAPTCHA認証

準備

キー取得

reCAPTCHAのサイト登録のページでキーを取得
https://www.google.com/recaptcha/admin


googleのアドレスでないといけない
xamppで実行する場合のアドレスは「127.0.0.1」
URLもlocalhostでなく127.0.0.1/~でないとエラーとなる
※xamppでもバーチャルホストにてドメインを設定した場合はそのドメインで使用可

実装

クライアント側

<html>
<head>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
 function validateRecaptcha ( code ) {
  if ( !!code ) {
   var form = document.querySelector(".recaptcha");
   form.removeAttribute('disabled');
  }
 }
</script>
</head>
<body>

<form action="server.php" method="post" enctype="multipart/form-data">
  <div
   class="g-recaptcha"
   data-callback="validateRecaptcha"
   キー取得で取得したSiteKeyを設定
   data-sitekey="XXXXXXXXXXXXXXXXXXXX">
  </div>

  <input name="test" value="test" />
  <input type="submit" name="my_submit" value="送信" id="btnSubmit"
   class="recaptcha" disabled />
</form>

</body>
</html>

サーバー側

<?php
クライアント側からのreCAPTCHAパラメータ(SiteKey)を取得
$recaptcha = htmlspecialchars($_POST['g-recaptcha-response'], ENT_QUOTES, 'UTF-8');

if(isset($recaptcha)){
 $captcha = $recaptcha;
}else{
 $captcha = "";
 echo "captchaエラー";
 exit;
}
キー取得で取得したSecretKeyを設定
$secretKey = "XXXXXXXXXXXXXXXXXXXX";

SiteKeyとSecretKeyを照合
$resp = @file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret={$secretKey}&response={$captcha}");
$resp_result = json_decode($resp, true);

if(intval($resp_result['success']) !== 1) {
 echo('NG');
}else{
 echo('OK');
}

サーバー証明書

OpenSSL

暗号化通信ライブラリ
SSL/TLSのツールキット

秘密鍵作成

電子証明書/秘密鍵」参照

openssl
RSA方式の秘密鍵を作成
genrsa
鍵の長さ=2048bit
2048
秘密鍵ファイル名
> test.key

CSR作成

電子証明書/CSR」参照
> openssl req
-new
秘密鍵ファイル名
-key test.key
CSRファイル名
-out test.csr
-subj "
 /C=JP
 /ST=Hyogo
 /L=Nishinomiya
 /O=Example Corp.
 /DC=jp
 識別名(CommonName)=ドメイン名
 /CN=www.example.jp"

設定ファイルを読み込んでのCSR作成

設定ファイル作成

設定ファイルを複製
C:\xampp\apache\conf\openssl.cnf

C:\xampp\apache\conf\openssl-san.cnf

末尾に以下を追加
[SAN]
subjectAltName = @alt_names

[alt_names]
DNS.1=localhost
DNS.2=test

CSR作成

> openssl req
-newkey rsa:4096
秘密鍵ファイル名
-keyout test.key
-x509
-nodes
CSRファイル名
-out test.csr
識別名(CommonName)=ドメイン名
-subj "//CN=test"
-reqexts SAN
-extensions SAN
設定ファイルを指定
-config openssl-san.cnf
-days 3650

証明書作成

SSLサーバー証明書、公開鍵
電子証明書/公開鍵」参照
openssl x509
-req
有効期間=10年
-days 3650
秘密鍵ファイル名
-signkey test.key
CSRファイル名
< test.csr
証明書ファイル名
> test.crt

PKCS12(pfx)形式へ変換

openssl pkcs12
-export
証明書ファイル名
-in test.crt
秘密鍵ファイル名
-inkey test.key
個人情報交換ファイル名
-out keystore.pfx
-name test

SSH用認証暗号鍵

ssh-keygen -t rsa
対話形式での質問に全て「Enter」

~/.ssh に以下の暗号鍵が生成される
id_rsa id_rsa.pub

less id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAo9vL2+xbs4NU53fFds+iuM7b749jVCjz0x3Ok4ZOKoSGODxq
NPhkDSM7I3dWWFeV4kXyiFA3xObTbto71xRvivW/NwyPw6DphNcutEDAVIeXIEX+

PZ6HRKwK8yD+OzcJNmdHf8cSeT1TLhp7t58HQgD8lfcdgjtyo+lIk0B3fuyIqpE1
+b6ECfIXG1s92zIstIxxT1gWGrj4VaDCiU4/0dND6TpF7JlYBA==
-----END RSA PRIVATE KEY-----

JAVA KeyTool

Javaが提供する鍵と証明書の管理ツール

個人情報交換ファイル作成

> keytool
キーペアを作成
-genkey
証明書・鍵のKeyStore内での識別名
-alias test
-storetype PKCS12
暗号化方式
-keyalg RSA
-keysize 2048
ファイル名
-keystore keystore.p12
証明書の有効日数
-validity 3650
keystore.p12というファイルが作成される

証明書の登録

keytool
-import
-keystore "C:\Program Files\Java\jreX.X.X\lib\security\cacerts"
-file "test.crt"
-storepass "changeit"
-alias test

証明書の削除

keytool
-delete
-keystore "C:\Program Files\Java\jreX.X.X\lib\security\cacerts"
-storepass "changeit"
-alias test

証明書の内容表示

keytool
-list -v
-keystore "C:\Program Files\Java\jreX.X.X\lib\security\cacerts"
-storepass "changeit"
※管理者権限で実行
結果
別名: test
作成日: 2017/04/29
エントリ・タイプ: trustedCertEntry
所有者: CN=test, O=Internet Widgits Pty Ltd, ST=Some-State, C=JP
発行者: CN=test, O=Internet Widgits Pty Ltd, ST=Some-State, C=JP
シリアル番号: b4b537f59b612674
有効期間の開始日: ~ 終了日: ~
証明書のフィンガプリント:
  MD5: ~
  SHA1: ~
  SHA256: ~
  署名アルゴリズム名: SHA256withRSA
  バージョン: 1

hydra 使用方法

hydraとは

認証サイトに対するユーザー名/パスワードの総当たりチェックツール
・FTP
・HTTP/HTTPS
・SMTP
等のプロトコルに対応
CVS、SVN等のアプリにも使用可能

設定

インストール

sudo apt install hydra

sudo apt install -y libssl-dev libssh-dev libidn11-dev libpcre3-dev libgtk2.0-dev libmysqlclient-dev libpq-dev libsvn-dev firebird-dev

実行

hydra [-l LOGIN | -L FILE] -P FILE

ユーザ名指定、パスワードファイル利用

hydra -l (ユーザ名) -P pwlist.txt

ユーザ名ファイル、パスワードファイル利用

hydra -L usrlist.txt -P pwlist.txt

パスワードリスト生成

crunchインストール

sudo apt install crunch

パスワード生成

crunch (最小文字数) (最大文字数) (仕様文字列)

小文字英字(文字列指定無し)で3桁
crunch 3 3
→aaa,aab,aac・・・

数字、小文字英字で1~3桁
crunch 1 3 abcdefghijklmnopqrstuvwxyz0123456789
→1aa,1ab,1ac・・・

数字、英字、記号で1~3桁
crunch 1 3 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_+=~`[]{}|\:;"'<>,.?/

テキストファイルに出力

crunch (最小文字数) (最大文字数) -o (出力対象ファイル)
例 crunch 3 3 -o pwlist.txt

暗号化技術

可逆/不可逆

可逆暗号

複合できる暗号

不可逆暗号

複合できない暗号

不可逆暗号の使い道

保存時、パスワード不可逆暗号して保存(1),
認証時、再度不可逆暗号化(2)して、(1)と照合
(1) (2)の時、認証OK
保存してある暗号を見られても安全

ハッシュ関数

暗号化に用いる代表的な技術
特定の文字列(引数)に対して、適当な値(ハッシュ値)を返す関数
引数が同じであれば常に同じハッシュ値を返す
ハッシュ値から引数を割り出す事はかなり難しい

SHA-256

ハッシュ関数の1つ
任意の長さの文字列(引数)に対して常に256ビットのハッシュ値を返す

通信方式

共通鍵暗号方式

securekey_common
共通鍵で暗号化されたデータは共通鍵でしか複合できない
暗号化プログラム=複合化プログラム=共通鍵

公開鍵暗号方式

PKI
Public Key Infrastructure

securekey_public

送信者:公開鍵を使って暗号化してデータ送信。
受信者:秘密鍵を使って複合化してデータ受信。
複合できるのはを持つ受信者だけ

秘密鍵
受信者だけが持つ
公開鍵
皆が持つ
公開鍵で暗号化 → 公開鍵で複合:×
公開鍵で暗号化 → 秘密鍵で複合:○
秘密鍵で暗号化 → 秘密鍵で複合:×
秘密鍵で暗号化 → 公開鍵で複合:○
誰ものものかも分からない公開鍵で暗号化してはいけない
→第三者しか複合できない暗号ができてしまう
秘密鍵を他人に見られてはいけない
自分しか複合できない暗号を複合されてしまう。

SSL通信

Secure Socket Layer
共通鍵暗号方式と公開鍵暗号方式を組み合わせて行う通信方式

securekey_ssl
サーバー証明書を確認して信用性を確保した後、
送信側が「共通鍵」を生成、公開鍵暗号方式を用いて「共通鍵」を共有して通信を行う。

TSL通信

Trancport Layer Security
SSLの後継
SSL3.0の次のバージョンがTSL1.0

認証

チャレンジ/レスポンス認証

charange_response

クライアント側で暗号化して電文をサーバー に送る認証方式
電文を盗聴されても安全
クライアント側に暗号化処理が必要

電子署名

公開鍵暗号方式を利用した証明方法
送信者:秘密鍵で暗号化してデータ送信。
受信者:公開鍵で複合化してデータ受信。
公開鍵で複合できる データは秘密鍵で暗号化されている。
データは秘密鍵を持つ人から送信されているという証明になる

クロスサイトリクエストフォージェリ

クロスサイトリクエストフォージェリとは?

Cross Site Request Forgeries
Forgery:偽もの
悪意を持って作成したサイトに攻撃用スクリプトを仕込んでおき、
訪問者に対して、訪問者が意図しない操作をさせる攻撃

csrf
・ 悪意あるページはiframe(サイズ:1×1px)で隠しページを読み込み
・ 隠しページはtrue_site.jspへ、名前や電話番号等のパラメータをPOSTする処理を含む
・ 悪意あるページを表示したユーザは、気づかずにtrue_site.jspへ名前や電話番号を入力されてしまう
・ true_site.jspが認証が必要なサイトであった場合でも、
ログイン後、ログオフする前にこの攻撃を受けると(forgery.htmlを閲覧すると)、
認証をすり抜け、認証が必要なサイトに対して意図せず行ってしまう。

攻撃方法例

※悪意あるページ(forgery.html)
<html>
<body>
 <!-- 訪問者に見せる画面 -->
 <p>welcome</p>
 

 <!-- 訪問者に見せない(悪意ある隠しコード) -->
 <iframe src="hide_submit.html" style="width:1px; height:1px"></iframe>
</body>
</html>

※隠しページ(hide_submit.html)
<html>

<body onload="document.myform.submit()">
 <form
  name="myform"
  method="POST"
  action="http://localhost:8080/myservlet/myPack/true_site.jsp">
  
  <!-- ↓項目が↑サイトへ自動的にPOSTされる -->
  <input type="hidden" name="name" value="株式会社米良太事務所" />
  <input type="hidden" name="address" value="兵庫県西宮市" />
  <input type="hidden" name="tel" value="050-3695-5892" />
  <input type="hidden" name="email" value="yone@office-yone.com" />
 </form>
</body>
</html>

対策

csrf

@WebFilter("/*")
public class CSRF {
 public class CsrfFilter implements Filter {
  @Override
  public void doFilter(
   ServletRequest req,
   ServletResponse res,
   FilterChain chain) throws IOException, ServletException {
   
   HttpServletRequest request = (HttpServletRequest)req;
   
   if (request.getMethod().equals("GET")){
    // GET要求時 → トークン生成
    createToken(request);
   }else{
    // POST要求時
    if (isSameToken(request))
     throw new ServletException("不正なアクセス");
   }
    
   chain.doFilter(req, res);
  }
  
  // POSTされたトークンとサーバで保持しているトークンをチェック
  private boolean isSameToken(HttpServletRequest request) {
   
   HttpSession session = request.getSession();
   
   String s_token = (String)session.getAttribute("token");
   String r_token = request.getParameter("token");
   
   // トークン無し時 = 不正
   if (s_token == null ||
    r_token == null ||
    r_token.isEmpty()){
    return false;
   }
   
   // 一致(true) or 不一致(false)
   return s_token.equals(r_token);   
  }
  
  // トークンを生成
  private void createToken(HttpServletRequest reqest) {
  
   MessageDigest md = null;
   HttpSession session = reqest.getSession();
   
   // セッションIDを元にハッシュ値を生成
   md = MessageDigest.getInstance("MD5");
   md.update(session.getId().getBytes());
   
   // バイトデータ → 16進数 & セッション属性に格納
   session.setAttribute("token", to16(md.digest()));
  }
 }
}

参考

電子証明書

概要

公開鍵が真正であることを証明するデータ。
以下を証明できる。
・データが改ざんされていないこと。
・データの作成者の信頼性

構成要素

電子証明書は実世界における印鑑証明書に当たる。

印鑑証明書 電子証明書
印鑑の印影 公開鍵
印鑑の持ち主の情報 公開鍵の持ち主の情報
印鑑証明書を発行した自治体名 証明書を発行した認証局の情報
発行元自治体の印 発行元認証局の署名

認証局(CA)

Certification Authority
電子証明書を発行する機関
Root認証局
他の認証局に対して証明書を発行する機関
自らの信頼性は、機関の公開情報、厳しい監査、運用実績、知名度によって自ら構築する
信頼性が揺らぐと過去に発行した証明書の信頼性が全て揺らぐ為に社会的な責任も発生する。

中間認証局
Root認証局以外の認証局。
Root認証局に証明書を発行してもらうことで自らの信頼性を構築する。

証明書の種類

サーバー証明書

=SSLサーバー証明書
情報通信先のサーバのサイト運営組織が実在していることの証明書
WebブラウザとWebサーバ間(またはサーバ同士)でSSL通信が行える。
認証局により発行される電子証明書の一種。

クライアント証明書

端末認証やメール署名・暗号化に使用する個人の証明書
PC・スマートフォン・タブレットなどに格納
クライアントを証明するので証明できない端末からのアクセスを制限できる

コードサイニング証明書

ソフトウェアの配布元を認証。
なりすましや内容の改ざんなどがされていないことを保証する。
WindowsアプリをClickOnceで実行する場合、
自己作成の証明書が自動で作成されるが1年に1回期限を延長する必要がある。
認証局から購入した証明書の場合はその作業が不要になる。

電子証明書の利用方法

WEBブラウザ等、電子証明書を利用するソフトウェアには、Root認証局の証明書が同梱されている。

certification
※InternetExplorerの証明書一覧

電子証明書を要する通信を行うWEBサイトを閲覧する場合、
最初にWEBサイトからサーバー証明書を取得する。
secure_pki1
次にWEBサイトの電子証明書の信頼性を確認する為に、中間認証局の証明書、Root認証局の証明書を順に確認する。
ブラウザにはRoot証明書が最初から同梱されているので、サーバー証明書がRoot認証局の認可を受けていれば、信頼性は確保できる。

secure_pki2

secure_pki3
上から
ルート認証局証明書
中間認証局証明書
サーバー証明書

ファイル

サーバー証明書

CSR

Certificate Signing Request
証明書の申請時に提出するファイル
公開鍵の情報、組織情報等を含む
拡張子:.csr、.txt等。無しでも何でも良い
中身
「--BEGIN CERTIFICATE REQUEST--」

「--END CERTIFICATE REQUEST--」

秘密鍵

拡張子:.key、.txt等。無しでも何でも良い
中身
「--BEGIN RSA PRIVATE KEY--」

「--END RSA PRIVATE KEY--」

公開鍵

=SSL証明書
拡張子:.crt、.cert、.ca、.txt等。無しでも何でも良い
Certificate(=証明書)の略
中身
「--BEGIN CERTIFICATE --」

「--END CERTIFICATE--」

キーペア

秘密鍵とそれに対応する公開鍵
拡張子:.snk等。無しでも何でも良い

個人情報交換ファイル

PKCS #12
Public Key Cryptography Standard #12
拡張子
.p12等
公開鍵証明書、秘密鍵からなるファイル
作成方法は「個人情報交換ファイル」参照

キーストア

クライアントが参照する鍵と証明書の情報ファイル
このファイルに情報が無い証明書は使用できない
=サイトにアクセスできない
Javaが実行時にデフォルトで使用するキーストア
C:\Program Files\Java\jreX.X.XXX\lib\security\cacerts

トラストストア

サーバが参照する鍵と証明書の情報ファイル

WEB認証

using System.Net;

string url = @”http://~”;

NetworkCredential credentials =
  new NetworkCredential(
    userName: @”~”,
    password: @”~”,
    domain: @”~”);

// 資格情報格納クラス
CredentialCache cache = new CredentialCache();
cache.Add(
  uriPrefix: new Uri(uriString: url),
  authType: @”NTLM”,
  cred: credentials);

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = cache;

request.AllowAutoRedirect = true;
request.CookieContainer = new CookieContainer(capacity: 5);

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
  Console.WriteLine(@”In”);
}

Console.WriteLine(@”Done”);
Console.ReadLine();

DDos

Dos攻撃

Denial of Service
攻撃対象に対して迷惑メールを送る等、多くのパケットを送り続け、回線やサービスをパンクさせる攻撃方法

DDoS攻撃

Distributed Denial of Service
インターネット上の利用可能な第三者のサーバー、ルーター等(BOT)を利用するDos攻撃。

DNSamp

DNSサーバーに対し名前解決等のリクエストを出す際、
要求者のIPを攻撃対象のIPに偽装するDDoS攻撃。
※DNS要求はNDPプロトコルを使用して行われる。
※NDPプロトコルでは要求者自身のIPを偽装する事が容易。
※TCPプロトコルでは難しい。
インターネット上に問い合わせ可能な(OpenResolver)DNSサーバーさえあれば利用な可能な事と、リクエストに対してレスポンスは10倍近くのパケット量になる事から2014年8月現在大流行中。

NTPamp

DNSampと同じく、NTPサーバーに対して時刻問い合わせのリクエストを出す際、
要求者のIPを攻撃対象のIPに偽装するDDoS攻撃。
これもDNSampと同じく、インターネット上に問い合わせ可能(OpenResolver)なNTPサーバーさえあれば利用な可能な事と、リクエストに対してレスポンスは10倍近くのパケット量になる事から2014年8月現在大流行中。

BOTとして利用されない為の対策

・セキュリティソフトの利用
・OS、ソフトウェアのアップデート
・ブロードバンドルーターの利用、ファームウェアのアップデート
・OpenResolver設定の変更(要求元のIPを確認する設定を施す)
※所有者に悪意がなく、悪意ある攻撃者に利用されただけであっても被攻撃者から責任を問われる事例あり。

OpenResolver(オープンレゾルバ)

誰の要求も断らないサーバー

JavaScriptインジェクション① 従来型脆弱性対応(エスケープ処理等)

はじめに

クロスサイトスクリプティング(XSS)は主にJavaScriptを利用して行われる。
HTML5、JavaScript及びその関連技術の普及に伴って脆弱性と対応策は広がる一方だが、
まずは従来からの対策

エスケープ処理

SQLインジェクションと同様。
攻撃者はテキストボックス等の入力欄にJavaScriptコードを挿入してくる。
JavaScriptを無効化する様に文字を置換する処理を施す事が対策。
攻撃例
住所:
というテキストボックスに対して、

住所:
という風に入力して攻撃してくる。
※サイトによってはこのJavaScriptが動いてしまう。
JavaScriptは必ず「<」「>」の文字でコードを囲む必要があるので、
例:<script>JavaScriptコード</script>

具体的には入力された「<」「>」等の文字を強制的に「&lt;」「&gt;」等の文字コードに置換する処理を「エスケープ処理」という。
※サーバー側で処理する際には「<」「>」⇒「&lt;」「&gt;」に変換されてJavaScriptは動作しない。
そもそもクライアントサイドでこの文字の入力を制限する様な処理を施すとなお良い。

「<」「>」の他にも、「"」「'」「&」等もhtmlにおいては特別な意味を持つ為、
それぞれ以下の様にエスケープ処理を行う。
< → &lt;
> → &gt;
" → &quot;
' → &#39;
& → &amp;

DOM生成

ユーザーが入力した値等を画面に表示したりする為に動的にhtmlを生成する際、
やり方(文字列によるhtml指定)によっては脆弱性となる。

①通常の表示

<script type="text/javascript">
  var normal = 'aaa';
  document.write("<input type='text' value='" + normal + "' /> ");
  (1)document.write("<input type='text' />")によりTextBoxが動的(サイト表示時)に生成される。
  (2)その際、変数:normalの内容をTextBoxに表示する(value=normal)

</script>

②JavaScriptインジェクション成功例

マウスオーバーイベントでalert(1)が実行される。
<script type="text/javascript">
  var XSS = "' onmouseover='alert(1);";
  document.write("<input type='text' value='" + XSS + "' /> ");
</script>

③JavaScriptインジェクション防止例

<form id="myForm">
</form>
<script type="text/javascript">
  var myForm = document.getElementById('myForm');
  var element = document.createElement('input');
  element.setAttribute('type','text');
  element.setAttribute('value',XSS);
  myForm.appendChild(element);
</script>
※setAttribute、appendChildを使用する事でJavaScriptインジェクションを無効化している。

JavaScriptインジェクション

URL

<a href="javascript: ">
<iframe src="data:text/html; ">
本来、URLが設定される~の部分にJavaScriptのコードが埋め込まれると、
URLにジャンプせずに埋め込まれたコードが実行されてしまう為、
URLの動的生成時はhttp,https限定とする。