保护网页免受点击劫持的Content Security Policy(CSP)

7 篇文章 0 订阅
6 篇文章 0 订阅

84. 保护网页免受点击劫持的Content Security Policy(CSP)

什么是点击劫持?

点击劫持(Clickjacking)是一种网络安全攻击技术,通过在一个网页上放置透明的或误导性的内容,诱使用户在不知情的情况下点击恶意操作。这种攻击技术可以欺骗用户并执行他们不想执行的操作,如点击隐藏的按钮或链接,可能导致敏感信息泄露、支付信息被篡改等风险。

Content Security Policy(CSP)的作用

Content Security Policy(CSP)是一种用于增强网页安全性的安全策略。它通过定义可信任的资源源和加载行为,限制了网页中的内容来源,从而防止点击劫持等攻击。CSP提供了一系列的指令,允许网页开发者明确控制浏览器加载和执行的资源。

设置CSP策略

要设置CSP策略,可以通过添加<meta>标签或响应头的方式来告知浏览器该网页的安全策略。

使用<meta>标签设置CSP策略

在网页的头部添加以下<meta>标签来设置CSP策略:

<meta http-equiv="Content-Security-Policy" content="指令1; 指令2; ...">

具体的CSP指令根据实际需求进行配置。以下是一个简单的示例,只允许加载同源的资源:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

上述示例中,default-src指令设置了默认策略,其中'self'表示只允许加载同源的资源。这样可以防止网页被其他域名的恶意页面嵌套,减少点击劫持的风险。

使用响应头设置CSP策略

在服务器端,可以通过设置响应头来指定CSP策略。以下是一个Node.js Express框架的示例:

const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy', "default-src 'self'");
  next();
});

// 网页路由和其他逻辑...

app.listen(3000, () => {
  console.log('服务器已启动,监听端口 3000');
});

上述示例中,我们使用Express框架在每个请求的响应中设置了Content-Security-Policy头部,将默认策略设置为只允许加载同源的资源。

通过根据实际需求设置适当的CSP策略,我们可以有效地保护网页免受点击劫持等攻击的影响,提升网页的安全性。

每日一游 - 大型端游之俄罗斯方块

俄罗斯方块

<!DOCTYPE html>
<html>
<head>
  <title>俄罗斯方块</title>
  <style>
    .block {
      width: 29px;
      height: 29px;
      border: 1px solid #000;
      position: absolute;
    }
    body {
      background-color: #f8f9fa;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
      font-family: Arial, sans-serif;
    }

    #game-area {
      width: 300px;
      height: 600px;
      margin: 0 auto;
      position: relative;
      background-color: #fff;
      border: 4px solid #ced4da;
      border-radius: 8px;
      box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
    }

    #score {
      text-align: center;
      font-size: 24px;
      margin-top: 16px;
    }
  </style>
