[英]Preventing HTML and Script injections in Javascript
Assume I have a page with an input box.假设我有一个带有输入框的页面。 The user types something into the input box and hits a button.
用户在输入框中输入内容并点击按钮。 The button triggers a function that picks up the value typed into the text box and outputs it onto the page beneath the text box for whatever reason.
该按钮会触发一个函数,该函数选取输入到文本框中的值并将其输出到文本框下方的页面上,无论出于何种原因。
Now this has been disturbingly difficult to find a definitive answer on or I wouldn't be asking but how would you go about outputting this string:现在很难找到一个明确的答案,否则我不会问,但你会如何输出这个字符串:
<script>alert("hello")</script> <h1> Hello World </h1>
So that neither the script is executed nor the HTML element is displayed?这样既不执行脚本也不显示 HTML 元素?
What I'm really asking here is if there is a standard method of avoiding both HTML and Script injection in Javascript .我在这里真正要问的是,是否有一种标准方法可以避免在Javascript 中同时避免 HTML 和 Script 注入。 Everyone seems to have a different way of doing it (I'm using jQuery so I know I can simply output the string to the text element rather than the html element for instance, that's not the point though).
每个人似乎都有不同的方法(我使用的是 jQuery,所以我知道我可以简单地将字符串输出到文本元素而不是html元素,例如,这不是重点)。
You can encode the <
and >
to their HTML equivelant.您可以将
<
和>
编码为它们的 HTML 等效项。
html = html.replace(/</g, "<").replace(/>/g, ">");
myDiv.textContent = arbitraryHtmlString
as @Dan pointed out, do not use innerHTML, even in nodes you don't append to the document because deffered callbacks and scripts are always executed.正如@Dan 指出的那样,不要使用innerHTML,即使在您不附加到文档的节点中也是如此,因为延迟回调和脚本总是被执行。 You can check this https://gomakethings.com/preventing-cross-site-scripting-attacks-when-using-innerhtml-in-vanilla-javascript/ for more info.
您可以查看此https://gomakethings.com/preventing-cross-site-scripting-attacks-when-using-innerhtml-in-vanilla-javascript/了解更多信息。
A one-liner:单线:
var encodedMsg = $('<div />').text(message).html();
See it work:看看它的工作:
https://jsfiddle.net/TimothyKanski/wnt8o12j/ https://jsfiddle.net/TimothyKanski/wnt8o12j/
I use this function htmlentities($string):我使用这个函数 htmlentities($string):
$msg = "<script>alert("hello")</script> <h1> Hello World </h1>" $msg = htmlentities($msg); echo $msg;
My solution using typescript + decorators + regex我使用打字稿 + 装饰器 + 正则表达式的解决方案
const removeTag = new RegExp("(<[a-zA-Z0-9]+>)|(</[a-zA-Z0-9]+>)", "g");
return value.replace(removeTag, "");
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; function filter(target) { return class extends target { constructor(...args) { super(...args); } setState(opts) { const state = { username: this.filter(opts.username), password: this.filter(opts.password), }; super.setState(state); } filter(value) { const removeTag = new RegExp("(<[a-zA-Z0-9]+>)|(</[a-zA-Z0-9]+>)", "g"); return value.replace(removeTag, ""); } }; } let Form = class Form { constructor() { this.state = { username: "", password: "", }; } setState(opts) { this.state = { ...this.state, ...opts, }; } getState() { return this.state; } }; Form = __decorate([ filter, __metadata("design:paramtypes", []) ], Form); function getElement(key) { return document.getElementById(key); } const button = getElement("btn"); const username = getElement("username"); const password = getElement("password"); const usernameOutput = getElement("username-output"); const passwordOutput = getElement("password-output"); function handleClick() { const form = new Form(); form.setState({ username: username.value, password: password.value }); usernameOutput.innerHTML = `Username: ${form.getState().username}`; passwordOutput.innerHTML = `Password: ${form.getState().password}`; } button.onclick = handleClick;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <style> :root { --bg: #1d1907; --foreground: #e3e0cd; --primary: #cfb53b; --black: #333; --white: #fafafa; } @keyframes borderColor { from { border-bottom: 1px solid var(--foreground); } to { border-bottom: 1px solid var(--primary); } } * { outline: none; border: none; } body { padding: 0.5rem; font-family: "Fira Code"; background-color: var(--bg); color: var(--foreground); } input { border-bottom: 1px solid var(--foreground); background-color: var(--black); color: var(--foreground); padding: 0.5rem; } input:focus { animation-name: borderColor; animation-duration: 3s; animation-fill-mode: forwards; } button { padding: 0.5rem; border-radius: 3px; border: 1px solid var(--primary); background-color: var(--primary); color: var(--white); } button:hover, button:active { background-color: var(--white); color: var(--primary); } .form { margin-bottom: 2rem; } </style> <title>Decorator</title> </head> <body> <h1>Prevent Injection</h1> <div class="form"> <div class="form-group"> <label for="username">Username</label> <input type="text" id="username" placeholder="Type your username" /> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" id="password" placeholder="Type your password" /> </div> <div class="form-group"> <button id="btn">Enviar</button> </div> </div> <div class="form-result"> <p id="username-output">Username:</p> <p id="password-output">Password:</p> </div> <script src="/dist/pratica1.js"></script> </body> </html>
Typescript Code bellow:打字稿代码如下:
type State = {
username: string;
password: string;
};
function filter<T extends new (...args: any[]) => any>(target: T): T {
return class extends target {
constructor(...args: any[]) {
super(...args);
}
setState(opts: State) {
const state = {
username: this.filter(opts.username),
password: this.filter(opts.password),
};
super.setState(state);
}
filter(value: string) {
const removeTag = new RegExp("(<[a-zA-Z0-9]+>)|(</[a-zA-Z0-9]+>)", "g");
return value.replace(removeTag, "");
}
};
}
@filter
class Form {
private state: State;
constructor() {
this.state = {
username: "",
password: "",
};
}
setState(opts: State) {
this.state = {
...this.state,
...opts,
};
}
getState() {
return this.state;
}
}
function getElement(key: string): HTMLElement | null {
return document.getElementById(key);
}
const button = getElement("btn") as HTMLButtonElement;
const username = getElement("username") as HTMLInputElement;
const password = getElement("password") as HTMLInputElement;
const usernameOutput = getElement("username-output") as HTMLParagraphElement;
const passwordOutput = getElement("password-output") as HTMLParagraphElement;
function handleClick() {
const form = new Form();
form.setState({ username: username.value, password: password.value });
usernameOutput.innerHTML = `Username: ${form.getState().username}`;
passwordOutput.innerHTML = `Password: ${form.getState().password}`;
}
button.onclick = handleClick;
Try this method to convert a 'string that could potentially contain html code' to 'text format':尝试使用此方法将“可能包含 html 代码的字符串”转换为“文本格式”:
$msg = "<div></div>";
$safe_msg = htmlspecialchars($msg, ENT_QUOTES);
echo $safe_msg;
Hope this helps!希望这有帮助!
Use this,用这个,
function restrict(elem){
var tf = _(elem);
var rx = new RegExp;
if(elem == "email"){
rx = /[ '"]/gi;
}else if(elem == "search" || elem == "comment"){
rx = /[^a-z 0-9.,?]/gi;
}else{
rx = /[^a-z0-9]/gi;
}
tf.value = tf.value.replace(rx , "" );
}
On the backend, for java , Try using StringUtils class or a custom script.在后端,对于 java ,尝试使用 StringUtils 类或自定义脚本。
public static String HTMLEncode(String aTagFragment) {
final StringBuffer result = new StringBuffer();
final StringCharacterIterator iterator = new
StringCharacterIterator(aTagFragment);
char character = iterator.current();
while (character != StringCharacterIterator.DONE )
{
if (character == '<')
result.append("<");
else if (character == '>')
result.append(">");
else if (character == '\"')
result.append(""");
else if (character == '\'')
result.append("'");
else if (character == '\\')
result.append("\");
else if (character == '&')
result.append("&");
else {
//the char is not a special one
//add it to the result as is
result.append(character);
}
character = iterator.next();
}
return result.toString();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.