如何防止WebView中的JavaScript接口被恶意调用?

端木琪帆 阅读 44

我在开发Android混合应用时,通过WebView添加了支付接口,但发现恶意参数能触发接口调用。比如这个暴露的pay接口:


// 接口暴露代码
webView.addJavascriptInterface(new Object() {
    @JavascriptInterface
    public void pay(String amount) {
        // 处理支付金额
    }
}, "PayApi");

我尝试用白名单过滤amount参数,但发现如果用户修改WebView的URL参数,仍然能调用pay(‘9999’)这样的恶意金额。有没有更安全的拦截方式?

我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
Air-智营
你这个问题在WebView安全里属于常见坑,简单说下标准写法。

首先别直接暴露pay这种敏感接口,建议加个鉴权层。按Google官方文档,addJavascriptInterface必须配合@JavascriptInterface注解使用,这点你倒是做对了。

关键问题在参数校验。amount不能直接拿来用,至少要加类型检查和范围限制。比如判断amount是否为正数,有没有超过预设阈值。像这样:

public void pay(String amount) {
try {
double value = Double.parseDouble(amount);
if (value > 0 && value <= MAX_PAY_AMOUNT) {
// 继续处理
}
} catch (Exception e) {
// 拒绝调用
}
}

更稳妥的做法是把支付金额存在服务端,前端传个订单ID过来,native端自己去查这个订单的真实金额。这样参数篡改就失效了。

还有个隐藏风险点:WebView是否允许加载外部URL?如果允许,建议加URL白名单验证,否则攻击者可以诱导加载恶意页面触发pay接口。

最后提个建议:这种敏感操作应该走原生页面,别用WebView搞混合开发。安全性和用户体验都更可控。
点赞 4
2026-02-06 12:06
Good“雯清
这个问题我踩过坑,直接说重点。WebView里暴露给JS的接口如果参数没校验,确实容易被攻击。你现在的白名单只过滤URL参数没用,因为JS是可以直接调pay方法的。

解决方法分两步:

1. 参数合法性校验必须做
在pay方法里加参数校验逻辑,比如金额必须是数字且在合理范围内:
public void pay(String amount) {
if (!isValidAmount(amount)) {
Log.e("支付异常", "非法金额参数: " + amount);
return;
}
// 处理支付...
}

private boolean isValidAmount(String amount) {
try {
double value = Double.parseDouble(amount);
return value > 0 && value <= 10000; // 限制最大金额
} catch (Exception e) {
return false;
}
}


2. 加签验证更安全
建议在H5页面发起支付时带上签名,签名包含金额+时间戳+密钥,native端验证签名有效性。这样即使参数被篡改也能识别:
public void pay(String amount, String sign) {
if (!isValidAmount(amount) || !verifySign(amount, sign)) {
// 记录异常日志并拦截
return;
}
// 处理支付...
}

private boolean verifySign(String amount, String clientSign) {
String serverSign = MD5.encrypt(amount + ":" + System.currentTimeMillis() + ":" + "your_secret_key");
return serverSign.equals(clientSign);
}


另外,建议用Android 4.2以上才支持的@JavascriptInterface注解,并且minSdk设到17以上。WebView的接口暴露一定要谨慎,能用postMessage通信更好。
点赞 5
2026-02-03 23:03