</head>
<body>
  <h1>俄罗斯方块</h1>
  <div id="game-area"></div>

  <div id="score">Score: 0</div>
  <button id="start-button">Start</button>


  <script>
    // 计分系统
    let gameStarted = false;

    function startGame() {
      if (!gameStarted) {
        gameStarted = true;
        score = 0;
        grid = [];
        for (let i = 0; i < 20; i++) {
          grid.push(new Array(10).fill(0));
        }
        clearGameArea();
        generateNewTetromino();
        gameInterval = setInterval(moveDown, 1000);
        document.getElementById('start-button').disabled = true;
      }
    }

    function restartGame() {
      score = 0;
      grid = [];
      for (let i = 0; i < 20; i++) {
        grid.push(new Array(10).fill(0));
      }
      clearGameArea();
      generateNewTetromino();
      gameInterval = setInterval(moveDown, 1000);
      document.getElementById('start-button').disabled = true;
    }

    document.getElementById('start-button').addEventListener('click', startGame);



    let gameInterval;
    const gameArea = document.getElementById('game-area');

    const tetrominoShapes = [
      [
        [1, 1, 1, 1],
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
      ],
      [
        [1, 1],
        [1, 1]
      ],
      [
        [1, 1, 1],
        [0, 1, 0]
      ],
      [
        [ 1, 1 ],
        [ 0, 1 ],
        [ 0, 1 ],
      ],
      // 添加更多方块形状...
    ];

    let currentTetromino = tetrominoShapes[0];  // 初始方块形状
    let currentX = 0;  // 初始方块横向位置
    let currentY = 0;  // 初始方块纵向位置

    function createBlock() {
      const block = document.createElement('div');
      block.className = 'block';
      return block;
    }

    function drawBlock(x, y) {
      const block = createBlock();
      block.style.left = x + 'px';
      block.style.top = y + 'px';
      gameArea.appendChild(block);
    }

    function clearGameArea() {
      while (gameArea.firstChild) {
        gameArea.removeChild(gameArea.firstChild);
      }
    }

    function drawTetromino() {
      clearGameArea();
      for (let i = 0; i < grid.length; i++) {
        const row = grid[i];
        for (let j = 0; j < row.length; j++) {
          if (row[j]) {
            const x = j * 30;
            const y = i * 30;
            drawBlock(x, y);
          }
        }
      }
      for (let i = 0; i < currentTetromino.length; i++) {
        const row = currentTetromino[i];
        for (let j = 0; j < row.length; j++) {
          if (row[j]) {
            const x = (j + currentX) * 30;
            const y = (i + currentY) * 30;
            drawBlock(x, y);
          }
        }
      }
    }

    function moveDown() {
      if (!checkCollision(0, 1, currentTetromino)) {
        currentY++;
        drawTetromino();
      } else {
        mergeTetromino();
        clearFullRows();
        generateNewTetromino();
        checkGameOver();
      }
    }

    function moveLeft() {
      if (!checkCollision(-1, 0, currentTetromino)) {
        currentX--;
        drawTetromino();
      }
    }

    function moveRight() {
      if (!checkCollision(1, 0, currentTetromino)) {
        currentX++;
        drawTetromino();
      }
    }

    function rotateTetromino() {
      const rotatedTetromino = [];
      for (let i = 0; i < currentTetromino[0].length; i++) {
        const newRow = [];
        for (let j = currentTetromino.length - 1; j >= 0; j--) {
          newRow.push(currentTetromino[j][i]);
        }
        rotatedTetromino.push(newRow);
      }

      if (!checkCollision(0, 0, rotatedTetromino)) {
        currentTetromino = rotatedTetromino;
        drawTetromino();
      }
    }

    function checkCollision(offsetX, offsetY, tetromino) {
      for (let i = 0; i < tetromino.length; i++) {
        for (let j = 0; j < tetromino[i].length; j++) {
          if (tetromino[i][j]) {
            const newX = j + currentX + offsetX;
            const newY = i + currentY + offsetY;
            if (newX < 0 || newX >= 10 || newY >= 20 || (newY >= 0 && grid[newY][newX])) {
              return true;
            }
          }
        }
      }
      return false;
    }

    function mergeTetromino() {
      for (let i = 0; i < currentTetromino.length; i++) {
        for (let j = 0; j < currentTetromino[i].length; j++) {
          if (currentTetromino[i][j]) {
            const x = j + currentX;
            const y = i + currentY;
            grid[y][x] = 1;
          }
        }
      }
    }

    function generateNewTetromino() {
      currentTetromino = tetrominoShapes[Math.floor(Math.random() * tetrominoShapes.length)];
      currentX = Math.floor((10 - currentTetromino[0].length) / 2);
      currentY = 0;
    }

    function clearFullRows() {
      const fullRows = [];
      for (let y = 0; y < grid.length; y++) {
        if (grid[y].every(cell => cell === 1)) {
          fullRows.push(y);
        }
      }

      for (let i = 0; i < fullRows.length; i++) {
        const row = fullRows[i];
        grid.splice(row, 1);
        grid.unshift(new Array(10).fill(0));
      }
    }

    let grid = [];
    for (let i = 0; i < 20; i++) {
      grid.push(new Array(10).fill(0));
    }

    gameInterval = setInterval(moveDown, 1000);

    document.addEventListener('keydown', (event) => {
      if (event.code === 'ArrowLeft') {
        moveLeft();
      } else if (event.code === 'ArrowRight') {
        moveRight();
      } else if (event.code === 'ArrowUp') {
        rotateTetromino();
      } else if (event.code === 'ArrowDown') {
        moveDown()
      }
    });

    function checkGameOver() {
      const topRow = grid[0];
      if (topRow.some(cell => cell === 1)) {
        clearInterval(gameInterval);
        alert('游戏结束! 你的分数为: ' + score);
      }
    }

    function updateScore(linesCleared) {
      score += linesCleared * 10;
    }

    function clearGameArea() {
      while (gameArea.firstChild) {
        gameArea.removeChild(gameArea.firstChild);
      }
    }

    function drawTetromino() {
      clearGameArea();
      for (let i = 0; i < grid.length; i++) {
        const row = grid[i];
        for (let j = 0; j < row.length; j++) {
          if (row[j]) {
            const x = j * 30;
            const y = i * 30;
            drawBlock(x, y);
          }
        }
      }
      for (let i = 0; i < currentTetromino.length; i++) {
        const row = currentTetromino[i];
        for (let j = 0; j < row.length; j++) {
          if (row[j]) {
            const x = (j + currentX) * 30;
            const y = (i + currentY) * 30;
            drawBlock(x, y);
          }
        }
      }
    }

    function mergeTetromino() {
      for (let i = 0; i < currentTetromino.length; i++) {
        for (let j = 0; j < currentTetromino[i].length; j++) {
          if (currentTetromino[i][j]) {
            const x = j + currentX;
            const y = i + currentY;
            grid[y][x] = 1;
          }
        }
      }
      checkGameOver();
    }

    function clearFullRows() {
      const fullRows = [];
      for (let y = 0; y < grid.length; y++) {
        if (grid[y].every(cell => cell === 1)) {
          fullRows.push(y);
        }
      }

      for (let i = 0; i < fullRows.length; i++) {
        const row = fullRows[i];
        grid.splice(row, 1);
        grid.unshift(new Array(10).fill(0));
      }

      updateScore(fullRows.length);
    }

    let score = 0;

    drawTetromino();
  </script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C# 中的 Content-Security-Policy (CSP) 配置用于设置网页中的安全策略,以防止一些常见的网络攻击,例如跨站脚本攻击 (XSS) 和点击劫持等。下面是一个示例的 CSP 配置: ```csharp using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; public class Startup { public void ConfigureServices(IServiceCollection services) { // 添加 CSP 配置 services.AddAntiforgery(options => { options.HeaderName = "X-XSS-Protection"; options.HeaderValue = "1; mode=block"; }); } public void Configure(IApplicationBuilder app) { // 使用 CSP 配置 app.Use(async (context, next) => { context.Response.Headers.Add("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"); await next(); }); // 其他中间件 } } ``` 上述示例中,我们使用了 `AddAntiforgery` 方法来设置 `X-XSS-Protection` 头部的值为 `1; mode=block`,以启用浏览器的内置 XSS 保护。接着,在 `Configure` 方法中使用了自定义的中间件来添加 CSP 头部,并指定了一些策略规则。 在上述 CSP 配置中,我们允许了 `default-src`、`script-src` 和 `style-src` 这三个指令,并设置了允许加载资源的源,例如 `'self'` 表示只允许加载同源的资源,`'unsafe-inline'` 表示允许内联的脚本和样式。 请注意,这只是一个简单的示例配置,并不一定适用于所有的情况,具体的 CSP 配置应根据实际需求和安全性考虑进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端每日三省

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值