是否可以安全地将html保存在数据库中而不进行消毒,然后将其显示在代码标记中,就像stackoverflow一样?

时间:2013-02-27 20:19:05

标签: php html mysql html5 security

我在数据库中存储html但是数据库但是服务器响应403禁止错误...而且我存储html就像代码不是为了实际渲染... 例如,这个问题已成功发布,并且在我的服务器上会出现403错误...

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>
    <script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.3-beta.js"></script>
    <script>
      var angularVelocity = 6;
      var angularVelocities = [];
      var lastRotations = 0;
      var controlled = false;
      var numWedges = 25;
      var angularFriction = 0.2;
      var target, activeWedge, stage, layer, wheel, pointer;

      function getAverageAngularVelocity() {
        var total = 0;
        var len = angularVelocities.length;

        if(len === 0) {
          return 0;
        }

        for(var n = 0; n < len; n++) {
          total += angularVelocities[n];
        }

        return total / len;
      }
      function purifyColor(color) {
        var randIndex = Math.round(Math.random() * 3);
        color[randIndex] = 0;
        return color;
      }
      function getRandomColor() {
        var r = 100 + Math.round(Math.random() * 55);
        var g = 100 + Math.round(Math.random() * 55);
        var b = 100 + Math.round(Math.random() * 55);
        var color = [r, g, b];
        color = purifyColor(color);
        color = purifyColor(color);

        return color;
      }
      function bind() {
        wheel.on('mousedown', function(evt) {
          angularVelocity = 0;
          controlled = true;
          target = evt.shape;
        });
        // add listeners to container
        document.body.addEventListener('mouseup', function() {
          controlled = false;
          angularVelocity = getAverageAngularVelocity() * 5;

          if(angularVelocity > 20) {
            angularVelocity = 20;
          }
          else if(angularVelocity < -20) {
            angularVelocity = -20;
          }

          angularVelocities = [];
        }, false);

        document.body.addEventListener('mousemove', function(evt) {
          var mousePos = stage.getMousePosition();
          if(controlled && mousePos && target) {
            var x = mousePos.x - wheel.getX();
            var y = mousePos.y - wheel.getY();
            var atan = Math.atan(y / x);
            var rotation = x >= 0 ? atan : atan + Math.PI;
            var targetGroup = target.getParent();

            wheel.setRotation(rotation - targetGroup.startRotation - (target.getAngle() / 2));
          }
        }, false);
      }
      function getRandomReward() {
        var mainDigit = Math.round(Math.random() * 9);
        return mainDigit + '\n0\n0';
      }
      function addWedge(n) {
        var s = getRandomColor();
        var reward = getRandomReward();
        var r = s[0];
        var g = s[1];
        var b = s[2];
        var angle = 2 * Math.PI / numWedges;

        var endColor = 'rgb(' + r + ',' + g + ',' + b + ')';
        r += 100;
        g += 100;
        b += 100;

        var startColor = 'rgb(' + r + ',' + g + ',' + b + ')';

        var wedge = new Kinetic.Group({
          rotation: 2 * n * Math.PI / numWedges,
        });

        var wedgeBackground = new Kinetic.Wedge({
          radius: 400,
          angle: angle,
          fillRadialGradientStartPoint: 0,
          fillRadialGradientStartRadius: 0,
          fillRadialGradientEndPoint: 0,
          fillRadialGradientEndRadius: 400,
          fillRadialGradientColorStops: [0, startColor, 1, endColor],
          fill: '#64e9f8',
          fillPriority: 'radial-gradient',
          stroke: '#ccc',
          strokeWidth: 2
        });

        wedge.add(wedgeBackground);

        var text = new Kinetic.Text({
          text: reward,
          fontFamily: 'Calibri',
          fontSize: 50,
          fill: 'white',
          align: 'center',
          stroke: 'yellow',
          strokeWidth: 1

        });

        // cache text as an image to improve performance
        text.toImage({
          width: text.getWidth(),
          height: text.getHeight(),
          callback: function(img) {
            var cachedText = new Kinetic.Image({
              image: img,
              listening: false,
              rotation: (Math.PI + angle) / 2,
              x: 380,
              y: 30
            });

            wedge.add(cachedText);
            layer.draw();
          }
        });

        wedge.startRotation = wedge.getRotation();

        wheel.add(wedge);
      }
      function animate(frame) {
        // handle wheel spin
        var angularVelocityChange = angularVelocity * frame.timeDiff * (1 - angularFriction) / 1000;
        angularVelocity -= angularVelocityChange;

        if(controlled) {
          if(angularVelocities.length > 10) {
            angularVelocities.shift();
          }

          angularVelocities.push((wheel.getRotation() - lastRotation) * 1000 / frame.timeDiff);
        }
        else {
          wheel.rotate(frame.timeDiff * angularVelocity / 1000);
        }
        lastRotation = wheel.getRotation();

        // activate / deactivate wedges based on point intersection
        var intersection = stage.getIntersection({
          x: stage.getWidth() / 2,
          y: 100
        });

        if(intersection) {
          var shape = intersection.shape;

          if(shape && (!activeWedge || (shape._id !== activeWedge._id))) {
            pointer.setY(20);
            pointer.transitionTo({
              y: 30,
              easing: 'elastic-ease-out',
              duration: 0.3
            });

            if(activeWedge) {
              activeWedge.setFillPriority('radial-gradient');
            }
            shape.setFillPriority('fill');
            activeWedge = shape;
          }
        }
      }
      function init() {
        stage = new Kinetic.Stage({
          container: 'container',
          width: 578,
          height: 200
        });
        layer = new Kinetic.Layer();
        wheel = new Kinetic.Group({
          x: stage.getWidth() / 2,
          y: 410
        });

        for(var n = 0; n < numWedges; n++) {
          addWedge(n);
        }
        pointer = new Kinetic.Wedge({
          fillRadialGradientStartPoint: 0,
          fillRadialGradientStartRadius: 0,
          fillRadialGradientEndPoint: 0,
          fillRadialGradientEndRadius: 30,
          fillRadialGradientColorStops: [0, 'white', 1, 'red'],
          stroke: 'white',
          strokeWidth: 2,
          lineJoin: 'round',
          angleDeg: 30,
          radius: 30,
          x: stage.getWidth() / 2,
          y: 30,
          rotationDeg: -105,
          shadowColor: 'black',
          shadowOffset: 3,
          shadowBlur: 2,
          shadowOpacity: 0.5
        });

        // add components to the stage
        layer.add(wheel);
        layer.add(pointer);
        stage.add(layer);

        // bind events
        bind();

        var anim = new Kinetic.Animation(animate, layer);

        // wait one second and then spin the wheel
        setTimeout(function() {
          anim.start();
        }, 1000);
      }
      init();

    </script>
  </body>
</html>

3 个答案:

答案 0 :(得分:7)

不,这样做是不安全的。假设你输出这样的html:

<code>
    user_submitted_html
</code

并且用户提交

</code>
    <script>
        do_something_malicious();
    </script>
<code>

将它们放在一起会给你

<code>
</code>
    <script>
        do_something_malicious();
    </script>
<code>
</code>

因此用户的脚本不再位于代码块中。

答案 1 :(得分:3)

您应该在将数据放入数据库之前对其进行序列化,然后在取出数据时对其进行反序列化。 http://php.net/manual/en/function.serialize.php

编辑:很抱歉回答太快...正如sys.stderr所说,您必须在序列化/显示数据之前清理数据。

答案 2 :(得分:2)

只要您转义输入中的所有html字符,它就是安全的。如果使用php,您希望通过内置函数htmlspecialchars()运行内容。这将阻止Web浏览器呈现html,而是显示原始代码。