- ベストアンサー
閲覧者さんが作ったコンテンツを自動で適応されるサイトの作り方は?
- 閲覧者さんが作ったコンテンツを自動で適応されるサイトの作り方について知りたいです。
- PHPを使用して閲覧者が入力した情報を保存し、次回の閲覧時にその情報を活用することができます。
- HTMLやPHPだけでなく、CSSやJavaScriptも閲覧者が作成できると便利ですが、一部制約があります。
- みんなの回答 (13)
- 専門家の回答
質問者が選んだベストアンサー
>Inputの中に入れた数値をjsで計算し結果をinnerhtmlで表記 それをevalでやってなければまだ大丈夫と思います evalでやってたとしても入力値をparseIntなどして 数値しか受け付けないようしているなら大丈夫です 出力時も同じく、parseIntなどして数値しか 出力されないようにしてれば大丈夫です どの言語でも、文字列を式として評価するという関数は 安易に使ってはいけません
その他の回答 (12)
- H240S18B73
- ベストアンサー率65% (190/288)
/^[\d\+\-\*\/\(\)]+$/ 単純に+-*/()と数字以外受け付けないならこんな感じでしょうが しかしこれでは数式として正しいかは判定できません /^([0-9]+[\+\-\*\/])+[0-9]$/ 四則演算のみカッコとかもなしって感じならこんな正規表現になるでしょうか カッコなしも許容しつつそれぞれのカッコが入れ子のものを含めて ちゃんと閉じられているかというのを 正規表現で書くと結構長くなりそうなので割愛します <>^&|とかのビット演算子は許容していいもんなのかちょっと判断しかねます アルファベットはないとは言っても剰余演算子%も許容していいのか微妙です
お礼
ありがとうございます。 初心者で申し訳ありませんが、 /^([0-9]+[\+\-\*\/])+[0-9]$/ をifの条件式に入れるだけで恐らく上手くいきませんよね。 ループさせて一文字ずつ全てチェックするのでしょうか?
- H240S18B73
- ベストアンサー率65% (190/288)
どうすればいいのかについては 先に述べた通り正規表現によって 数式としてのみ評価できる入力以外は受け付けない という形の対応が良いかと思います 使う関数についてはRegExp.test()になるでしょうか 数式としてのみ評価できる文字列であるか ということを調べる正規表現については あまり安易にこれでいいとは言えません もしかしたら正規表現では難しいので 数式の文字列を解析する関数を自分で作った方が安全 という結論にもなるかもしれません eval()は本当に使い所が難しいのです
お礼
結局eval()がある所のみ危険なのですね。 これを使わなければ安全なので、大変であれば、自由に計算する部分はなくして公開する方法もありますね。 それならinput typ=”number” やテキストを表記するだけなので、何も気にせずにも安全なのですね。
補足
具体的にどうするかがわからないのですが、 http://www.24w.jp/study_contents.php?bid=javascript&iid=javascript&sid=string&cid=006 のように入力情報が該当する文字化確認して。該当した場合のみ処理を実行するという事でしょうか? もう少し具体的にソースを見せてもらえませんでしょうか?
- H240S18B73
- ベストアンサー率65% (190/288)
ユーザー入力を直接的にJSのコードとして利用する場合に無害化をする際には 「難読化」されたコードへの対策も必要となります しかし「難読化」には様々な形があり全てに対応するのは困難です この点からも受け付けたい入力の形式が決まっているならば、 入力のブラックリストを作るよりも むしろホワイトリストを作ってそれ以外受け付けない というような対処をする方が現実的です サーバーサイドでユーザー入力を直接的に実行コードとして扱いたいならば 「サンドボックス」を作る技術が必要になるかと思います
お礼
https://blog.ohgaki.net/how-to-make-white-list ホワイトリストの情報を調べてみましたが上記のように、 具体的な関数の情報がありません。 具体的にどのように作るかという情報があれば教えていただければ幸いです。 またjsのみの場合は上記で十分なのだと思いますが、 このサイトのように、PHPが絡む場合はこれでは対処できず サンドボックスというものを使わないと危険なのですね。 これは入力情報をここのサイトのように表記するだけなら何も気にせずに良いという事なのでしょうか? 受け取った結果を計算したり、テキストを加工して表記したり、表記だけでない場合はそこまでしないと危険という事でしょうか?
- H240S18B73
- ベストアンサー率65% (190/288)
入力に数式を期待するならば 正規表現によって数式として評価できる文字列式以外のものは 全て排除するという対応が良いように思います およそ関数と言ったものを使わない数式には アルファベットはないはずですし使う記号も限られているはずです 先にも述べましたが XSS攻撃というのはユーザー入力 すなわちURLパラメータを利用することによって行われます 単純にinput要素の値を取得している間は XSS攻撃の脆弱性を心配する必要はあまりありません フォームを送信してサーバーサイドで計算を行うとか 前回の入力を記憶しておくと言ったようなことを やろうとした時にXSSやCSRF攻撃の脆弱性の可能性が出てきます 補足までに セキュリティー面においてJSによる入力値検証などというものは あってないようなものです JSの入力値検証というのは所詮ユーザービリティーを 目的としたものでしかないという認識で当たるべきです セキュリティーはクライアントサイドではなく サーバーサイドに寄るところです クライアントサイドに対して気をつけるべきは ユーザーに漏らしてはいけない情報がコードに含まれていないか ユーザーに渡してしまっていないかと言ったようなところです
お礼
フロントjsのみであれば何も気にせず入力させてもまず大丈夫ですね。 ただローカルストレージに保存したいのですが、この場合は危険なのですね。
補足
入力制限の方法を調べてみました。 https://allabout.co.jp/gm/gc/23854/3/ 結構大変なことをしないといけないようですね。 理屈としてはinputの中身を取得して、そこに*/+-123455678890以外が入っていた場合計算を行わないで、エラーを出すようにすればセキュアという事でしょうか? それともこれでも入植したものをjsが処理しているので、本末転倒でしょうか? またこれらの文字以外の物がなかった場合だけ実行というifを作るというのもとんでもない数のネストになってしまいますね。
- H240S18B73
- ベストアンサー率65% (190/288)
<script>タグを入力されても実行されなかった ということはとりあえず出力時などに html特殊文字のエスケープはされている ということだとは思います 一応対策はしてあるっぽいので大丈夫なんだろうな というところではあります が、先に述べたXSS対策の一つとしてエンコードを指定して受け取っているか というところが明確ではないので言い切ることはできないです 文字コードによってタグを記述することで 単純なエスケープならかいくぐることができるからです %¥\&の入力を許容するとやりたい放題ってのは これによって文字コードでの入力の記述が可能になり 事実上どんな文字も入力ができることになるからです 文字コードでの入力を受け取らないために エンコードを指定しての入力値の受け取りが必要になります
お礼
私のjsは特別なことは何もしていないので恐らく%¥\&がエスケープされていないのですね。
- H240S18B73
- ベストアンサー率65% (190/288)
XSS脆弱性は要するに特定のURLを踏むだけで任意のスクリプトを ユーザーに実行させることができてしまうことに起因します その点で言えばlocation.searchなどを使って URLから入力値を得るということをしていれば XSS脆弱性というのはJSだけでも起こり得ます
お礼
ローカル環境でのテストですが、<script>alert("hacked!")</script>をinputとtextareaに入れて実行ボタンを押してみましたがalertは出ませんでした。出れば危険でなければ安全という判断でよいでしょうか? 良ければもう一度公開したいと思います。
補足
>>> console.log(escape(‘abcde’)); console.log(escape(‘あいうえお’)); abcde %u3042%u3044%u3046%u3048%u304A このように値を受け取った後にエスケープしてから、計算をすると良いのかと思ったのですが下記のようにありました。 >>> 実はescape関数はブラウザなどにより挙動が異なるため、使用が推奨されていません。
- H240S18B73
- ベストアンサー率65% (190/288)
どちらかというとformの送信先のPHPなどのプログラムに脆弱性は起因します XSS対策としては ユーザー入力の文字列を出力に利用する場合は 受け取り時はエンコードを指定して受け取る、 出力時は特殊文字をエスケープする といったことが基本となります その他の攻撃方法や対策については 参考URLのPDFを一読してみてください PHPなどサーバーサイドの言語に手を出す場合には 必ず知っておきたい知識です
お礼
Inputの中に入れた数値をjsで計算し結果をinnerhtmlで表記するようにしている部分は、%¥\&最低限の物だけエスケープしてから公表したほうがいいでしょうか? あまり情報が出てこないのですが%¥\&をエスケープする関数を子の処理より前に実行すれば安全なのでしょうか?
補足
見てみます。 また、jsのみのinnerhtmlの計算は、公開しても問題ないのでしょうか? サーバサイドのみ危険ですがフロントは特に危険な事はないと思っているのですが、大丈夫ですか?
- H240S18B73
- ベストアンサー率65% (190/288)
例示されたコードについては ユーザー入力を利用しているとはいっても Formから送信された値を利用しているわけではないので URLを踏ませるだけで任意のスクリプトを実行させられる というようなものにはなっていないはずです また、PHPなどサーバーの処理は設置していないだろうと思うので まだ自分のコードが起因してサイトにバックドアを仕掛けられたとか そういう心配をする段階には来てないと思います しかし、今の例示されたコードの延長でPHPを使って Formから送信された値を利用しようというのは非常に危険です ユーザー入力は信用しないのが原則です
お礼
ありがとうございます。 仰る通り、ただinputに入れた数値や*、/などを使ってjsで計算しているだけです。 PHPなどサーバサイドはここには一切絡んでいません。 まず問題ないならほっとしました。 するとinnerHTMLが危ないというのは、jsにのみ入力情報が渡される構造の、ちょっとした計算をするwebアプリ程度なら、 何も気にせずに使ってもいいのですね。 textcontentにすると安全とも聞きますが、こちらは文字通りテキストにすべてしてしまうので、計算式を入れることが出来ずに困ります。 >>> Formから送信された値を利用しているわけではないので URLを踏ませるだけで任意のスクリプトを実行させられる というようなものにはなっていないはずです これはhtmlのformタグを使っていないという事でしょうか? inputやtextareaの場合は、そこに何を入れられてもだいじょうぶだが formタグを使った問い合わせフォームなどは危険という事でしょうか? 実はPHP工房の問い合わせフォームをHTMLがformタグを使って同じページに使っているのですが、 大丈夫ですかね。 色々と心配になってきました。
- H240S18B73
- ベストアンサー率65% (190/288)
>ここに危険なソースを書いてボタンを押すと対策していないと個人情報がデータベースから抜かれたりするということでしょうか? そういうのもあるでしょうが、攻撃というのは往々にして 真っ向正直にブラウザでフォームを入力して行われることはありません 直接フォームの送り先のプログラムにリクエストを投げて行われます それも大体手動ではなくプログラムによって可能性のある脆弱性を 利用した攻撃をひたすら試してきます まず規定のフォームから送られてきたことをチェックすることが基本です これがCSRF対策というところになります JSにおけるXSSについてはどちらかというと別のユーザーを攻撃する あるいは別のユーザーに攻撃を行わせる攻撃といったものです ユーザー入力を直接JSに渡す仕組みがあると 特定のリンクを踏むだけで任意のスクリプトを実行させることができます それを利用してそのサイトを踏み台としてユーザーに攻撃をおこなったり ユーザーに攻撃を行わせたりするのがXSSです 先に言ったようにXSS対策はユーザー入力を 直接JSコードに利用しないというのが対策です 特に&%\¥あたりの文字の入力を許すともうやりたい放題です もちろんPHPのコード内でも同じです PHPでそれをやるとデータベースを覗いたりデータを消したり サーバーにバックドアを仕込んで同居するサイトにやりたい放題されます サーバーサイドでユーザー入力を直接コードに利用するのは もう論外ってレベルです
補足
難しいですね。 まえにInputの中に入れた数値をjsで計算し結果をinnerhtmlで表記するように下のですがすぐにやめた方がいいと言うことでしょうかから
- H240S18B73
- ベストアンサー率65% (190/288)
JSやCSSをユーザー入力やデータベースの値を利用して PHPによって出力することは可能です PHPでJSやCSSのコードを出力してscriptのsrcや linkのhrefとして利用することもできます なんならPHPは画像だって出力できます また、ユーザーにcookieをもたせておくなどすることで それをブラウザ毎に記憶しておくということもできます しかしユーザー入力を直接的に利用してJSを出力することは それ自体XSS脆弱性なのでやるべきことではありません というかやってはいけません ユーザー入力を利用したJSの出力を行う場合の ユーザー入力の無害化には高度な知識を要すると思います 上級者を自称できるレベルでないならやらないほうが無難です ユーザー入力を受けてあれこれするというものを作りたいときは 少なくともXSS・CSRF・ディレクトリトラサーバル といった攻撃についての知識は最低限持ち合わせるべきです
お礼
>>> それをevalでやってなければまだ大丈夫と思います evalでやってたとしても入力値をparseIntなどして 数値しか受け付けないようしているなら大丈夫です 出力時も同じく、parseIntなどして数値しか 出力されないようにしてれば大丈夫です 攻撃者はこの挙動を利用して,ユーザーを http://example.jp/search?q=<script>alert(1)</script> などに誘導することで,ユーザーのブラウザ上でJavaScriptを実行させることができます。 結論としては、PHPが絡まないJSのみなら、すべて入力できてもまずだいじょうぶなので公開しても大丈夫だが、 念のため記載する可能性のある物以外はjsが無視するようにしておいた方が良いという事でしょうか? よって下記と数値以外はエスケープしたいのですが、具体的にこの関数を、inputのvalueを取得する前に記載しておくと良いと教えていただければ幸いです。 このページに情報があるでも構いません。 >>> Inputの中に入れた数値をjsで計算し結果をinnerhtmlで表記するようにしている部分は、%¥\&最低限の物だけエスケープしてから公表したほうがいいでしょうか? あまり情報が出てこないのですが%¥\&をエスケープする関数を子の処理より前に実行すれば安全なのでしょうか?
補足
このサイトもそうですよね このコメントも自動的に表記されます ここに危険なソースを書いてボタンを押すと対策していないと個人情報がデータベースから抜かれたりするということでしょうか?
- 1
- 2
お礼
ありがとうございます。念のためすぐにhtmlを削除しました。 var Btn = document.getElementById('Btn'); Btn.addEventListener('click', function() { var userInput = document.getElementById('UserInput').value; var Result = eval(userInput); Result = round(Result); if (!(userInput === '')) { document.getElementById('Result').innerHTML = Result; } else { document.getElementById('Result').innerHTML = 'em'; } }); のようにしていたのですが、危険だったという事でしょうか? 訪問者はほとんどいませんが、ボットが自動的に行って、自分のサイトにウイルスが仕込まれていたり、する可能性が既に0ではないのですか? それであれば確認する必要があるのですが、もし良い方法があれば教えていただければ幸いです。 宜しくお願い致します。
補足
別質問にしますので、具体的にソースを教えていただければ幸いです。